Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2130596

Browse files
authored
feat: support ESM configs and .cjs and .mjs extensions (#2068)
1 parent 838a706 commit 2130596

16 files changed

+752
-41
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`new-workspace-type-module should pass linting after creating a new workspace from scratch using @angular-eslint 1`] = `
4+
{
5+
"@angular-devkit/build-angular": "^18.X.X",
6+
"@angular/cli": "^18.X.X",
7+
"@angular/compiler-cli": "^18.X.X",
8+
"@types/jasmine": "~5.1.0",
9+
"angular-eslint": "0.0.0-e2e",
10+
"eslint": "^9.9.1",
11+
"jasmine-core": "~5.2.0",
12+
"karma": "~6.4.0",
13+
"karma-chrome-launcher": "~3.2.0",
14+
"karma-coverage": "~2.2.0",
15+
"karma-jasmine": "~5.1.0",
16+
"karma-jasmine-html-reporter": "~2.1.0",
17+
"ng-packagr": "^18.X.X",
18+
"typescript": "~5.X.X",
19+
"typescript-eslint": "8.5.0"
20+
}
21+
`;
22+
23+
exports[`new-workspace-type-module should pass linting after creating a new workspace from scratch using @angular-eslint 2`] = `
24+
"// @ts-check
25+
import eslint from \\"@eslint/js\\";
26+
import tseslint from \\"typescript-eslint\\";
27+
import angular from \\"angular-eslint\\";
28+
29+
export default tseslint.config(
30+
{
31+
files: [\\"**/*.ts\\"],
32+
extends: [
33+
eslint.configs.recommended,
34+
...tseslint.configs.recommended,
35+
...tseslint.configs.stylistic,
36+
...angular.configs.tsRecommended,
37+
],
38+
processor: angular.processInlineTemplates,
39+
rules: {
40+
\\"@angular-eslint/directive-selector\\": [
41+
\\"error\\",
42+
{
43+
type: \\"attribute\\",
44+
prefix: \\"app\\",
45+
style: \\"camelCase\\",
46+
},
47+
],
48+
\\"@angular-eslint/component-selector\\": [
49+
\\"error\\",
50+
{
51+
type: \\"element\\",
52+
prefix: \\"app\\",
53+
style: \\"kebab-case\\",
54+
},
55+
],
56+
},
57+
},
58+
{
59+
files: [\\"**/*.html\\"],
60+
extends: [
61+
...angular.configs.templateRecommended,
62+
...angular.configs.templateAccessibility,
63+
],
64+
rules: {},
65+
}
66+
);
67+
"
68+
`;
69+
70+
exports[`new-workspace-type-module should pass linting after creating a new workspace from scratch using @angular-eslint 3`] = `
71+
Object {
72+
"builder": "@angular-eslint/builder:lint",
73+
"options": Object {
74+
"lintFilePatterns": Array [
75+
"src/**/*.ts",
76+
"src/**/*.html",
77+
],
78+
},
79+
}
80+
`;
81+
82+
exports[`new-workspace-type-module should pass linting after creating a new workspace from scratch using @angular-eslint 4`] = `
83+
"// @ts-check
84+
import tseslint from \\"typescript-eslint\\";
85+
import rootConfig from \\"../../eslint.config.js\\";
86+
87+
export default tseslint.config(
88+
...rootConfig,
89+
{
90+
files: [\\"**/*.ts\\"],
91+
rules: {
92+
\\"@angular-eslint/directive-selector\\": [
93+
\\"error\\",
94+
{
95+
type: \\"attribute\\",
96+
prefix: \\"app\\",
97+
style: \\"camelCase\\",
98+
},
99+
],
100+
\\"@angular-eslint/component-selector\\": [
101+
\\"error\\",
102+
{
103+
type: \\"element\\",
104+
prefix: \\"app\\",
105+
style: \\"kebab-case\\",
106+
},
107+
],
108+
},
109+
},
110+
{
111+
files: [\\"**/*.html\\"],
112+
rules: {},
113+
}
114+
);
115+
"
116+
`;
117+
118+
exports[`new-workspace-type-module should pass linting after creating a new workspace from scratch using @angular-eslint 5`] = `
119+
Object {
120+
"builder": "@angular-eslint/builder:lint",
121+
"options": Object {
122+
"eslintConfig": "projects/another-app/eslint.config.js",
123+
"lintFilePatterns": Array [
124+
"projects/another-app/**/*.ts",
125+
"projects/another-app/**/*.html",
126+
],
127+
},
128+
}
129+
`;
130+
131+
exports[`new-workspace-type-module should pass linting after creating a new workspace from scratch using @angular-eslint 6`] = `
132+
"// @ts-check
133+
import tseslint from \\"typescript-eslint\\";
134+
import rootConfig from \\"../../eslint.config.js\\";
135+
136+
export default tseslint.config(
137+
...rootConfig,
138+
{
139+
files: [\\"**/*.ts\\"],
140+
rules: {
141+
\\"@angular-eslint/directive-selector\\": [
142+
\\"error\\",
143+
{
144+
type: \\"attribute\\",
145+
prefix: \\"lib\\",
146+
style: \\"camelCase\\",
147+
},
148+
],
149+
\\"@angular-eslint/component-selector\\": [
150+
\\"error\\",
151+
{
152+
type: \\"element\\",
153+
prefix: \\"lib\\",
154+
style: \\"kebab-case\\",
155+
},
156+
],
157+
},
158+
},
159+
{
160+
files: [\\"**/*.html\\"],
161+
rules: {},
162+
}
163+
);
164+
"
165+
`;
166+
167+
exports[`new-workspace-type-module should pass linting after creating a new workspace from scratch using @angular-eslint 7`] = `
168+
Object {
169+
"builder": "@angular-eslint/builder:lint",
170+
"options": Object {
171+
"eslintConfig": "projects/another-lib/eslint.config.mjs",
172+
"lintFilePatterns": Array [
173+
"projects/another-lib/**/*.ts",
174+
"projects/another-lib/**/*.html",
175+
],
176+
},
177+
}
178+
`;
179+
180+
exports[`new-workspace-type-module should pass linting after creating a new workspace from scratch using @angular-eslint 8`] = `
181+
"
182+
Linting \\"new-workspace-type-module\\"...
183+
184+
All files pass linting.
185+
186+
187+
Linting \\"another-app\\"...
188+
189+
All files pass linting.
190+
191+
192+
Linting \\"another-lib\\"...
193+
194+
__ROOT__//new-workspace-type-module/projects/another-lib/src/lib/another-lib.service.ts
195+
8:17 error Unexpected empty constructor @typescript-eslint/no-empty-function
196+
197+
✖ 1 problem (1 error, 0 warnings)
198+
"
199+
`;

