From cfe32c25604ebcf83341fd7158f0965d08b60488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leosvel=20P=C3=A9rez=20Espinosa?= Date: Mon, 24 Mar 2025 13:42:18 +0100 Subject: [PATCH] feat(misc): add `--useProjectJson` flag to CNW (#30475) ## Current Behavior Creating new workspaces since Nx 20.6.0 will generate the Nx configuration in `package.json` files. This is intended, given that it is part of the new setup using TypeScript Project References and Package Manager Workspaces, but there's no way to choose to generate the Nx configuration in `project.json` files. Project generators do allow to choose but there's no way to do it when creating a new workspace. This forces users who want to use `project.json` files to generate an empty workspace and then use a project generator. ## Expected Behavior When creating a new Nx workspace, users can provide an option (`--use-project-json`) to generate the Nx configuration in `project.json` files. ## Related Issue(s) Fixes #30464 --- docs/generated/cli/create-nx-workspace.md | 1 + .../nx/documents/create-nx-workspace.md | 1 + .../packages/workspace/generators/new.json | 4 ++++ .../packages/workspace/generators/preset.json | 4 ++++ .../bin/create-nx-workspace.ts | 6 ++++++ .../src/generators/new/generate-preset.ts | 1 + packages/workspace/src/generators/new/new.ts | 1 + .../workspace/src/generators/new/schema.json | 4 ++++ .../workspace/src/generators/preset/preset.ts | 18 +++++++++--------- .../src/generators/preset/schema.d.ts | 1 + .../src/generators/preset/schema.json | 4 ++++ 11 files changed, 36 insertions(+), 9 deletions(-) diff --git a/docs/generated/cli/create-nx-workspace.md b/docs/generated/cli/create-nx-workspace.md index 008b241dd1..c6117aef2f 100644 --- a/docs/generated/cli/create-nx-workspace.md +++ b/docs/generated/cli/create-nx-workspace.md @@ -46,6 +46,7 @@ Install `create-nx-workspace` globally to invoke the command directly, or use `n | `--style` | string | Stylesheet type to be used with certain stacks. | | `--unitTestRunner` | `jest`, `vitest`, `none` | Test runner to use for unit tests. | | `--useGitHub` | boolean | Will you be using GitHub as your git hosting provider? (Default: `false`) | +| `--useProjectJson` | boolean | Use a 'project.json' file for the Nx configuration instead of a 'package.json' file. This defaults to 'true' when '--no-workspaces' is used. Otherwise, it defaults to 'false'. | | `--useReactRouter` | boolean | Generate a Server-Side Rendered (SSR) React app using React Router. | | `--version` | boolean | Show version number. | | `--workspaces` | boolean | Use package manager workspaces. (Default: `true`) | diff --git a/docs/generated/packages/nx/documents/create-nx-workspace.md b/docs/generated/packages/nx/documents/create-nx-workspace.md index 008b241dd1..c6117aef2f 100644 --- a/docs/generated/packages/nx/documents/create-nx-workspace.md +++ b/docs/generated/packages/nx/documents/create-nx-workspace.md @@ -46,6 +46,7 @@ Install `create-nx-workspace` globally to invoke the command directly, or use `n | `--style` | string | Stylesheet type to be used with certain stacks. | | `--unitTestRunner` | `jest`, `vitest`, `none` | Test runner to use for unit tests. | | `--useGitHub` | boolean | Will you be using GitHub as your git hosting provider? (Default: `false`) | +| `--useProjectJson` | boolean | Use a 'project.json' file for the Nx configuration instead of a 'package.json' file. This defaults to 'true' when '--no-workspaces' is used. Otherwise, it defaults to 'false'. | | `--useReactRouter` | boolean | Generate a Server-Side Rendered (SSR) React app using React Router. | | `--version` | boolean | Show version number. | | `--workspaces` | boolean | Use package manager workspaces. (Default: `true`) | diff --git a/docs/generated/packages/workspace/generators/new.json b/docs/generated/packages/workspace/generators/new.json index 24848877a9..f485a8d30b 100644 --- a/docs/generated/packages/workspace/generators/new.json +++ b/docs/generated/packages/workspace/generators/new.json @@ -108,6 +108,10 @@ "description": "Whether to use package manager workspaces.", "type": "boolean", "default": true + }, + "useProjectJson": { + "type": "boolean", + "description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file." } }, "additionalProperties": true, diff --git a/docs/generated/packages/workspace/generators/preset.json b/docs/generated/packages/workspace/generators/preset.json index 5a41e61a4e..bd928ff683 100644 --- a/docs/generated/packages/workspace/generators/preset.json +++ b/docs/generated/packages/workspace/generators/preset.json @@ -125,6 +125,10 @@ "description": "Whether to use package manager workspaces.", "type": "boolean", "default": true + }, + "useProjectJson": { + "type": "boolean", + "description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file." } }, "required": ["preset", "name"], diff --git a/packages/create-nx-workspace/bin/create-nx-workspace.ts b/packages/create-nx-workspace/bin/create-nx-workspace.ts index f1dbacc2a3..0e414c554d 100644 --- a/packages/create-nx-workspace/bin/create-nx-workspace.ts +++ b/packages/create-nx-workspace/bin/create-nx-workspace.ts @@ -35,6 +35,7 @@ interface BaseArguments extends CreateWorkspaceOptions { linter?: 'none' | 'eslint'; formatter?: 'none' | 'prettier'; workspaces?: boolean; + useProjectJson?: boolean; } interface NoneArguments extends BaseArguments { @@ -175,6 +176,10 @@ export const commandsObject: yargs.Argv = yargs type: 'boolean', default: true, }) + .option('useProjectJson', { + describe: chalk.dim`Use a 'project.json' file for the Nx configuration instead of a 'package.json' file. This defaults to 'true' when '--no-workspaces' is used. Otherwise, it defaults to 'false'.`, + type: 'boolean', + }) .option('formatter', { describe: chalk.dim`Code formatter to use.`, type: 'string', @@ -288,6 +293,7 @@ async function normalizeArgsMiddleware( }); argv.workspaces ??= true; + argv.useProjectJson ??= !argv.workspaces; try { argv.name = await determineFolder(argv); diff --git a/packages/workspace/src/generators/new/generate-preset.ts b/packages/workspace/src/generators/new/generate-preset.ts index 1d33963913..e52d22f36b 100644 --- a/packages/workspace/src/generators/new/generate-preset.ts +++ b/packages/workspace/src/generators/new/generate-preset.ts @@ -103,6 +103,7 @@ export function generatePreset(host: Tree, opts: NormalizedSchema) { opts.nxCloudToken ? `--nxCloudToken=${opts.nxCloudToken}` : null, opts.formatter ? `--formatter=${opts.formatter}` : null, opts.workspaces !== false ? `--workspaces` : `--no-workspaces`, + opts.useProjectJson ? `--useProjectJson` : null, ].filter((e) => !!e); } } diff --git a/packages/workspace/src/generators/new/new.ts b/packages/workspace/src/generators/new/new.ts index 0877bf361c..2036980844 100644 --- a/packages/workspace/src/generators/new/new.ts +++ b/packages/workspace/src/generators/new/new.ts @@ -43,6 +43,7 @@ interface Schema { formatter?: 'none' | 'prettier'; workspaces?: boolean; workspaceGlobs?: string | string[]; + useProjectJson?: boolean; } export interface NormalizedSchema extends Schema { diff --git a/packages/workspace/src/generators/new/schema.json b/packages/workspace/src/generators/new/schema.json index 71cbfd2d30..271f01294a 100644 --- a/packages/workspace/src/generators/new/schema.json +++ b/packages/workspace/src/generators/new/schema.json @@ -111,6 +111,10 @@ "description": "Whether to use package manager workspaces.", "type": "boolean", "default": true + }, + "useProjectJson": { + "type": "boolean", + "description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file." } }, "additionalProperties": true diff --git a/packages/workspace/src/generators/preset/preset.ts b/packages/workspace/src/generators/preset/preset.ts index 1bf779dcb9..7ecf966bf3 100644 --- a/packages/workspace/src/generators/preset/preset.ts +++ b/packages/workspace/src/generators/preset/preset.ts @@ -82,7 +82,7 @@ async function createPreset(tree: Tree, options: Schema) { nxCloudToken: options.nxCloudToken, useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else if (options.preset === Preset.ReactStandalone) { const { applicationGenerator: reactApplicationGenerator } = require('@nx' + @@ -121,7 +121,7 @@ async function createPreset(tree: Tree, options: Schema) { nxCloudToken: options.nxCloudToken, useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else if (options.preset === Preset.VueStandalone) { const { applicationGenerator: vueApplicationGenerator } = require('@nx' + @@ -153,7 +153,7 @@ async function createPreset(tree: Tree, options: Schema) { nxCloudToken: options.nxCloudToken, useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else if (options.preset === Preset.NuxtStandalone) { const { applicationGenerator: nuxtApplicationGenerator } = require('@nx' + @@ -186,7 +186,7 @@ async function createPreset(tree: Tree, options: Schema) { addPlugin, useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else if (options.preset === Preset.NextJsStandalone) { const { applicationGenerator: nextApplicationGenerator } = require('@nx' + @@ -231,7 +231,7 @@ async function createPreset(tree: Tree, options: Schema) { addPlugin, useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else if (options.preset === Preset.Express) { const { @@ -246,7 +246,7 @@ async function createPreset(tree: Tree, options: Schema) { addPlugin, useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else if (options.preset === Preset.ReactNative) { const { reactNativeApplicationGenerator } = require('@nx' + @@ -262,7 +262,7 @@ async function createPreset(tree: Tree, options: Schema) { bundler: options.bundler ?? 'webpack', useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else if (options.preset === Preset.Expo) { const { expoApplicationGenerator } = require('@nx' + '/expo'); @@ -276,7 +276,7 @@ async function createPreset(tree: Tree, options: Schema) { nxCloudToken: options.nxCloudToken, useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else if (options.preset === Preset.TS) { const { initGenerator } = require('@nx' + '/js'); @@ -330,7 +330,7 @@ async function createPreset(tree: Tree, options: Schema) { addPlugin, useTsSolution: options.workspaces, formatter: options.formatter, - useProjectJson: !options.workspaces, + useProjectJson: options.useProjectJson, }); } else { throw new Error(`Invalid preset ${options.preset}`); diff --git a/packages/workspace/src/generators/preset/schema.d.ts b/packages/workspace/src/generators/preset/schema.d.ts index dd7d8e777d..c83c8b4b18 100644 --- a/packages/workspace/src/generators/preset/schema.d.ts +++ b/packages/workspace/src/generators/preset/schema.d.ts @@ -25,4 +25,5 @@ export interface Schema { serverRouting?: boolean; prefix?: string; nxCloudToken?: string; + useProjectJson?: boolean; } diff --git a/packages/workspace/src/generators/preset/schema.json b/packages/workspace/src/generators/preset/schema.json index 968404fe4c..711c5504a6 100644 --- a/packages/workspace/src/generators/preset/schema.json +++ b/packages/workspace/src/generators/preset/schema.json @@ -128,6 +128,10 @@ "description": "Whether to use package manager workspaces.", "type": "boolean", "default": true + }, + "useProjectJson": { + "type": "boolean", + "description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file." } }, "required": ["preset", "name"]