feat(misc): enable ts solution setup by default for new workspaces (#30372)

## Current Behavior

To create a new workspace that uses the new TS solution setup the
`--workspaces` flag must be provided (Node, React, and Vue stacks).

## Expected Behavior

New workspaces should be created by default using the new TS solution
setup (Node, React, and Vue stacks). Users can opt out of it by
providing the `--no-workspaces` flag.

## Related Issue(s)

Fixes #
This commit is contained in:
Leosvel Pérez Espinosa 2025-03-14 17:42:31 +01:00 committed by GitHub
parent 398ab354e5
commit 2d69aa12bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 66 additions and 65 deletions

View File

@ -47,7 +47,7 @@ Install `create-nx-workspace` globally to invoke the command directly, or use `n
| `--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`) |
| `--version` | boolean | Show version number. |
| `--workspaces` | boolean | Use package manager workspaces. (Default: `false`) |
| `--workspaces` | boolean | Use package manager workspaces. (Default: `true`) |
| `--workspaceType` | `integrated`, `package-based`, `standalone` | The type of workspace to create. |
## Presets

View File

@ -47,7 +47,7 @@ Install `create-nx-workspace` globally to invoke the command directly, or use `n
| `--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`) |
| `--version` | boolean | Show version number. |
| `--workspaces` | boolean | Use package manager workspaces. (Default: `false`) |
| `--workspaces` | boolean | Use package manager workspaces. (Default: `true`) |
| `--workspaceType` | `integrated`, `package-based`, `standalone` | The type of workspace to create. |
## Presets

View File

@ -102,7 +102,7 @@
"workspaces": {
"description": "Whether to use package manager workspaces.",
"type": "boolean",
"default": false
"default": true
}
},
"additionalProperties": true,

View File

@ -119,7 +119,7 @@
"workspaces": {
"description": "Whether to use package manager workspaces.",
"type": "boolean",
"default": false
"default": true
}
},
"required": ["preset", "name"],

View File

@ -29,12 +29,16 @@ There are two different methods that Nx supports for linking TypeScript projects
## Project Linking with Workspaces
To create a new Nx workspace that links projects with package manager workspaces, use the `--workspaces` flag.
Create a new Nx workspace that links projects with package manager workspaces:
```shell
npx create-nx-workspace --workspaces
npx create-nx-workspace
```
{% callout type="note" title="Opt-out of Workspaces" %}
You can opt-out of workspaces by running `npx create-nx-workspace --no-workspaces`.
{% /callout %}
### Set Up Package Manager Workspaces
The configuration for package manager workspaces varies based on which package manager you're using.

View File