e2e/src/eslint-8--new-workspace-create-application-false-ng-add-then-project.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ describe('eslint-8--new-workspace-create-application-false-ng-add-then-project',
6464
JSON.stringify(fixture.readJson('package.json').devDependencies, null, 2),
6565
).toMatchSnapshot();
6666

67-
// Root eslint config should be eslintrc, not eslint.config.js
67+
// Root eslint config should be eslintrc, not a flat config
6868
expect(fixture.readFile('.eslintrc.json')).toMatchSnapshot();
6969
expect(fixture.fileExists('eslint.config.js')).toBe(false);
70+
expect(fixture.fileExists('eslint.config.cjs')).toBe(false);
71+
expect(fixture.fileExists('eslint.config.mjs')).toBe(false);
7072

7173
// App project ("app-project")
7274
expect(fixture.fileExists('projects/app-project/tslint.json')).toBe(false);
@@ -76,6 +78,12 @@ describe('eslint-8--new-workspace-create-application-false-ng-add-then-project',
7678
expect(fixture.fileExists('projects/app-project/eslint.config.js')).toBe(
7779
false,
7880
);
81+
expect(fixture.fileExists('projects/app-project/eslint.config.cjs')).toBe(
82+
false,
83+
);
84+
expect(fixture.fileExists('projects/app-project/eslint.config.mjs')).toBe(
85+
false,
86+
);
7987

8088
// It should not contain the eslintConfig option, it is not needed for eslintrc files
8189
expect(

e2e/src/eslint-8--new-workspace-create-application-false-project-then-ng-add.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ describe('eslint-8--new-workspace-create-application-false-project-then-ng-add',
6464
JSON.stringify(fixture.readJson('package.json').devDependencies, null, 2),
6565
).toMatchSnapshot();
6666

67-
// Root eslint config should be eslintrc, not eslint.config.js
67+
// Root eslint config should be eslintrc, not a flat config
6868
expect(fixture.readFile('.eslintrc.json')).toMatchSnapshot();
6969
expect(fixture.fileExists('eslint.config.js')).toBe(false);
70+
expect(fixture.fileExists('eslint.config.cjs')).toBe(false);
71+
expect(fixture.fileExists('eslint.config.mjs')).toBe(false);
7072

7173
// App project ("app-project")
7274
expect(fixture.fileExists('projects/app-project/tslint.json')).toBe(false);
@@ -76,6 +78,12 @@ describe('eslint-8--new-workspace-create-application-false-project-then-ng-add',
7678
expect(fixture.fileExists('projects/app-project/eslint.config.js')).toBe(
7779
false,
7880
);
81+
expect(fixture.fileExists('projects/app-project/eslint.config.cjs')).toBe(
82+
false,
83+
);
84+
expect(fixture.fileExists('projects/app-project/eslint.config.mjs')).toBe(
85+
false,
86+
);
7987

8088
// It should not contain the eslintConfig option, it is not needed for eslintrc files
8189
expect(

e2e/src/eslint-8--new-workspace.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,11 @@ describe('eslint-8--new-workspace', () => {
6969
JSON.stringify(fixture.readJson('package.json').devDependencies, null, 2),
7070
).toMatchSnapshot();
7171

72-
// Root eslint config should be eslintrc, not eslint.config.js
72+
// Root eslint config should be eslintrc, not a flat config
7373
expect(fixture.readFile('.eslintrc.json')).toMatchSnapshot();
7474
expect(fixture.fileExists('eslint.config.js')).toBe(false);
75+
expect(fixture.fileExists('eslint.config.cjs')).toBe(false);
76+
expect(fixture.fileExists('eslint.config.mjs')).toBe(false);
7577

7678
// It should not contain the eslintConfig option, it is not needed for eslintrc files
7779
expect(
@@ -87,6 +89,12 @@ describe('eslint-8--new-workspace', () => {
8789
expect(fixture.fileExists('projects/another-app/eslint.config.js')).toBe(
8890
false,
8991
);
92+
expect(fixture.fileExists('projects/another-app/eslint.config.cjs')).toBe(
93+
false,
94+
);
95+
expect(fixture.fileExists('projects/another-app/eslint.config.mjs')).toBe(
96+
false,
97+
);
9098

9199
// It should not contain the eslintConfig option, it is not needed for eslintrc files
92100
expect(
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import path from 'node:path';
2+
import { setWorkspaceRoot } from 'nx/src/utils/workspace-root';
3+
import { FIXTURES_DIR, Fixture } from '../utils/fixtures';
4+
import {
5+
LONG_TIMEOUT_MS,
6+
runNgAdd,
7+
runNgGenerate,
8+
runNgNew,
9+
} from '../utils/local-registry-process';
10+
import { runLint } from '../utils/run-lint';
11+
import { normalizeVersionsOfPackagesWeDoNotControl } from '../utils/snapshot-serializers';
12+
13+
expect.addSnapshotSerializer(normalizeVersionsOfPackagesWeDoNotControl);
14+
15+
const fixtureDirectory = 'new-workspace-type-module';
16+
let fixture: Fixture;
17+
18+
describe('new-workspace-type-module', () => {
19+
jest.setTimeout(LONG_TIMEOUT_MS);
20+
21+
beforeAll(async () => {
22+
process.chdir(FIXTURES_DIR);
23+
await runNgNew(fixtureDirectory);
24+
25+
process.env.NX_DAEMON = 'false';
26+
process.env.NX_CACHE_PROJECT_GRAPH = 'false';
27+
28+
const workspaceRoot = path.join(FIXTURES_DIR, fixtureDirectory);
29+
process.chdir(workspaceRoot);
30+
process.env.NX_WORKSPACE_ROOT_PATH = workspaceRoot;
31+
setWorkspaceRoot(workspaceRoot);
32+
33+
fixture = new Fixture(workspaceRoot);
34+
35+
// Set root package.json to use type: module
36+
fixture.writeJson('package.json', {
37+
...fixture.readJson('package.json'),
38+
type: 'module',
39+
});
40+
41+
await runNgAdd();
42+
await runNgGenerate(['app', 'another-app', '--interactive=false']);
43+
await runNgGenerate(['lib', 'another-lib', '--interactive=false']);
44+
});
45+
46+
it('should pass linting after creating a new workspace from scratch using @angular-eslint', async () => {
47+
// TSLint configs and dependencies should not be present
48+
expect(fixture.fileExists('tslint.json')).toBe(false);
49+
expect(
50+
JSON.stringify(fixture.readJson('package.json').devDependencies, null, 2),
51+
).toMatchSnapshot();
52+
53+
// Root eslint config should be eslint.config.js, not eslintrc, AND contain ESM (because of type: module)
54+
expect(fixture.readFile('eslint.config.js')).toMatchSnapshot();
55+
expect(fixture.fileExists('.eslintrc.json')).toBe(false);
56+
57+
expect(
58+
fixture.readJson('angular.json').projects['new-workspace-type-module']
59+
.architect.lint,
60+
).toMatchSnapshot();
61+
62+
// Additional project ("another-app")
63+
expect(fixture.fileExists('projects/another-app/tslint.json')).toBe(false);
64+
65+
/**
66+
* The project config should contain ESM, because the root config contains ESM, and it should use a plain .js
67+
* extension because there is no project package.json to influence the extension.
68+
*/
69+
expect(
70+
fixture.readFile('projects/another-app/eslint.config.js'),
71+
).toMatchSnapshot();
72+
expect(fixture.fileExists('projects/another-app/.eslintrc.json')).toBe(
73+
false,
74+
);
75+
76+
// It should contain the eslintConfig option set to the project level eslint.config.js file
77+
expect(
78+
fixture.readJson('angular.json').projects['another-app'].architect.lint,
79+
).toMatchSnapshot();
80+
81+
// Additional library project ("another-lib")
82+
expect(fixture.fileExists('projects/another-lib/tslint.json')).toBe(false);
83+
84+
/**
85+
* The project config should contain ESM, because the root config contains ESM, but because in this case it has its
86+
* own project package.json which does not have type: module set, it should use a .mjs extension.
87+
*/
88+
expect(
89+
fixture.readFile('projects/another-lib/eslint.config.mjs'),
90+
).toMatchSnapshot();
91+
expect(fixture.fileExists('projects/another-lib/.eslintrc.json')).toBe(
92+
false,
93+
);
94+
95+
// It should contain the eslintConfig option set to the project level eslint.config.mjs file
96+
expect(
97+
fixture.readJson('angular.json').projects['another-lib'].architect.lint,
98+
).toMatchSnapshot();
99+
100+
const lintOutput = await runLint(fixtureDirectory);
101+
expect(lintOutput).toMatchSnapshot();
102+
});
103+
});

e2e/suites/9/project.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "e2e-suite-9",
3+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
4+
"projectType": "application",
5+
"targets": {
6+
"e2e-suite": {
7+
"executor": "./packages/nx-plugin:e2e-test-suite",
8+
"options": {
9+
"cwd": "e2e",
10+
"testFilePath": "src/new-workspace-type-module.test.ts"
11+
}
12+
}
13+
},
14+
"implicitDependencies": ["packages/*"]
15+
}

0 commit comments

Comments
 (0)