Skip to content

Commit 5b6d1b4

Browse files
leosvelperezjaysoo
andauthored
feat(angular): force explicit targets when NX_ADD_PLUGINS is not explicitly true (#21852)
Co-authored-by: Jack Hsu <[email protected]>
1 parent 4c8c24b commit 5b6d1b4

File tree

23 files changed

+145
-26
lines changed

23 files changed

+145
-26
lines changed

packages/angular/src/generators/add-linting/add-linting.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export async function addLintingGenerator(
3737
skipFormat: true,
3838
rootProject: rootProject,
3939
addPlugin: options.addPlugin,
40+
addExplicitTargets: true,
4041
});
4142
tasks.push(lintTask);
4243

packages/angular/src/generators/add-linting/schema.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ export interface AddLintingGeneratorSchema {
77
skipPackageJson?: boolean;
88
unitTestRunner?: string;
99
addPlugin?: boolean;
10+
addExplicitTargets?: boolean;
1011
}

packages/angular/src/generators/application/lib/add-e2e.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
3434
devServerTarget: `${options.name}:serve:development`,
3535
baseUrl: 'http://localhost:4200',
3636
rootProject: options.rootProject,
37-
addPlugin: options.addPlugin,
37+
addPlugin: false,
38+
addExplicitTargets: false, // since e2e is a separate project, use inferred targets
3839
});
3940
} else if (options.e2eTestRunner === 'playwright') {
4041
const { configurationGenerator: playwrightConfigurationGenerator } =
@@ -62,7 +63,7 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
6263
}`,
6364
webServerAddress: `http://localhost:${options.port ?? 4200}`,
6465
rootProject: options.rootProject,
65-
addPlugin: options.addPlugin,
66+
addPlugin: false,
6667
});
6768
}
6869
}

packages/angular/src/generators/application/lib/add-linting.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ export async function addLinting(host: Tree, options: NormalizedSchema) {
1616
skipPackageJson: options.skipPackageJson,
1717
unitTestRunner: options.unitTestRunner,
1818
skipFormat: true,
19-
addPlugin: options.addPlugin,
19+
addPlugin: false,
2020
});
2121
}

packages/angular/src/generators/application/lib/add-unit-test-runner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export async function addUnitTestRunner(host: Tree, options: NormalizedSchema) {
1010
projectRoot: options.appProjectRoot,
1111
skipPackageJson: options.skipPackageJson,
1212
strict: options.strict,
13-
addPlugin: options.addPlugin,
13+
addPlugin: false,
1414
});
1515
}
1616
}

packages/angular/src/generators/application/lib/normalize-options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export async function normalizeOptions(
2626
});
2727
options.rootProject = appProjectRoot === '.';
2828
options.projectNameAndRootFormat = projectNameAndRootFormat;
29-
options.addPlugin ??= process.env.NX_ADD_PLUGINS === 'true';
29+
options.addPlugin ??= process.env.NX_ADD_PLUGINS !== 'false';
3030

3131
const e2eProjectName = options.rootProject ? 'e2e' : `${appProjectName}-e2e`;
3232
const e2eProjectRoot = options.rootProject ? 'e2e' : `${appProjectRoot}-e2e`;

packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ export async function cypressComponentConfigurationInternal(
5252
const installTask = await baseCyCTConfig(tree, {
5353
project: options.project,
5454
skipFormat: true,
55-
addPlugin: options.addPlugin,
55+
addPlugin: false,
56+
addExplicitTargets: true,
5657
});
5758

5859
await configureCypressCT(tree, options);

packages/angular/src/generators/library/library.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ async function addUnitTestRunner(
134134
projectRoot: options.projectRoot,
135135
skipPackageJson: options.skipPackageJson,
136136
strict: options.strict,
137-
addPlugin: options.addPlugin,
137+
addPlugin: false,
138138
});
139139
}
140140
}

