diff --git a/packages/angular/src/generators/add-linting/add-linting.ts b/packages/angular/src/generators/add-linting/add-linting.ts index 0cbe631879610..c07709450d908 100755 --- a/packages/angular/src/generators/add-linting/add-linting.ts +++ b/packages/angular/src/generators/add-linting/add-linting.ts @@ -37,6 +37,7 @@ export async function addLintingGenerator( skipFormat: true, rootProject: rootProject, addPlugin: options.addPlugin, + addExplicitTargets: !options.addPlugin, }); tasks.push(lintTask); diff --git a/packages/angular/src/generators/application/lib/add-e2e.ts b/packages/angular/src/generators/application/lib/add-e2e.ts index 58a98c319242e..3ca335b87dc34 100644 --- a/packages/angular/src/generators/application/lib/add-e2e.ts +++ b/packages/angular/src/generators/application/lib/add-e2e.ts @@ -14,6 +14,9 @@ import { getInstalledAngularVersionInfo } from '../../utils/version-utils'; import type { NormalizedSchema } from './normalized-schema'; export async function addE2e(tree: Tree, options: NormalizedSchema) { + // check for explicit false, separate e2e projects infer targets by default + const addPlugin = process.env.NX_ADD_PLUGINS !== 'false'; + if (options.e2eTestRunner === 'cypress') { // TODO: This can call `@nx/web:static-config` generator when ready addFileServerTarget(tree, options, 'serve-static'); @@ -34,7 +37,7 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) { devServerTarget: `${options.name}:serve:development`, baseUrl: 'http://localhost:4200', rootProject: options.rootProject, - addPlugin: options.addPlugin, + addPlugin: addPlugin, }); } else if (options.e2eTestRunner === 'playwright') { const { configurationGenerator: playwrightConfigurationGenerator } = @@ -62,7 +65,7 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) { }`, webServerAddress: `http://localhost:${options.port ?? 4200}`, rootProject: options.rootProject, - addPlugin: options.addPlugin, + addPlugin: addPlugin, }); } } diff --git a/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts b/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts index 66b9627e82191..99503584d13a1 100644 --- a/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts +++ b/packages/angular/src/generators/cypress-component-configuration/cypress-component-configuration.ts @@ -46,13 +46,14 @@ export async function cypressComponentConfigurationInternal( tree: Tree, options: CypressComponentConfigSchema ) { - options.addPlugin ??= process.env.NX_ADD_PLUGINS !== 'false'; + options.addPlugin ??= process.env.NX_ADD_PLUGINS === 'true'; const projectConfig = readProjectConfiguration(tree, options.project); const installTask = await baseCyCTConfig(tree, { project: options.project, skipFormat: true, addPlugin: options.addPlugin, + addExplicitTargets: !options.addPlugin, }); await configureCypressCT(tree, options); diff --git a/packages/angular/src/generators/ng-add/utilities/workspace.ts b/packages/angular/src/generators/ng-add/utilities/workspace.ts index d81f8d2640d7a..905af4cc94a96 100644 --- a/packages/angular/src/generators/ng-add/utilities/workspace.ts +++ b/packages/angular/src/generators/ng-add/utilities/workspace.ts @@ -191,7 +191,7 @@ export async function updateRootEsLintConfig( unitTestRunner?: string ): Promise { await lintInitGenerator(tree, { - addPlugin: process.env.NX_ADD_PLUGINS !== 'false', + addPlugin: process.env.NX_ADD_PLUGINS === 'true', }); if (!existingEsLintConfig) { diff --git a/packages/angular/src/generators/storybook-configuration/lib/generate-storybook-configuration.ts b/packages/angular/src/generators/storybook-configuration/lib/generate-storybook-configuration.ts index 556b9c8784b40..5f825f2dbd458 100644 --- a/packages/angular/src/generators/storybook-configuration/lib/generate-storybook-configuration.ts +++ b/packages/angular/src/generators/storybook-configuration/lib/generate-storybook-configuration.ts @@ -6,7 +6,11 @@ export async function generateStorybookConfiguration( tree: Tree, options: StorybookConfigurationOptions ): Promise { - const { configurationGenerator } = ensurePackage('@nx/storybook', nxVersion); + const addPlugin = process.env.NX_ADD_PLUGINS === 'true'; + + const { configurationGenerator } = ensurePackage< + typeof import('@nx/storybook') + >('@nx/storybook', nxVersion); return await configurationGenerator(tree, { project: options.project, uiFramework: '@storybook/angular', @@ -17,5 +21,7 @@ export async function generateStorybookConfiguration( interactionTests: options.interactionTests, configureStaticServe: options.configureStaticServe, skipFormat: true, + addPlugin: addPlugin, + addExplicitTargets: !addPlugin, }); } diff --git a/packages/angular/src/generators/utils/add-jest.ts b/packages/angular/src/generators/utils/add-jest.ts index e2ecd6d25be0d..a7150fbca16a6 100644 --- a/packages/angular/src/generators/utils/add-jest.ts +++ b/packages/angular/src/generators/utils/add-jest.ts @@ -33,6 +33,7 @@ export async function addJest( skipPackageJson: options.skipPackageJson, skipFormat: true, addPlugin: options.addPlugin, + addExplicitTargets: !options.addPlugin, }); const setupFile = joinPathFragments( diff --git a/packages/cypress/src/generators/component-configuration/component-configuration.ts b/packages/cypress/src/generators/component-configuration/component-configuration.ts index 0dc933855339b..6875aa38a0490 100644 --- a/packages/cypress/src/generators/component-configuration/component-configuration.ts +++ b/packages/cypress/src/generators/component-configuration/component-configuration.ts @@ -64,7 +64,7 @@ export async function componentConfigurationGeneratorInternal( tasks.push(updateDeps(tree, opts)); addProjectFiles(tree, projectConfig, opts); - if (!hasPlugin) { + if (!hasPlugin || opts.addExplicitTargets) { addTargetToProject(tree, projectConfig, opts); } updateNxJsonConfiguration(tree, hasPlugin); diff --git a/packages/cypress/src/generators/component-configuration/schema.d.ts b/packages/cypress/src/generators/component-configuration/schema.d.ts index 11430de45c51e..bd9aef559c8b2 100644 --- a/packages/cypress/src/generators/component-configuration/schema.d.ts +++ b/packages/cypress/src/generators/component-configuration/schema.d.ts @@ -5,4 +5,9 @@ export interface CypressComponentConfigurationSchema { bundler?: 'webpack' | 'vite'; jsx?: boolean; addPlugin?: boolean; + + /** + * @internal + */ + addExplicitTargets?: boolean; } diff --git a/packages/cypress/src/generators/configuration/configuration.ts b/packages/cypress/src/generators/configuration/configuration.ts index 6c29bc895aaa5..dcfc9325dca1f 100644 --- a/packages/cypress/src/generators/configuration/configuration.ts +++ b/packages/cypress/src/generators/configuration/configuration.ts @@ -93,6 +93,7 @@ export async function configurationGeneratorInternal( const linterTask = await addLinterToCyProject(tree, { ...opts, cypressDir: opts.directory, + addPlugin: opts.addPlugin, }); tasks.push(linterTask); diff --git a/packages/cypress/src/utils/add-linter.ts b/packages/cypress/src/utils/add-linter.ts index 5679d65da15ed..821c9565a83b7 100644 --- a/packages/cypress/src/utils/add-linter.ts +++ b/packages/cypress/src/utils/add-linter.ts @@ -39,6 +39,7 @@ export interface CyLinterOptions { * This is useful when adding linting to a brand new project vs an existing one **/ overwriteExisting?: boolean; + addPlugin?: boolean; } export async function addLinterToCyProject( @@ -63,6 +64,7 @@ export async function addLinterToCyProject( setParserOptionsProject: options.setParserOptionsProject, skipPackageJson: options.skipPackageJson, rootProject: options.rootProject, + addPlugin: options.addPlugin, }) ); } diff --git a/packages/eslint/src/generators/lint-project/lint-project.ts b/packages/eslint/src/generators/lint-project/lint-project.ts index 0a93999a88485..3e9acec2af810 100644 --- a/packages/eslint/src/generators/lint-project/lint-project.ts +++ b/packages/eslint/src/generators/lint-project/lint-project.ts @@ -52,6 +52,11 @@ interface LintProjectOptions { rootProject?: boolean; keepExistingVersions?: boolean; addPlugin?: boolean; + + /** + * @internal + */ + addExplicitTargets?: boolean; } export function lintProjectGenerator(tree: Tree, options: LintProjectOptions) { @@ -91,7 +96,7 @@ export async function lintProjectGeneratorInternal( } const hasPlugin = hasEslintPlugin(tree); - if (hasPlugin) { + if (hasPlugin && !options.addExplicitTargets) { if ( lintFilePatterns && lintFilePatterns.length && diff --git a/packages/jest/src/generators/configuration/configuration.ts b/packages/jest/src/generators/configuration/configuration.ts index a786f6f9ed9ba..41c25e7ef2ab8 100644 --- a/packages/jest/src/generators/configuration/configuration.ts +++ b/packages/jest/src/generators/configuration/configuration.ts @@ -105,7 +105,7 @@ export async function configurationGeneratorInternal( ); } }); - if (!hasPlugin) { + if (!hasPlugin || options.addExplicitTargets) { updateWorkspace(tree, options); } diff --git a/packages/jest/src/generators/configuration/schema.d.ts b/packages/jest/src/generators/configuration/schema.d.ts index e3021f1cb1d23..afc7659eae769 100644 --- a/packages/jest/src/generators/configuration/schema.d.ts +++ b/packages/jest/src/generators/configuration/schema.d.ts @@ -19,6 +19,11 @@ export interface JestProjectSchema { compiler?: 'tsc' | 'babel' | 'swc'; skipPackageJson?: boolean; js?: boolean; + + /** + * @internal + */ + addExplicitTargets?: boolean; } export type NormalizedJestProjectSchema = JestProjectSchema & { diff --git a/packages/storybook/src/generators/configuration/configuration.ts b/packages/storybook/src/generators/configuration/configuration.ts index be3d53e8ca84a..45fa2609c92cd 100644 --- a/packages/storybook/src/generators/configuration/configuration.ts +++ b/packages/storybook/src/generators/configuration/configuration.ts @@ -174,7 +174,7 @@ export async function configurationGeneratorInternal( let devDeps = {}; - if (!hasPlugin) { + if (!hasPlugin || schema.addExplicitTargets) { if (schema.uiFramework === '@storybook/angular') { addAngularStorybookTarget(tree, schema.project, schema.interactionTests); } else { diff --git a/packages/storybook/src/generators/configuration/schema.d.ts b/packages/storybook/src/generators/configuration/schema.d.ts index 81e9b5519cb0a..cc42b504cdcfa 100644 --- a/packages/storybook/src/generators/configuration/schema.d.ts +++ b/packages/storybook/src/generators/configuration/schema.d.ts @@ -20,4 +20,9 @@ export interface StorybookConfigureSchema { */ cypressDirectory?: string; addPlugin?: boolean; + + /** + * @internal + */ + addExplicitTargets?: boolean; } diff --git a/packages/workspace/src/generators/preset/preset.ts b/packages/workspace/src/generators/preset/preset.ts index 93b77fad063e1..27dd003874c28 100644 --- a/packages/workspace/src/generators/preset/preset.ts +++ b/packages/workspace/src/generators/preset/preset.ts @@ -34,7 +34,6 @@ async function createPreset(tree: Tree, options: Schema) { e2eTestRunner: options.e2eTestRunner ?? 'cypress', bundler: options.bundler, ssr: options.ssr, - addPlugin, }); } else if (options.preset === Preset.AngularStandalone) { const { @@ -53,7 +52,6 @@ async function createPreset(tree: Tree, options: Schema) { e2eTestRunner: options.e2eTestRunner ?? 'cypress', bundler: options.bundler, ssr: options.ssr, - addPlugin, }); } else if (options.preset === Preset.ReactMonorepo) { const { applicationGenerator: reactApplicationGenerator } = require('@nx' +