@nx/plugin 23.2.0-canary.20260720-beb379f → 23.2.0-canary.20260722-6a072a2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/generators/e2e-project/e2e.d.ts +1 -1
- package/dist/src/generators/e2e-project/e2e.js +117 -2
- package/dist/src/generators/e2e-project/files/src/__simplePluginName__.spec.ts__tmpl__ +2 -2
- package/dist/src/generators/e2e-project/schema.d.ts +1 -0
- package/dist/src/generators/e2e-project/schema.json +6 -0
- package/dist/src/generators/plugin/plugin.js +6 -0
- package/dist/src/generators/plugin/schema.d.ts +1 -1
- package/dist/src/generators/plugin/schema.json +1 -1
- package/package.json +14 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Tree, type GeneratorCallback } from '@nx/devkit';
|
|
2
2
|
import type { Schema } from './schema';
|
|
3
3
|
export declare function e2eProjectGenerator(host: Tree, schema: Schema): Promise<GeneratorCallback>;
|
|
4
4
|
export declare function e2eProjectGeneratorInternal(host: Tree, schema: Schema): Promise<GeneratorCallback>;
|
|
@@ -9,6 +9,7 @@ const jest_1 = require("@nx/jest");
|
|
|
9
9
|
const js_1 = require("@nx/js");
|
|
10
10
|
const internal_2 = require("@nx/js/internal");
|
|
11
11
|
const path_1 = require("path");
|
|
12
|
+
const versions_1 = require("../../utils/versions");
|
|
12
13
|
async function normalizeOptions(host, options) {
|
|
13
14
|
const linter = await (0, internal_2.normalizeLinterOption)(host, options.linter);
|
|
14
15
|
const projectName = options.rootProject ? 'e2e' : `${options.pluginName}-e2e`;
|
|
@@ -112,6 +113,112 @@ async function addJest(host, options) {
|
|
|
112
113
|
}
|
|
113
114
|
return jestTask;
|
|
114
115
|
}
|
|
116
|
+
async function addVitest(host, options) {
|
|
117
|
+
const projectConfiguration = {
|
|
118
|
+
name: options.projectName,
|
|
119
|
+
root: options.projectRoot,
|
|
120
|
+
projectType: 'application',
|
|
121
|
+
sourceRoot: `${options.projectRoot}/src`,
|
|
122
|
+
implicitDependencies: [options.pluginName],
|
|
123
|
+
};
|
|
124
|
+
if (options.isTsSolutionSetup) {
|
|
125
|
+
(0, devkit_1.writeJson)(host, (0, devkit_1.joinPathFragments)(options.projectRoot, 'package.json'), {
|
|
126
|
+
name: options.projectName,
|
|
127
|
+
version: '0.0.1',
|
|
128
|
+
private: true,
|
|
129
|
+
});
|
|
130
|
+
(0, devkit_1.updateProjectConfiguration)(host, options.projectName, projectConfiguration);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
projectConfiguration.targets = {};
|
|
134
|
+
(0, devkit_1.addProjectConfiguration)(host, options.projectName, projectConfiguration);
|
|
135
|
+
}
|
|
136
|
+
(0, devkit_1.ensurePackage)('@nx/vitest', versions_1.nxVersion);
|
|
137
|
+
// Use `require` rather than a dynamic `import()`: `ensurePackage` makes the
|
|
138
|
+
// on-demand-installed package resolvable via CJS resolution only, so a true
|
|
139
|
+
// ESM dynamic import cannot see the temp install.
|
|
140
|
+
const { configurationGenerator: vitestConfigurationGenerator, } = require('@nx/vitest/generators');
|
|
141
|
+
const vitestTask = await vitestConfigurationGenerator(host, {
|
|
142
|
+
project: options.projectName,
|
|
143
|
+
testTarget: 'e2e',
|
|
144
|
+
skipFormat: true,
|
|
145
|
+
addPlugin: options.addPlugin,
|
|
146
|
+
testEnvironment: 'node',
|
|
147
|
+
coverageProvider: 'none',
|
|
148
|
+
});
|
|
149
|
+
(0, internal_2.addLocalRegistryScripts)(host);
|
|
150
|
+
// Vitest has no `globalTeardown` option. Its `globalSetup` file must export
|
|
151
|
+
// both `setup` and `teardown`, so wire the local registry scripts through a
|
|
152
|
+
// wrapper module. Without the teardown, the verdaccio process started in
|
|
153
|
+
// setup outlives the test run.
|
|
154
|
+
const vitestGlobalSetupPath = 'tools/scripts/vitest-global-setup.ts';
|
|
155
|
+
if (!host.exists(vitestGlobalSetupPath)) {
|
|
156
|
+
host.write(vitestGlobalSetupPath, `/**
|
|
157
|
+
* This script adapts the local registry scripts to vitest's globalSetup
|
|
158
|
+
* lifecycle: vitest calls the exported setup and teardown functions around
|
|
159
|
+
* the test run.
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
export { default as setup } from './start-local-registry';
|
|
163
|
+
export { default as teardown } from './stop-local-registry';
|
|
164
|
+
`);
|
|
165
|
+
}
|
|
166
|
+
// Add globalSetup to vitest config
|
|
167
|
+
// Check for both .mts and .ts extensions (mts is checked first as it's the default created by @nx/vitest)
|
|
168
|
+
const vitestConfigExtensions = ['mts', 'ts'];
|
|
169
|
+
let vitestConfigPath;
|
|
170
|
+
for (const ext of vitestConfigExtensions) {
|
|
171
|
+
const configPath = (0, devkit_1.joinPathFragments)(options.projectRoot, `vitest.config.${ext}`);
|
|
172
|
+
if (host.exists(configPath)) {
|
|
173
|
+
vitestConfigPath = configPath;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (vitestConfigPath) {
|
|
178
|
+
let vitestConfig = host.read(vitestConfigPath, 'utf-8');
|
|
179
|
+
const globalSetupPath = (0, path_1.join)((0, devkit_1.offsetFromRoot)(options.projectRoot), vitestGlobalSetupPath);
|
|
180
|
+
// Insert globalSetup in the test config
|
|
181
|
+
// Look for 'test: {' and insert our properties right after the opening brace
|
|
182
|
+
const testConfigRegex = /(test:\s*\{\s*)/;
|
|
183
|
+
const match = testConfigRegex.exec(vitestConfig);
|
|
184
|
+
if (match) {
|
|
185
|
+
// Extract the indentation from the next line to maintain consistent formatting
|
|
186
|
+
const afterMatch = vitestConfig.slice(match.index + match[0].length);
|
|
187
|
+
const nextLineMatch = afterMatch.match(/\n(\s*)/);
|
|
188
|
+
const indent = nextLineMatch ? nextLineMatch[1] : ' ';
|
|
189
|
+
vitestConfig = vitestConfig.replace(testConfigRegex, `$1\n${indent}globalSetup: '${globalSetupPath}',`);
|
|
190
|
+
host.write(vitestConfigPath, vitestConfig);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
// If we can't find the test config block, log a warning
|
|
194
|
+
throw new Error(`Could not find test configuration block in ${vitestConfigPath}. Please manually add the globalSetup property.`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// This should not happen as the vitest configuration generator should create the config file
|
|
199
|
+
throw new Error(`Could not find Vitest config for project ${options.projectName} at ${options.projectRoot}`);
|
|
200
|
+
}
|
|
201
|
+
const project = (0, devkit_1.readProjectConfiguration)(host, options.projectName);
|
|
202
|
+
project.targets ??= {};
|
|
203
|
+
if (project.targets.e2e) {
|
|
204
|
+
const e2eTarget = project.targets.e2e;
|
|
205
|
+
project.targets.e2e = {
|
|
206
|
+
...e2eTarget,
|
|
207
|
+
dependsOn: [`^build`],
|
|
208
|
+
options: {
|
|
209
|
+
...e2eTarget.options,
|
|
210
|
+
pool: 'forks',
|
|
211
|
+
poolOptions: {
|
|
212
|
+
forks: {
|
|
213
|
+
singleFork: true,
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
(0, devkit_1.updateProjectConfiguration)(host, options.projectName, project);
|
|
219
|
+
}
|
|
220
|
+
return vitestTask;
|
|
221
|
+
}
|
|
115
222
|
async function addLintingToApplication(tree, options) {
|
|
116
223
|
const lintTask = await (0, eslint_1.lintProjectGenerator)(tree, {
|
|
117
224
|
linter: options.linter,
|
|
@@ -119,7 +226,7 @@ async function addLintingToApplication(tree, options) {
|
|
|
119
226
|
tsConfigPaths: [
|
|
120
227
|
(0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.app.json'),
|
|
121
228
|
],
|
|
122
|
-
unitTestRunner: 'jest',
|
|
229
|
+
unitTestRunner: options.testRunner ?? 'jest',
|
|
123
230
|
skipFormat: true,
|
|
124
231
|
setParserOptionsProject: false,
|
|
125
232
|
addPlugin: options.addPlugin,
|
|
@@ -145,11 +252,19 @@ async function e2eProjectGeneratorInternal(host, schema) {
|
|
|
145
252
|
const tasks = [];
|
|
146
253
|
validatePlugin(host, schema.pluginName);
|
|
147
254
|
const options = await normalizeOptions(host, schema);
|
|
255
|
+
// Default to jest if no testRunner is specified
|
|
256
|
+
options.testRunner = options.testRunner ?? 'jest';
|
|
148
257
|
addFiles(host, options);
|
|
149
258
|
tasks.push(await (0, js_1.setupVerdaccio)(host, {
|
|
150
259
|
skipFormat: true,
|
|
151
260
|
}));
|
|
152
|
-
|
|
261
|
+
// Add test runner based on the testRunner option
|
|
262
|
+
if (options.testRunner === 'vitest') {
|
|
263
|
+
tasks.push(await addVitest(host, options));
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
tasks.push(await addJest(host, options));
|
|
267
|
+
}
|
|
153
268
|
updatePluginPackageJson(host, options);
|
|
154
269
|
if (options.linter !== 'none') {
|
|
155
270
|
tasks.push(await addLintingToApplication(host, {
|
|
@@ -8,14 +8,14 @@ describe('<%= pluginName %>', () => {
|
|
|
8
8
|
beforeAll(() => {
|
|
9
9
|
projectDirectory = createTestProject();
|
|
10
10
|
|
|
11
|
-
// The plugin has been built and published to a local registry in the
|
|
11
|
+
// The plugin has been built and published to a local registry in the globalSetup
|
|
12
12
|
// Install the plugin built with the latest source code into the test repo
|
|
13
13
|
execSync(`<%= packageManagerCommands.addDev %> <%= pluginPackageName %>@e2e`, {
|
|
14
14
|
cwd: projectDirectory,
|
|
15
15
|
stdio: 'inherit',
|
|
16
16
|
env: process.env,
|
|
17
17
|
});
|
|
18
|
-
});
|
|
18
|
+
}, 30_000);
|
|
19
19
|
|
|
20
20
|
afterAll(() => {
|
|
21
21
|
if (projectDirectory) {
|
|
@@ -30,6 +30,12 @@
|
|
|
30
30
|
"type": "string",
|
|
31
31
|
"description": "Jest config file."
|
|
32
32
|
},
|
|
33
|
+
"testRunner": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"enum": ["jest", "vitest"],
|
|
36
|
+
"description": "Test runner to use for the e2e tests.",
|
|
37
|
+
"default": "jest"
|
|
38
|
+
},
|
|
33
39
|
"linter": {
|
|
34
40
|
"description": "The tool to use for running lint checks.",
|
|
35
41
|
"type": "string",
|
|
@@ -83,6 +83,11 @@ async function pluginGeneratorInternal(host, schema) {
|
|
|
83
83
|
'@nx/devkit': nxVersion,
|
|
84
84
|
}, {
|
|
85
85
|
[options.unitTestRunner === 'vitest' ? '@nx/vitest' : '@nx/jest']: nxVersion,
|
|
86
|
+
...(options.e2eTestRunner === 'vitest'
|
|
87
|
+
? { '@nx/vitest': nxVersion }
|
|
88
|
+
: options.e2eTestRunner === 'jest'
|
|
89
|
+
? { '@nx/jest': nxVersion }
|
|
90
|
+
: {}),
|
|
86
91
|
'@nx/js': nxVersion,
|
|
87
92
|
'@nx/plugin': nxVersion,
|
|
88
93
|
}));
|
|
@@ -103,6 +108,7 @@ async function pluginGeneratorInternal(host, schema) {
|
|
|
103
108
|
linter: options.linter,
|
|
104
109
|
useProjectJson: options.useProjectJson,
|
|
105
110
|
addPlugin: options.addPlugin,
|
|
111
|
+
testRunner: options.e2eTestRunner,
|
|
106
112
|
}));
|
|
107
113
|
}
|
|
108
114
|
if (options.linter === 'eslint' && !options.skipLintChecks) {
|
|
@@ -7,7 +7,7 @@ export interface Schema {
|
|
|
7
7
|
skipTsConfig?: boolean; // default is false
|
|
8
8
|
skipFormat?: boolean; // default is false
|
|
9
9
|
skipLintChecks?: boolean; // default is false
|
|
10
|
-
e2eTestRunner?: 'jest' | 'none';
|
|
10
|
+
e2eTestRunner?: 'jest' | 'vitest' | 'none';
|
|
11
11
|
e2eProjectDirectory?: string;
|
|
12
12
|
tags?: string;
|
|
13
13
|
unitTestRunner?: 'jest' | 'vitest' | 'none';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/plugin",
|
|
3
|
-
"version": "23.2.0-canary.
|
|
3
|
+
"version": "23.2.0-canary.20260722-6a072a2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This plugin is used to create Nx plugins! It contains generators for generating common plugin features like generators, executors, migrations and more.",
|
|
6
6
|
"repository": {
|
|
@@ -36,13 +36,21 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"tslib": "^2.3.0",
|
|
39
|
-
"@nx/devkit": "23.2.0-canary.
|
|
40
|
-
"@nx/jest": "23.2.0-canary.
|
|
41
|
-
"@nx/js": "23.2.0-canary.
|
|
42
|
-
"@nx/eslint": "23.2.0-canary.
|
|
39
|
+
"@nx/devkit": "23.2.0-canary.20260722-6a072a2",
|
|
40
|
+
"@nx/jest": "23.2.0-canary.20260722-6a072a2",
|
|
41
|
+
"@nx/js": "23.2.0-canary.20260722-6a072a2",
|
|
42
|
+
"@nx/eslint": "23.2.0-canary.20260722-6a072a2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"nx": "23.2.0-canary.
|
|
45
|
+
"nx": "23.2.0-canary.20260722-6a072a2"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@nx/vitest": "23.2.0-canary.20260722-6a072a2"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"@nx/vitest": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
46
54
|
},
|
|
47
55
|
"publishConfig": {
|
|
48
56
|
"access": "public"
|