packages/angular/src/generators/ng-add/__snapshots__/migrate-from-angular-cli.spec.ts.snap

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,16 @@ exports[`workspace move to nx layout should create nx.json 1`] = `
9999
],
100100
"sharedGlobals": [],
101101
},
102-
"plugins": [
103-
{
104-
"options": {
105-
"targetName": "lint",
106-
},
107-
"plugin": "@nx/eslint/plugin",
108-
},
109-
],
110102
"targetDefaults": {
103+
"@nx/eslint:lint": {
104+
"cache": true,
105+
"inputs": [
106+
"default",
107+
"{workspaceRoot}/.eslintrc.json",
108+
"{workspaceRoot}/.eslintignore",
109+
"{workspaceRoot}/eslint.config.js",
110+
],
111+
},
111112
"build": {
112113
"cache": true,
113114
"dependsOn": [

packages/angular/src/generators/ng-add/utilities/workspace.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ export async function updateRootEsLintConfig(
191191
unitTestRunner?: string
192192
): Promise<void> {
193193
await lintInitGenerator(tree, {
194-
addPlugin: process.env.NX_ADD_PLUGINS !== 'false',
194+
addPlugin: process.env.NX_ADD_PLUGINS === 'true',
195195
});
196196

197197
if (!existingEsLintConfig) {

packages/angular/src/generators/storybook-configuration/lib/generate-storybook-configuration.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ export async function generateStorybookConfiguration(
66
tree: Tree,
77
options: StorybookConfigurationOptions
88
): Promise<GeneratorCallback> {
9-
const { configurationGenerator } = ensurePackage('@nx/storybook', nxVersion);
9+
const addPlugin = process.env.NX_ADD_PLUGINS === 'true';
10+
11+
const { configurationGenerator } = ensurePackage<
12+
typeof import('@nx/storybook')
13+
>('@nx/storybook', nxVersion);
1014
return await configurationGenerator(tree, {
1115
project: options.project,
1216
uiFramework: '@storybook/angular',
@@ -17,5 +21,7 @@ export async function generateStorybookConfiguration(
1721
interactionTests: options.interactionTests,
1822
configureStaticServe: options.configureStaticServe,
1923
skipFormat: true,
24+
addPlugin: addPlugin,
25+
addExplicitTargets: !addPlugin,
2026
});
2127
}

packages/angular/src/generators/utils/add-jest.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export async function addJest(
3232
skipSerializers: false,
3333
skipPackageJson: options.skipPackageJson,
3434
skipFormat: true,
35-
addPlugin: options.addPlugin,
35+
addPlugin: false,
36+
addExplicitTargets: true,
3637
});
3738

3839
const setupFile = joinPathFragments(

packages/cypress/src/generators/component-configuration/component-configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export async function componentConfigurationGeneratorInternal(
6464
tasks.push(updateDeps(tree, opts));
6565

6666
addProjectFiles(tree, projectConfig, opts);
67-
if (!hasPlugin) {
67+
if (!hasPlugin || opts.addExplicitTargets) {
6868
addTargetToProject(tree, projectConfig, opts);
6969
}
7070
updateNxJsonConfiguration(tree, hasPlugin);

packages/cypress/src/generators/component-configuration/schema.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,9 @@ export interface CypressComponentConfigurationSchema {
55
bundler?: 'webpack' | 'vite';
66
jsx?: boolean;
77
addPlugin?: boolean;
8+
9+
/**
10+
* @internal
11+
*/
12+
addExplicitTargets?: boolean;
813
}

packages/cypress/src/generators/configuration/configuration.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,48 @@ export default defineConfig({
554554
"
555555
`);
556556
});
557+
558+
it('should support generating explicit targets', async () => {
559+
mockedInstalledCypressVersion.mockReturnValue(undefined); // ensure init is called
560+
addProject(tree, { name: 'explicit-lib', type: 'apps' });
561+
addProject(tree, { name: 'inferred-lib', type: 'apps' });
562+
563+
await cypressE2EConfigurationGenerator(tree, {
564+
project: 'explicit-lib',
565+
baseUrl: 'http://localhost:4200',
566+
addPlugin: true,
567+
addExplicitTargets: true,
568+
});
569+
await cypressE2EConfigurationGenerator(tree, {
570+
project: 'inferred-lib',
571+
baseUrl: 'http://localhost:4200',
572+
addPlugin: true,
573+
addExplicitTargets: false,
574+
});
575+
576+
expect(readProjectConfiguration(tree, 'explicit-lib').targets.e2e)
577+
.toMatchInlineSnapshot(`
578+
{
579+
"configurations": {
580+
"ci": {
581+
"devServerTarget": "explicit-lib:serve-static",
582+
},
583+
"production": {
584+
"devServerTarget": "explicit-lib:serve:production",
585+
},
586+
},
587+
"executor": "@nx/cypress:cypress",
588+
"options": {
589+
"cypressConfig": "apps/explicit-lib/cypress.config.ts",
590+
"devServerTarget": "explicit-lib:serve",
591+
"testingType": "e2e",
592+
},
593+
}
594+
`);
595+
expect(
596+
readProjectConfiguration(tree, 'inferred-lib').targets.e2e
597+
).toBeUndefined();
598+
});
557599
});
558600
});
559601

packages/cypress/src/generators/configuration/configuration.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export interface CypressE2EConfigSchema {
4848
webServerCommands?: Record<string, string>;
4949
ciWebServerCommand?: string;
5050
addPlugin?: boolean;
51+
addExplicitTargets?: boolean;
5152
}
5253

5354
type NormalizedSchema = ReturnType<typeof normalizeOptions>;
@@ -56,7 +57,10 @@ export function configurationGenerator(
5657
tree: Tree,
5758
options: CypressE2EConfigSchema
5859
) {
59-
return configurationGeneratorInternal(tree, { addPlugin: false, ...options });
60+
return configurationGeneratorInternal(tree, {
61+
addPlugin: false,
62+
...options,
63+
});
6064
}
6165

