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

Skip to content

Commit c5a70bb

Browse files
authored
chore: switch to using angular-devkit directly for schematics and builder (#1985)
1 parent 7425423 commit c5a70bb

File tree

9 files changed

+357
-216
lines changed

9 files changed

+357
-216
lines changed

packages/builder/package.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@
1818
"LICENSE",
1919
"builders.json"
2020
],
21-
"dependencies": {
22-
"@nx/devkit": ">= 19.5.4 < 20.0.0",
23-
"nx": ">= 19.5.4 < 20.0.0"
24-
},
2521
"devDependencies": {
2622
"@angular-devkit/architect": ">= 0.1800.0 < 0.1900.0",
2723
"@angular-devkit/core": ">= 18.0.0 < 19.0.0"

packages/builder/src/lint.impl.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
1-
import type { BuilderOutput } from '@angular-devkit/architect';
2-
import {
3-
convertNxExecutor,
4-
joinPathFragments,
5-
workspaceRoot,
6-
} from '@nx/devkit';
1+
import { createBuilder, type BuilderOutput } from '@angular-devkit/architect';
72
import type { ESLint } from 'eslint';
83
import { existsSync, mkdirSync, writeFileSync } from 'fs';
94
import { dirname, join, resolve } from 'path';
105
import type { Schema } from './schema';
116
import { resolveAndInstantiateESLint } from './utils/eslint-utils';
127

13-
export default convertNxExecutor(
8+
export default createBuilder(
149
async (options: Schema, context): Promise<BuilderOutput> => {
15-
const systemRoot = context.root;
10+
const systemRoot = context.workspaceRoot;
1611

1712
// eslint resolves files relative to the current working directory.
1813
// We want these paths to always be resolved relative to the workspace
1914
// root to be able to run the lint executor from any subfolder.
2015
process.chdir(systemRoot);
2116

22-
const projectName = context.projectName || '<???>';
17+
const projectName = context.target?.project ?? '<???>';
2318
const printInfo = options.format && !options.silent;
2419

2520
if (printInfo) {
@@ -43,9 +38,7 @@ export default convertNxExecutor(
4338
* we only want to support it if the user has explicitly opted into it by converting
4439
* their root ESLint config to use eslint.config.js
4540
*/
46-
const useFlatConfig = existsSync(
47-
joinPathFragments(workspaceRoot, 'eslint.config.js'),
48-
);
41+
const useFlatConfig = existsSync(join(systemRoot, 'eslint.config.js'));
4942
const { eslint, ESLint } = await resolveAndInstantiateESLint(
5043
eslintConfigPath,
5144
options,
@@ -74,8 +67,9 @@ export default convertNxExecutor(
7467
)
7568
) {
7669
let eslintConfigPathForError = `for ${projectName}`;
77-
if (context.projectsConfigurations?.projects?.[projectName]?.root) {
78-
const { root } = context.projectsConfigurations.projects[projectName];
70+
const projectMetadata = await context.getProjectMetadata(projectName);
71+
if (projectMetadata?.root) {
72+
const { root } = projectMetadata;
7973
eslintConfigPathForError = `\`${root}/.eslintrc.json\``;
8074
}
8175

@@ -168,7 +162,7 @@ For full guidance on how to resolve this issue, please see https://github.com/an
168162
const formattedResults = await formatter.format(finalLintResults);
169163

170164
if (options.outputFile) {
171-
const pathToOutputFile = join(context.root, options.outputFile);
165+
const pathToOutputFile = join(systemRoot, options.outputFile);
172166
mkdirSync(dirname(pathToOutputFile), { recursive: true });
173167
writeFileSync(pathToOutputFile, formattedResults);
174168
} else {

packages/schematics/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@
3838
"dependencies": {
3939
"@angular-eslint/eslint-plugin": "18.2.0",
4040
"@angular-eslint/eslint-plugin-template": "18.2.0",
41-
"@nx/devkit": ">= 19.5.4 < 20.0.0",
4241
"ignore": "5.3.2",
43-
"nx": "^19.0.6",
4442
"semver": "7.6.3",
4543
"strip-json-comments": "3.1.1"
4644
},
Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { Tree } from '../devkit-imports';
2-
import { convertNxGenerator } from '../devkit-imports';
1+
import type { Rule, Tree } from '@angular-devkit/schematics';
2+
import { chain } from '@angular-devkit/schematics';
33
import {
44
addESLintTargetToProject,
55
createESLintConfigForProject,
@@ -11,26 +11,27 @@ interface Schema {
1111
setParserOptionsProject?: boolean;
1212
}
1313

14-
export default convertNxGenerator(async (tree: Tree, options: Schema) => {
15-
const projectName = determineTargetProjectName(tree, options.project);
16-
if (!projectName) {
17-
throw new Error(
18-
'\n' +
19-
`
14+
export default function addESLintToProject(schema: Schema): Rule {
15+
return (tree: Tree) => {
16+
const projectName = determineTargetProjectName(tree, schema.project);
17+
if (!projectName) {
18+
throw new Error(
19+
'\n' +
20+
`
2021
Error: You must specify a project to add ESLint to because you have multiple projects in your angular.json
2122
2223
E.g. npx ng g @angular-eslint/schematics:add-eslint-to-project {{YOUR_PROJECT_NAME_GOES_HERE}}
23-
`.trim(),
24-
);
25-
}
26-
27-
// Create the config file first so that we can check for its existence when setting the target
28-
createESLintConfigForProject(
29-
tree,
30-
projectName,
31-
options.setParserOptionsProject ?? false,
32-
);
33-
34-
// Update the lint builder and config in angular.json
35-
addESLintTargetToProject(tree, projectName, 'lint');
36-
});
24+
`.trim(),
25+
);
26+
}
27+
return chain([
28+
// Create the ESLint config file for the project
29+
createESLintConfigForProject(
30+
projectName,
31+
schema.setParserOptionsProject ?? false,
32+
),
33+
// Set the lint builder and config in angular.json
34+
addESLintTargetToProject(projectName, 'lint'),
35+
]);
36+
};
37+
}
Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1+
import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
2+
import { chain, externalSchematic } from '@angular-devkit/schematics';
13
/**
24
* We are able to use the full, unaltered Schema directly from @schematics/angular
35
* The applicable json file is copied from node_modules as a prebuiid step to ensure
46
* they stay in sync.
57
*/
68
import type { Schema as AngularSchema } from '@schematics/angular/application/schema';
7-
import type { Tree } from '../devkit-imports';
8-
import {
9-
convertNxGenerator,
10-
wrapAngularDevkitSchematic,
11-
} from '../devkit-imports';
129
import {
1310
addESLintTargetToProject,
1411
createESLintConfigForProject,
@@ -18,25 +15,27 @@ interface Schema extends AngularSchema {
1815
setParserOptionsProject?: boolean;
1916
}
2017

21-
export default convertNxGenerator(async (tree: Tree, options: Schema) => {
22-
// Remove angular-eslint specific options before passing to the Angular schematic
23-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
24-
const { setParserOptionsProject, ...angularOptions } = options;
25-
26-
const applicationGenerator = wrapAngularDevkitSchematic(
27-
'@schematics/angular',
28-
'application',
29-
);
30-
31-
await applicationGenerator(tree, angularOptions);
18+
function eslintRelatedChanges(options: Schema) {
19+
return chain([
20+
// Create the ESLint config file for the project
21+
createESLintConfigForProject(
22+
options.name,
23+
options.setParserOptionsProject ?? false,
24+
),
25+
// Update the lint builder and config in angular.json
26+
addESLintTargetToProject(options.name, 'lint'),
27+
]);
28+
}
3229

33-
// Create the config file first so that we can check for its existence when setting the target
34-
createESLintConfigForProject(
35-
tree,
36-
options.name,
37-
options.setParserOptionsProject ?? false,
38-
);
30+
export default function (options: Schema): Rule {
31+
return (host: Tree, context: SchematicContext) => {
32+
// Remove angular-eslint specific options before passing to the Angular schematic
33+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
34+
const { setParserOptionsProject, ...angularOptions } = options;
3935

40-
// Update the lint builder and config in angular.json
41-
addESLintTargetToProject(tree, options.name, 'lint');
42-
});
36+
return chain([
37+
externalSchematic('@schematics/angular', 'application', angularOptions),
38+
eslintRelatedChanges(options),
39+
])(host, context);
40+
};
41+
}
Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1+
import type { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
2+
import { chain, externalSchematic } from '@angular-devkit/schematics';
13
/**
24
* We are able to use the full, unaltered Schema directly from @schematics/angular
35
* The applicable json file is copied from node_modules as a prebuiid step to ensure
46
* they stay in sync.
57
*/
68
import type { Schema as AngularSchema } from '@schematics/angular/library/schema';
7-
import type { Tree } from '../devkit-imports';
8-
import {
9-
convertNxGenerator,
10-
wrapAngularDevkitSchematic,
11-
} from '../devkit-imports';
129
import {
1310
addESLintTargetToProject,
1411
createESLintConfigForProject,
@@ -18,25 +15,27 @@ interface Schema extends AngularSchema {
1815
setParserOptionsProject?: boolean;
1916
}
2017

21-
export default convertNxGenerator(async (tree: Tree, options: Schema) => {
22-
// Remove angular-eslint specific options before passing to the Angular schematic
23-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
24-
const { setParserOptionsProject, ...angularOptions } = options;
25-
26-
const libraryGenerator = wrapAngularDevkitSchematic(
27-
'@schematics/angular',
28-
'library',
29-
);
30-
31-
await libraryGenerator(tree, angularOptions);
18+
function eslintRelatedChanges(options: Schema) {
19+
return chain([
20+
// Create the ESLint config file for the project
21+
createESLintConfigForProject(
22+
options.name,
23+
options.setParserOptionsProject ?? false,
24+
),
25+
// Update the lint builder and config in angular.json
26+
addESLintTargetToProject(options.name, 'lint'),
27+
]);
28+
}
3229

33-
// Create the config file first so that we can check for its existence when setting the target
34-
createESLintConfigForProject(
35-
tree,
36-
options.name,
37-
options.setParserOptionsProject ?? false,
38-
);
30+
export default function (options: Schema): Rule {
31+
return (host: Tree, context: SchematicContext) => {
32+
// Remove angular-eslint specific options before passing to the Angular schematic
33+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
34+
const { setParserOptionsProject, ...angularOptions } = options;
3935

40-
// Update the lint builder and config in angular.json
41-
addESLintTargetToProject(tree, options.name, 'lint');
42-
});
36+
return chain([
37+
externalSchematic('@schematics/angular', 'library', angularOptions),
38+
eslintRelatedChanges(options),
39+
])(host, context);
40+
};
41+
}

0 commit comments

Comments
 (0)