@ -8,9 +8,8 @@ description: A comprehensive reference of all environment variables that can be
The following environment variables are ones that you can set to change the behavior of Nx in different environments.
| Property | Type | Description |
| ------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| NX_ADD_PLUGINS | boolean | If set to `false`, Nx will not add plugins to infer tasks. This is `true` by default. Workspaces created before Nx 18 will have this disabled via a migration for backwards compatibility |
| NX_ADD_TS_PLUGIN | boolean | If set to `false` when creating a new workspace using the `ts` preset, Nx will not add the `@nx/js/typescript` plugin to infer tasks and will not set up the workspace with [TypeScript project references](https://www.typescriptlang.org/docs/handbook/project-references.html). This is `true` by default. |
| NX_BASE | string | The default base branch to use when calculating the affected projects. Can be overridden on the command line with `--base`. |
| NX_CACHE_DIRECTORY | string | The cache for task outputs is stored in `.nx/cache` by default. Set this variable to use a different directory. |
| NX_CACHE_PROJECT_GRAPH | boolean | If set to `false`, disables the project graph cache. Most useful when developing a plugin that modifies the project graph. |

View File

@ -52,7 +52,7 @@ title="Nx React Monorepo Tutorial Walkthrough"
Create a new React monorepo with the following command:
```{% command="npx create-nx-workspace@latest react-monorepo --preset=react-monorepo --workspaces" path="~" %}
```{% command="npx create-nx-workspace@latest react-monorepo --preset=react-monorepo" path="~" %}
NX Let's create a new workspace [https://nx.dev/getting-started/intro]

View File

@ -167,7 +167,7 @@ export const commandsObject: yargs.Argv<Arguments> = yargs
.option('workspaces', {
describe: chalk.dim`Use package manager workspaces.`,
type: 'boolean',
default: false,
default: true,
})
.option('formatter', {
describe: chalk.dim`Code formatter to use.`,
@ -281,6 +281,8 @@ async function normalizeArgsMiddleware(
"Let's create a new workspace [https://nx.dev/getting-started/intro]",
});
argv.workspaces ??= true;
try {
argv.name = await determineFolder(argv);
if (!argv.preset || isKnownPreset(argv.preset)) {
@ -414,8 +416,7 @@ async function determineStack(
{
name: `none`,
message:
process.env.NX_ADD_PLUGINS !== 'false' &&
process.env.NX_ADD_TS_PLUGIN !== 'false'
process.env.NX_ADD_PLUGINS !== 'false' && parsedArgs.workspaces
? `None: Configures a TypeScript/JavaScript monorepo.`
: `None: Configures a TypeScript/JavaScript project with minimal structure.`,
},
@ -519,7 +520,7 @@ async function determineNoneOptions(
if (
(!parsedArgs.preset || parsedArgs.preset === Preset.TS) &&
process.env.NX_ADD_PLUGINS !== 'false' &&
process.env.NX_ADD_TS_PLUGIN !== 'false'
parsedArgs.workspaces
) {
return {
preset: Preset.TS,
@ -595,7 +596,7 @@ async function determineReactOptions(
let linter: undefined | 'none' | 'eslint';
let formatter: undefined | 'none' | 'prettier';
const workspaces = parsedArgs.workspaces ?? false;
const workspaces = parsedArgs.workspaces;
if (parsedArgs.preset && parsedArgs.preset !== Preset.React) {
preset = parsedArgs.preset;
@ -764,7 +765,7 @@ async function determineVueOptions(
let linter: undefined | 'none' | 'eslint';
let formatter: undefined | 'none' | 'prettier';
const workspaces = parsedArgs.workspaces ?? false;
const workspaces = parsedArgs.workspaces;
if (parsedArgs.preset && parsedArgs.preset !== Preset.Vue) {
preset = parsedArgs.preset;
@ -1032,7 +1033,7 @@ async function determineNodeOptions(
let linter: undefined | 'none' | 'eslint';
let formatter: undefined | 'none' | 'prettier';
let unitTestRunner: undefined | 'none' | 'jest' = undefined;
const workspaces = parsedArgs.workspaces ?? false;
const workspaces = parsedArgs.workspaces;
if (parsedArgs.preset) {
preset = parsedArgs.preset;

View File

@ -89,8 +89,7 @@ export async function initGeneratorInternal(
schema.addPlugin ??=
process.env.NX_ADD_PLUGINS !== 'false' &&
nxJson.useInferencePlugins !== false;
schema.addTsPlugin ??=
schema.addPlugin && process.env.NX_ADD_TS_PLUGIN !== 'false';
schema.addTsPlugin ??= schema.addPlugin;
if (schema.addTsPlugin) {
await addPlugin(

View File

@ -62,10 +62,6 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
const options = await normalizeOptions(host, schema);
if (options.isUsingTsSolutionConfig) {
await addProjectToTsSolutionWorkspace(host, options.projectRoot);
}
if (options.publishable === true && !schema.importPath) {
throw new Error(
`For publishable libs you have to provide a proper "--importPath" which needs to be a valid npm package name (e.g. my-awesome-lib or @myorg/my-lib)`
@ -112,6 +108,10 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
createFiles(host, options);
if (options.isUsingTsSolutionConfig) {
await addProjectToTsSolutionWorkspace(host, options.projectRoot);
}
const lintTask = await addLinting(host, options);
tasks.push(lintTask);

View File

@ -99,7 +99,7 @@ export function generatePreset(host: Tree, opts: NormalizedSchema) {
opts.prefix !== undefined ? `--prefix=${opts.prefix}` : null,
opts.nxCloudToken ? `--nxCloudToken=${opts.nxCloudToken}` : null,
opts.formatter ? `--formatter=${opts.formatter}` : null,
opts.workspaces ? `--workspaces` : null,
opts.workspaces !== false ? `--workspaces` : `--no-workspaces`,
].filter((e) => !!e);
}
}

View File

@ -85,6 +85,7 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
appName,
isCustomPreset: false,
nxCloud: nxCloud,
workspaces: true,
});
await formatFiles(tree);
const dir = join(__dirname, 'tmp', `${preset}-${nxCloud}`);

View File

@ -275,8 +275,8 @@ function createFiles(tree: Tree, options: NormalizedSchema) {
options.preset === Preset.TsStandalone
? './files-root-app'
: (options.preset === Preset.TS &&
process.env.NX_ADD_PLUGINS !== 'false' &&
process.env.NX_ADD_TS_PLUGIN !== 'false') ||
options.workspaces &&
process.env.NX_ADD_PLUGINS !== 'false') ||
options.preset === Preset.NPM
? './files-package-based-repo'
: './files-integrated-repo';
@ -294,7 +294,7 @@ function createFiles(tree: Tree, options: NormalizedSchema) {
async function createReadme(
tree: Tree,
{ name, appName, directory, preset, nxCloud }: NormalizedSchema,
{ name, appName, directory, preset, nxCloud, workspaces }: NormalizedSchema,
nxCloudToken?: string
) {
const formattedNames = names(name);
@ -314,8 +314,7 @@ async function createReadme(
isJsStandalone: preset === Preset.TsStandalone,
isTsPreset: preset === Preset.TS,
isUsingNewTsSolutionSetup:
process.env.NX_ADD_PLUGINS !== 'false' &&
process.env.NX_ADD_TS_PLUGIN !== 'false',
process.env.NX_ADD_PLUGINS !== 'false' && workspaces,
isEmptyRepo: !appName,
appName,
generateAppCmd: presetInfo.generateAppCmd,
@ -416,7 +415,7 @@ function setUpWorkspacesInPackageJson(tree: Tree, options: NormalizedSchema) {
options.preset === Preset.NPM ||
(options.preset === Preset.TS &&
process.env.NX_ADD_PLUGINS !== 'false' &&
process.env.NX_ADD_TS_PLUGIN !== 'false') ||
options.workspaces) ||
((options.preset === Preset.Expo ||
options.preset === Preset.NextJs ||
options.preset === Preset.ReactMonorepo ||

View File

@ -105,7 +105,7 @@
"workspaces": {
"description": "Whether to use package manager workspaces.",
"type": "boolean",
"default": false
"default": true
}
},
"additionalProperties": true

View File

@ -309,9 +309,7 @@ async function createPreset(tree: Tree, options: Schema) {
const { initGenerator } = require('@nx' + '/js');
return initGenerator(tree, {
formatter: options.formatter,
addTsPlugin:
process.env.NX_ADD_PLUGINS !== 'false' &&
process.env.NX_ADD_TS_PLUGIN !== 'false',
addTsPlugin: process.env.NX_ADD_PLUGINS !== 'false' && options.workspaces,
});
} else if (options.preset === Preset.TsStandalone) {
const { libraryGenerator } = require('@nx' + '/js');

View File

@ -122,7 +122,7 @@
"workspaces": {
"description": "Whether to use package manager workspaces.",
"type": "boolean",
"default": false
"default": true
}
},
"required": ["preset", "name"]