6266
export async function configurationGeneratorInternal(
@@ -86,13 +90,15 @@ export async function configurationGeneratorInternal(
8690
);
8791

8892
await addFiles(tree, opts, projectGraph, hasPlugin);
89-
if (!hasPlugin) {
93+
if (!hasPlugin || options.addExplicitTargets) {
9094
addTarget(tree, opts);
9195
}
9296

9397
const linterTask = await addLinterToCyProject(tree, {
9498
...opts,
9599
cypressDir: opts.directory,
100+
addPlugin: opts.addPlugin,
101+
addExplicitTargets: opts.addExplicitTargets,
96102
});
97103
tasks.push(linterTask);
98104

packages/cypress/src/utils/add-linter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export interface CyLinterOptions {
3939
* This is useful when adding linting to a brand new project vs an existing one
4040
**/
4141
overwriteExisting?: boolean;
42+
addPlugin?: boolean;
43+
addExplicitTargets?: boolean;
4244
}
4345

4446
export async function addLinterToCyProject(
@@ -63,6 +65,8 @@ export async function addLinterToCyProject(
6365
setParserOptionsProject: options.setParserOptionsProject,
6466
skipPackageJson: options.skipPackageJson,
6567
rootProject: options.rootProject,
68+
addPlugin: options.addPlugin,
69+
addExplicitTargets: options.addExplicitTargets,
6670
})
6771
);
6872
}

packages/eslint/src/generators/lint-project/lint-project.spec.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import {
22
addProjectConfiguration,
3+
readJson,
34
readProjectConfiguration,
4-
updateJson,
55
Tree,
6-
readJson,
6+
updateJson,
77
} from '@nx/devkit';
88

99
import { Linter } from '../utils/linter';
@@ -298,4 +298,39 @@ describe('@nx/eslint:lint-project', () => {
298298
"
299299
`);
300300
});
301+
302+
it('should support generating explicit targets on project config', async () => {
303+
addProjectConfiguration(tree, 'explicit-lib', {
304+
root: 'libs/explicit-lib',
305+
projectType: 'library',
306+
targets: {},
307+
});
308+
addProjectConfiguration(tree, 'inferred-lib', {
309+
root: 'libs/inferred-lib',
310+
projectType: 'library',
311+
targets: {},
312+
});
313+
314+
await lintProjectGenerator(tree, {
315+
...defaultOptions,
316+
linter: Linter.EsLint,
317+
project: 'explicit-lib',
318+
addExplicitTargets: true,
319+
});
320+
await lintProjectGenerator(tree, {
321+
...defaultOptions,
322+
linter: Linter.EsLint,
323+
project: 'inferred-lib',
324+
addExplicitTargets: false,
325+
});
326+
327+
const explicitCOnfig = readProjectConfiguration(tree, 'explicit-lib');
328+
expect(explicitCOnfig.targets.lint).toMatchInlineSnapshot(`
329+
{
330+
"executor": "@nx/eslint:lint",
331+
}
332+
`);
333+
const inferredConfig = readProjectConfiguration(tree, 'inferred-lib');
334+
expect(inferredConfig.targets.lint).toBeUndefined();
335+
});
301336
});

packages/eslint/src/generators/lint-project/lint-project.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ interface LintProjectOptions {
5252
rootProject?: boolean;
5353
keepExistingVersions?: boolean;
5454
addPlugin?: boolean;
55+
56+
/**
57+
* @internal
58+
*/
59+
addExplicitTargets?: boolean;
5560
}
5661

5762
export function lintProjectGenerator(tree: Tree, options: LintProjectOptions) {
@@ -91,7 +96,7 @@ export async function lintProjectGeneratorInternal(
9196
}
9297

9398
const hasPlugin = hasEslintPlugin(tree);
94-
if (hasPlugin) {
99+
if (hasPlugin && !options.addExplicitTargets) {
95100
if (
96101
lintFilePatterns &&
97102
lintFilePatterns.length &&

packages/jest/src/generators/configuration/configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export async function configurationGeneratorInternal(
105105
);
106106
}
107107
});
108-
if (!hasPlugin) {
108+
if (!hasPlugin || options.addExplicitTargets) {
109109
updateWorkspace(tree, options);
110110
}
111111

packages/jest/src/generators/configuration/schema.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ export interface JestProjectSchema {
1919
compiler?: 'tsc' | 'babel' | 'swc';
2020
skipPackageJson?: boolean;
2121
js?: boolean;
22+
23+
/**
24+
* @internal
25+
*/
26+
addExplicitTargets?: boolean;
2227
}
2328

2429
export type NormalizedJestProjectSchema = JestProjectSchema & {

packages/storybook/src/generators/configuration/configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ export async function configurationGeneratorInternal(
174174

175175
let devDeps = {};
176176

177-
if (!hasPlugin) {
177+
if (!hasPlugin || schema.addExplicitTargets) {
178178
if (schema.uiFramework === '@storybook/angular') {
179179
addAngularStorybookTarget(tree, schema.project, schema.interactionTests);
180180
} else {

packages/storybook/src/generators/configuration/schema.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,9 @@ export interface StorybookConfigureSchema {
2020
*/
2121
cypressDirectory?: string;
2222
addPlugin?: boolean;
23+
24+
/**
25+
* @internal
26+
*/
27+
addExplicitTargets?: boolean;
2328
}

0 commit comments

Comments
 (0)