@nx/workspace 20.4.0-canary.20250123-7524356 → 20.4.0-canary.20250125-15fc599
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +3 -3
- package/src/generators/convert-to-monorepo/convert-to-monorepo.js +6 -3
- package/src/generators/move/lib/normalize-schema.js +6 -4
- package/src/generators/move/lib/utils.d.ts +0 -16
- package/src/generators/move/lib/utils.js +0 -31
- package/src/generators/new/generate-preset.js +3 -0
- package/src/generators/new/new.d.ts +1 -0
- package/src/generators/new/schema.json +5 -0
- package/src/generators/preset/preset.js +21 -6
- package/src/generators/preset/schema.d.ts +1 -0
- package/src/generators/preset/schema.json +5 -0
- package/src/utils/ts-solution-setup.d.ts +2 -0
- package/src/utils/ts-solution-setup.js +21 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nx/workspace",
|
3
|
-
"version": "20.4.0-canary.
|
3
|
+
"version": "20.4.0-canary.20250125-15fc599",
|
4
4
|
"private": false,
|
5
5
|
"description": "The Workspace plugin contains executors and generators that are useful for any Nx workspace. It should be present in every Nx workspace and other plugins build on it.",
|
6
6
|
"repository": {
|
@@ -38,12 +38,12 @@
|
|
38
38
|
}
|
39
39
|
},
|
40
40
|
"dependencies": {
|
41
|
-
"@nx/devkit": "20.4.0-canary.
|
41
|
+
"@nx/devkit": "20.4.0-canary.20250125-15fc599",
|
42
42
|
"chalk": "^4.1.0",
|
43
43
|
"enquirer": "~2.3.6",
|
44
44
|
"tslib": "^2.3.0",
|
45
45
|
"yargs-parser": "21.1.1",
|
46
|
-
"nx": "20.4.0-canary.
|
46
|
+
"nx": "20.4.0-canary.20250125-15fc599"
|
47
47
|
},
|
48
48
|
"publishConfig": {
|
49
49
|
"access": "public"
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.monorepoGenerator = monorepoGenerator;
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
5
5
|
const move_1 = require("../move/move");
|
6
|
+
const ts_solution_setup_1 = require("../../utils/ts-solution-setup");
|
6
7
|
async function monorepoGenerator(tree, options) {
|
7
8
|
const projects = (0, devkit_1.getProjects)(tree);
|
8
9
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
@@ -22,7 +23,8 @@ async function monorepoGenerator(tree, options) {
|
|
22
23
|
// Currently, Nx only handles apps+libs or packages. You cannot mix and match them.
|
23
24
|
// If the standalone project is an app (React, Angular, etc), then use apps+libs.
|
24
25
|
// Otherwise, for TS standalone (lib), use packages.
|
25
|
-
const isRootProjectApp = rootProject.projectType ===
|
26
|
+
const isRootProjectApp = (0, ts_solution_setup_1.getProjectType)(tree, rootProject.root, rootProject.projectType) ===
|
27
|
+
'application';
|
26
28
|
const appsDir = isRootProjectApp ? 'apps' : 'packages';
|
27
29
|
const libsDir = isRootProjectApp ? 'libs' : 'packages';
|
28
30
|
if (rootProject) {
|
@@ -38,13 +40,14 @@ async function monorepoGenerator(tree, options) {
|
|
38
40
|
});
|
39
41
|
}
|
40
42
|
for (const project of projectsToMove) {
|
43
|
+
const projectType = (0, ts_solution_setup_1.getProjectType)(tree, project.root, project.projectType);
|
41
44
|
await (0, move_1.moveGenerator)(tree, {
|
42
45
|
projectName: project.name,
|
43
46
|
newProjectName: project.name,
|
44
|
-
destination:
|
47
|
+
destination: projectType === 'application'
|
45
48
|
? (0, devkit_1.joinPathFragments)(appsDir, project.root === '.' ? project.name : project.root)
|
46
49
|
: (0, devkit_1.joinPathFragments)(libsDir, project.root === '.' ? project.name : project.root),
|
47
|
-
updateImportPath:
|
50
|
+
updateImportPath: projectType === 'library',
|
48
51
|
});
|
49
52
|
}
|
50
53
|
}
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.normalizeSchema = normalizeSchema;
|
4
4
|
const get_import_path_1 = require("../../../utilities/get-import-path");
|
5
5
|
const utils_1 = require("./utils");
|
6
|
+
const ts_solution_setup_1 = require("../../../utils/ts-solution-setup");
|
6
7
|
async function normalizeSchema(tree, schema, projectConfiguration) {
|
7
8
|
const { destination, newProjectName, importPath } = await determineProjectNameAndRootOptions(tree, schema, projectConfiguration);
|
8
9
|
return {
|
@@ -14,11 +15,11 @@ async function normalizeSchema(tree, schema, projectConfiguration) {
|
|
14
15
|
};
|
15
16
|
}
|
16
17
|
async function determineProjectNameAndRootOptions(tree, options, projectConfiguration) {
|
17
|
-
validateName(options.newProjectName, projectConfiguration);
|
18
|
+
validateName(tree, options.newProjectName, projectConfiguration);
|
18
19
|
const projectNameAndRootOptions = getProjectNameAndRootOptions(tree, options, projectConfiguration);
|
19
20
|
return projectNameAndRootOptions;
|
20
21
|
}
|
21
|
-
function validateName(name, projectConfiguration) {
|
22
|
+
function validateName(tree, name, projectConfiguration) {
|
22
23
|
if (!name) {
|
23
24
|
return;
|
24
25
|
}
|
@@ -34,13 +35,14 @@ function validateName(name, projectConfiguration) {
|
|
34
35
|
*/
|
35
36
|
const libraryPattern = '(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$';
|
36
37
|
const appPattern = '^[a-zA-Z][^:]*$';
|
37
|
-
|
38
|
+
const projectType = (0, ts_solution_setup_1.getProjectType)(tree, projectConfiguration.root, projectConfiguration.projectType);
|
39
|
+
if (projectType === 'application') {
|
38
40
|
const validationRegex = new RegExp(appPattern);
|
39
41
|
if (!validationRegex.test(name)) {
|
40
42
|
throw new Error(`The new project name should match the pattern "${appPattern}". The provided value "${name}" does not match.`);
|
41
43
|
}
|
42
44
|
}
|
43
|
-
else if (projectConfiguration.projectType === 'library') {
|
45
|
+
else if ((0, ts_solution_setup_1.getProjectType)(tree, projectConfiguration.root, projectConfiguration.projectType) === 'library') {
|
44
46
|
const validationRegex = new RegExp(libraryPattern);
|
45
47
|
if (!validationRegex.test(name)) {
|
46
48
|
throw new Error(`The new project name should match the pattern "${libraryPattern}". The provided value "${name}" does not match.`);
|
@@ -1,19 +1,3 @@
|
|
1
|
-
import { ProjectConfiguration, Tree } from '@nx/devkit';
|
2
|
-
import { Schema } from '../schema';
|
3
|
-
/**
|
4
|
-
* This helper function ensures that we don't move libs or apps
|
5
|
-
* outside of the folders they should be in.
|
6
|
-
*
|
7
|
-
* This will break if someone isn't using the default libs/apps
|
8
|
-
* folders. In that case, they're on their own :/
|
9
|
-
*/
|
10
|
-
export declare function getDestination(host: Tree, schema: Schema, project: ProjectConfiguration): string;
|
11
|
-
/**
|
12
|
-
* Joins path segments replacing slashes with dashes
|
13
|
-
*
|
14
|
-
* @param path
|
15
|
-
*/
|
16
|
-
export declare function getNewProjectName(path: string): string;
|
17
1
|
/**
|
18
2
|
* Normalizes slashes (removes duplicates)
|
19
3
|
*
|
@@ -1,38 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.getDestination = getDestination;
|
4
|
-
exports.getNewProjectName = getNewProjectName;
|
5
3
|
exports.normalizePathSlashes = normalizePathSlashes;
|
6
4
|
const devkit_1 = require("@nx/devkit");
|
7
|
-
/**
|
8
|
-
* This helper function ensures that we don't move libs or apps
|
9
|
-
* outside of the folders they should be in.
|
10
|
-
*
|
11
|
-
* This will break if someone isn't using the default libs/apps
|
12
|
-
* folders. In that case, they're on their own :/
|
13
|
-
*/
|
14
|
-
function getDestination(host, schema, project) {
|
15
|
-
const projectType = project.projectType;
|
16
|
-
const workspaceLayout = (0, devkit_1.getWorkspaceLayout)(host);
|
17
|
-
let rootFolder = workspaceLayout.libsDir;
|
18
|
-
if (projectType === 'application') {
|
19
|
-
rootFolder = workspaceLayout.appsDir;
|
20
|
-
}
|
21
|
-
return (0, devkit_1.joinPathFragments)(rootFolder, schema.destination);
|
22
|
-
}
|
23
|
-
/**
|
24
|
-
* Joins path segments replacing slashes with dashes
|
25
|
-
*
|
26
|
-
* @param path
|
27
|
-
*/
|
28
|
-
function getNewProjectName(path) {
|
29
|
-
// strip leading '/' or './' or '../' and trailing '/' and replaces '/' with '-'
|
30
|
-
return (0, devkit_1.normalizePath)(path)
|
31
|
-
.replace(/(^\.{0,2}\/|\.{1,2}\/|\/$)/g, '')
|
32
|
-
.split('/')
|
33
|
-
.filter((x) => !!x)
|
34
|
-
.join('-');
|
35
|
-
}
|
36
5
|
/**
|
37
6
|
* Normalizes slashes (removes duplicates)
|
38
7
|
*
|
@@ -70,6 +70,9 @@ function generatePreset(host, opts) {
|
|
70
70
|
: null,
|
71
71
|
parsedArgs.interactive ? '--interactive=true' : '--interactive=false',
|
72
72
|
opts.routing !== undefined ? `--routing=${opts.routing}` : null,
|
73
|
+
opts.unitTestRunner !== undefined
|
74
|
+
? `--unitTestRunner=${opts.unitTestRunner}`
|
75
|
+
: null,
|
73
76
|
opts.e2eTestRunner !== undefined
|
74
77
|
? `--e2eTestRunner=${opts.e2eTestRunner}`
|
75
78
|
: null,
|
@@ -18,6 +18,7 @@ interface Schema {
|
|
18
18
|
standaloneApi?: boolean;
|
19
19
|
routing?: boolean;
|
20
20
|
packageManager?: PackageManager;
|
21
|
+
unitTestRunner?: 'jest' | 'vitest' | 'none';
|
21
22
|
e2eTestRunner?: 'cypress' | 'playwright' | 'detox' | 'jest' | 'none';
|
22
23
|
ssr?: boolean;
|
23
24
|
serverRouting?: boolean;
|
@@ -73,6 +73,11 @@
|
|
73
73
|
"type": "boolean",
|
74
74
|
"default": true
|
75
75
|
},
|
76
|
+
"unitTestRunner": {
|
77
|
+
"description": "The tool to use for running unit tests.",
|
78
|
+
"type": "string",
|
79
|
+
"enum": ["jest", "vitest", "none"]
|
80
|
+
},
|
76
81
|
"e2eTestRunner": {
|
77
82
|
"description": "The tool to use for running e2e tests.",
|
78
83
|
"type": "string",
|
@@ -30,6 +30,7 @@ async function createPreset(tree, options) {
|
|
30
30
|
standalone: options.standaloneApi,
|
31
31
|
routing: options.routing,
|
32
32
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
33
|
+
unitTestRunner: options.unitTestRunner,
|
33
34
|
bundler: options.bundler,
|
34
35
|
ssr: options.ssr,
|
35
36
|
serverRouting: options.serverRouting,
|
@@ -48,6 +49,7 @@ async function createPreset(tree, options) {
|
|
48
49
|
rootProject: true,
|
49
50
|
standalone: options.standaloneApi,
|
50
51
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
52
|
+
unitTestRunner: options.unitTestRunner,
|
51
53
|
bundler: options.bundler,
|
52
54
|
ssr: options.ssr,
|
53
55
|
serverRouting: options.serverRouting,
|
@@ -65,6 +67,8 @@ async function createPreset(tree, options) {
|
|
65
67
|
linter: options.linter,
|
66
68
|
bundler: options.bundler ?? 'webpack',
|
67
69
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
70
|
+
unitTestRunner: options.unitTestRunner ??
|
71
|
+
(options.bundler === 'vite' ? 'vitest' : 'jest'),
|
68
72
|
addPlugin,
|
69
73
|
nxCloudToken: options.nxCloudToken,
|
70
74
|
useTsSolution: options.workspaces,
|
@@ -74,15 +78,16 @@ async function createPreset(tree, options) {
|
|
74
78
|
else if (options.preset === presets_1.Preset.ReactStandalone) {
|
75
79
|
const { applicationGenerator: reactApplicationGenerator } = require('@nx' +
|
76
80
|
'/react');
|
81
|
+
const bundler = options.bundler ?? 'vite';
|
77
82
|
return reactApplicationGenerator(tree, {
|
78
83
|
name: options.name,
|
79
84
|
directory: '.',
|
80
85
|
style: options.style,
|
81
86
|
linter: options.linter,
|
82
87
|
rootProject: true,
|
83
|
-
bundler
|
88
|
+
bundler,
|
84
89
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
85
|
-
unitTestRunner: options.bundler === 'vite' ? 'vitest' : 'jest',
|
90
|
+
unitTestRunner: options.unitTestRunner ?? (bundler === 'vite' ? 'vitest' : 'jest'),
|
86
91
|
addPlugin,
|
87
92
|
nxCloudToken: options.nxCloudToken,
|
88
93
|
formatter: options.formatter,
|
@@ -96,7 +101,7 @@ async function createPreset(tree, options) {
|
|
96
101
|
directory: (0, path_1.join)('apps', options.name),
|
97
102
|
linter: options.linter,
|
98
103
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
99
|
-
unitTestRunner: 'vitest',
|
104
|
+
unitTestRunner: options.unitTestRunner ?? 'vitest',
|
100
105
|
addPlugin,
|
101
106
|
nxCloudToken: options.nxCloudToken,
|
102
107
|
useTsSolution: options.workspaces,
|
@@ -112,7 +117,7 @@ async function createPreset(tree, options) {
|
|
112
117
|
linter: options.linter,
|
113
118
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
114
119
|
rootProject: true,
|
115
|
-
unitTestRunner: 'vitest',
|
120
|
+
unitTestRunner: options.unitTestRunner ?? 'vitest',
|
116
121
|
addPlugin,
|
117
122
|
nxCloudToken: options.nxCloudToken,
|
118
123
|
formatter: options.formatter,
|
@@ -127,6 +132,7 @@ async function createPreset(tree, options) {
|
|
127
132
|
style: options.style,
|
128
133
|
linter: options.linter,
|
129
134
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
135
|
+
unitTestRunner: options.unitTestRunner,
|
130
136
|
addPlugin,
|
131
137
|
nxCloudToken: options.nxCloudToken,
|
132
138
|
useTsSolution: options.workspaces,
|
@@ -143,7 +149,7 @@ async function createPreset(tree, options) {
|
|
143
149
|
linter: options.linter,
|
144
150
|
rootProject: true,
|
145
151
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
146
|
-
unitTestRunner: 'vitest',
|
152
|
+
unitTestRunner: options.unitTestRunner ?? 'vitest',
|
147
153
|
addPlugin,
|
148
154
|
nxCloudToken: options.nxCloudToken,
|
149
155
|
});
|
@@ -157,6 +163,7 @@ async function createPreset(tree, options) {
|
|
157
163
|
style: options.style,
|
158
164
|
linter: options.linter,
|
159
165
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
166
|
+
unitTestRunner: options.unitTestRunner,
|
160
167
|
addPlugin,
|
161
168
|
nxCloudToken: options.nxCloudToken,
|
162
169
|
useTsSolution: options.workspaces,
|
@@ -173,7 +180,7 @@ async function createPreset(tree, options) {
|
|
173
180
|
linter: options.linter,
|
174
181
|
rootProject: true,
|
175
182
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
176
|
-
unitTestRunner: 'vitest',
|
183
|
+
unitTestRunner: options.unitTestRunner ?? 'vitest',
|
177
184
|
addPlugin,
|
178
185
|
nxCloudToken: options.nxCloudToken,
|
179
186
|
});
|
@@ -189,6 +196,7 @@ async function createPreset(tree, options) {
|
|
189
196
|
appDir: options.nextAppDir,
|
190
197
|
src: options.nextSrcDir,
|
191
198
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
199
|
+
unitTestRunner: options.unitTestRunner,
|
192
200
|
addPlugin,
|
193
201
|
useTsSolution: options.workspaces,
|
194
202
|
formatter: options.formatter,
|
@@ -205,6 +213,7 @@ async function createPreset(tree, options) {
|
|
205
213
|
appDir: options.nextAppDir,
|
206
214
|
src: options.nextSrcDir,
|
207
215
|
e2eTestRunner: options.e2eTestRunner ?? 'playwright',
|
216
|
+
unitTestRunner: options.unitTestRunner,
|
208
217
|
rootProject: true,
|
209
218
|
addPlugin,
|
210
219
|
formatter: options.formatter,
|
@@ -232,6 +241,7 @@ async function createPreset(tree, options) {
|
|
232
241
|
directory: (0, path_1.join)('apps', options.name),
|
233
242
|
linter: options.linter,
|
234
243
|
e2eTestRunner: options.e2eTestRunner ?? 'jest',
|
244
|
+
unitTestRunner: options.unitTestRunner,
|
235
245
|
addPlugin,
|
236
246
|
useTsSolution: options.workspaces,
|
237
247
|
formatter: options.formatter,
|
@@ -244,6 +254,7 @@ async function createPreset(tree, options) {
|
|
244
254
|
directory: (0, path_1.join)('apps', options.name),
|
245
255
|
linter: options.linter,
|
246
256
|
e2eTestRunner: options.e2eTestRunner ?? 'jest',
|
257
|
+
unitTestRunner: options.unitTestRunner,
|
247
258
|
addPlugin,
|
248
259
|
useTsSolution: options.workspaces,
|
249
260
|
formatter: options.formatter,
|
@@ -257,6 +268,7 @@ async function createPreset(tree, options) {
|
|
257
268
|
directory: (0, path_1.join)('apps', options.name),
|
258
269
|
linter: options.linter,
|
259
270
|
e2eTestRunner: options.e2eTestRunner ?? 'detox',
|
271
|
+
unitTestRunner: options.unitTestRunner,
|
260
272
|
addPlugin,
|
261
273
|
nxCloudToken: options.nxCloudToken,
|
262
274
|
bundler: options.bundler ?? 'webpack',
|
@@ -271,6 +283,7 @@ async function createPreset(tree, options) {
|
|
271
283
|
directory: (0, path_1.join)('apps', options.name),
|
272
284
|
linter: options.linter,
|
273
285
|
e2eTestRunner: options.e2eTestRunner ?? 'detox',
|
286
|
+
unitTestRunner: options.unitTestRunner,
|
274
287
|
addPlugin,
|
275
288
|
nxCloudToken: options.nxCloudToken,
|
276
289
|
useTsSolution: options.workspaces,
|
@@ -312,6 +325,7 @@ async function createPreset(tree, options) {
|
|
312
325
|
docker: options.docker,
|
313
326
|
rootProject: true,
|
314
327
|
e2eTestRunner: options.e2eTestRunner ?? 'jest',
|
328
|
+
unitTestRunner: options.unitTestRunner,
|
315
329
|
addPlugin,
|
316
330
|
});
|
317
331
|
}
|
@@ -328,6 +342,7 @@ async function createPreset(tree, options) {
|
|
328
342
|
docker: options.docker,
|
329
343
|
rootProject: false,
|
330
344
|
e2eTestRunner: options.e2eTestRunner ?? 'jest',
|
345
|
+
unitTestRunner: options.unitTestRunner,
|
331
346
|
addPlugin,
|
332
347
|
useTsSolution: options.workspaces,
|
333
348
|
formatter: options.formatter,
|
@@ -90,6 +90,11 @@
|
|
90
90
|
"type": "boolean",
|
91
91
|
"default": true
|
92
92
|
},
|
93
|
+
"unitTestRunner": {
|
94
|
+
"description": "The tool to use for running unit tests.",
|
95
|
+
"type": "string",
|
96
|
+
"enum": ["jest", "vitest", "none"]
|
97
|
+
},
|
93
98
|
"e2eTestRunner": {
|
94
99
|
"description": "The tool to use for running e2e tests.",
|
95
100
|
"type": "string",
|
@@ -0,0 +1,21 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getProjectType = getProjectType;
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
5
|
+
// This is copied from `@nx/js` to avoid circular dependencies.
|
6
|
+
function getProjectType(tree, projectRoot, projectType) {
|
7
|
+
if (projectType)
|
8
|
+
return projectType;
|
9
|
+
if ((0, devkit_1.joinPathFragments)(projectRoot, 'tsconfig.lib.json'))
|
10
|
+
return 'library';
|
11
|
+
if ((0, devkit_1.joinPathFragments)(projectRoot, 'tsconfig.app.json'))
|
12
|
+
return 'application';
|
13
|
+
// If there are no exports, assume it is an application since both buildable and non-buildable libraries have exports.
|
14
|
+
const packageJsonPath = (0, devkit_1.joinPathFragments)(projectRoot, 'package.json');
|
15
|
+
const packageJson = tree.exists(packageJsonPath)
|
16
|
+
? (0, devkit_1.readJson)(tree, (0, devkit_1.joinPathFragments)(projectRoot, 'package.json'))
|
17
|
+
: null;
|
18
|
+
if (!packageJson?.exports)
|
19
|
+
return 'application';
|
20
|
+
return 'library';
|
21
|
+
}
|