@nx/node 0.0.0-pr-31222-862e973 → 0.0.0-pr-31313-387cdca
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/LICENSE +1 -1
- package/README.md +1 -1
- package/migrations.json +24 -38
- package/package.json +9 -8
- package/src/generators/application/application.d.ts +3 -1
- package/src/generators/application/application.js +102 -27
- package/src/generators/application/files/common/tsconfig.app.json +0 -1
- package/src/generators/application/files/common/webpack.config.js__tmpl__ +4 -4
- package/src/generators/application/schema.d.ts +5 -5
- package/src/generators/application/schema.json +27 -30
- package/src/generators/e2e-project/e2e-project.js +112 -32
- package/src/generators/e2e-project/files/cli/jest.config.ts__tmpl__ +17 -4
- package/src/generators/e2e-project/files/server/common/jest.config.ts__tmpl__ +17 -4
- package/src/generators/e2e-project/files/server/common/src/support/global-setup.ts__tmpl__ +6 -0
- package/src/generators/e2e-project/files/server/common/src/support/global-teardown.ts__tmpl__ +3 -0
- package/src/generators/e2e-project/files/server/common/src/support/test-setup.ts__tmpl__ +0 -1
- package/src/generators/e2e-project/files/ts-solution/tsconfig.json__tmpl__ +14 -0
- package/src/generators/e2e-project/schema.d.ts +1 -3
- package/src/generators/e2e-project/schema.json +4 -5
- package/src/generators/library/files/ts-solution/tsconfig.lib.json +15 -0
- package/src/generators/library/library.d.ts +1 -0
- package/src/generators/library/library.js +78 -43
- package/src/generators/library/schema.d.ts +3 -5
- package/src/generators/library/schema.json +21 -24
- package/src/utils/kill-port.d.ts +7 -0
- package/src/utils/kill-port.js +36 -0
- package/src/utils/versions.d.ts +6 -6
- package/src/utils/versions.js +6 -6
- package/src/utils/wait-for-port-open.d.ts +24 -0
- package/src/utils/wait-for-port-open.js +47 -0
- package/utils.d.ts +2 -0
- package/utils.js +7 -0
- package/src/generators/e2e-project/files/cli/tsconfig.spec.json__tmpl__ +0 -12
- package/src/generators/e2e-project/files/server/common/tsconfig.json__tmpl__ +0 -13
- package/src/generators/library/files/lib/package.json__tmpl__ +0 -4
- package/src/migrations/update-16-0-0/update-webpack-executor.d.ts +0 -2
- package/src/migrations/update-16-0-0/update-webpack-executor.js +0 -17
- package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.d.ts +0 -2
- package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.js +0 -9
- package/src/migrations/update-16-3-1/update-webpack-executor.d.ts +0 -2
- package/src/migrations/update-16-3-1/update-webpack-executor.js +0 -17
- package/src/migrations/update-16-4-0/replace-node-executor.d.ts +0 -2
- package/src/migrations/update-16-4-0/replace-node-executor.js +0 -14
- /package/src/generators/e2e-project/files/{cli → non-ts-solution}/tsconfig.json__tmpl__ +0 -0
- /package/src/generators/e2e-project/files/{server/common → non-ts-solution}/tsconfig.spec.json__tmpl__ +0 -0
- /package/src/generators/library/files/{lib → non-ts-solution}/tsconfig.lib.json +0 -0
|
@@ -11,10 +11,13 @@ const versions_1 = require("../../utils/versions");
|
|
|
11
11
|
const eslint_file_1 = require("@nx/eslint/src/generators/utils/eslint-file");
|
|
12
12
|
const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-project-command");
|
|
13
13
|
const config_file_1 = require("@nx/jest/src/utils/config/config-file");
|
|
14
|
+
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
|
|
15
|
+
const posix_1 = require("node:path/posix");
|
|
16
|
+
const add_swc_config_1 = require("@nx/js/src/utils/swc/add-swc-config");
|
|
14
17
|
async function e2eProjectGenerator(host, options) {
|
|
15
18
|
return await e2eProjectGeneratorInternal(host, {
|
|
16
19
|
addPlugin: false,
|
|
17
|
-
|
|
20
|
+
useProjectJson: true,
|
|
18
21
|
...options,
|
|
19
22
|
});
|
|
20
23
|
}
|
|
@@ -23,22 +26,51 @@ async function e2eProjectGeneratorInternal(host, _options) {
|
|
|
23
26
|
const options = await normalizeOptions(host, _options);
|
|
24
27
|
const appProject = (0, devkit_1.readProjectConfiguration)(host, options.project);
|
|
25
28
|
// TODO(@ndcunningham): This is broken.. the outputs are wrong.. and this isn't using the jest generator
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
options
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
const packageJson = {
|
|
30
|
+
name: options.importPath,
|
|
31
|
+
version: '0.0.1',
|
|
32
|
+
private: true,
|
|
33
|
+
};
|
|
34
|
+
if (!options.useProjectJson) {
|
|
35
|
+
packageJson.nx = {
|
|
36
|
+
name: options.e2eProjectName !== options.importPath
|
|
37
|
+
? options.e2eProjectName
|
|
38
|
+
: undefined,
|
|
39
|
+
implicitDependencies: [options.project],
|
|
40
|
+
targets: {
|
|
41
|
+
e2e: {
|
|
42
|
+
executor: '@nx/jest:jest',
|
|
43
|
+
outputs: ['{projectRoot}/test-output/jest/coverage'],
|
|
44
|
+
options: {
|
|
45
|
+
jestConfig: `${options.e2eProjectRoot}/jest.config.ts`,
|
|
46
|
+
passWithNoTests: true,
|
|
47
|
+
},
|
|
48
|
+
dependsOn: [`${options.project}:build`, `${options.project}:serve`],
|
|
37
49
|
},
|
|
38
|
-
dependsOn: [`${options.project}:build`],
|
|
39
50
|
},
|
|
40
|
-
}
|
|
41
|
-
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
(0, devkit_1.addProjectConfiguration)(host, options.e2eProjectName, {
|
|
55
|
+
root: options.e2eProjectRoot,
|
|
56
|
+
implicitDependencies: [options.project],
|
|
57
|
+
projectType: 'application',
|
|
58
|
+
targets: {
|
|
59
|
+
e2e: {
|
|
60
|
+
executor: '@nx/jest:jest',
|
|
61
|
+
outputs: ['{workspaceRoot}/coverage/{e2eProjectRoot}'],
|
|
62
|
+
options: {
|
|
63
|
+
jestConfig: `${options.e2eProjectRoot}/jest.config.ts`,
|
|
64
|
+
passWithNoTests: true,
|
|
65
|
+
},
|
|
66
|
+
dependsOn: [`${options.project}:build`, `${options.project}:serve`],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (!options.useProjectJson || options.isUsingTsSolutionConfig) {
|
|
72
|
+
(0, devkit_1.writeJson)(host, (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'package.json'), packageJson);
|
|
73
|
+
}
|
|
42
74
|
// TODO(@nicholas): Find a better way to get build target
|
|
43
75
|
// We remove the 'test' target from the e2e project because it is not needed
|
|
44
76
|
// The 'e2e' target is the one that should run the tests for the e2e project
|
|
@@ -65,19 +97,30 @@ async function e2eProjectGeneratorInternal(host, _options) {
|
|
|
65
97
|
});
|
|
66
98
|
}
|
|
67
99
|
const jestPreset = (0, config_file_1.findRootJestPreset)(host) ?? 'jest.preset.js';
|
|
100
|
+
const tsConfigFile = options.isUsingTsSolutionConfig
|
|
101
|
+
? 'tsconfig.json'
|
|
102
|
+
: 'tsconfig.spec.json';
|
|
103
|
+
const rootOffset = (0, devkit_1.offsetFromRoot)(options.e2eProjectRoot);
|
|
104
|
+
const coverageDirectory = options.isUsingTsSolutionConfig
|
|
105
|
+
? 'test-output/jest/coverage'
|
|
106
|
+
: (0, devkit_1.joinPathFragments)(rootOffset, 'coverage', options.e2eProjectName);
|
|
107
|
+
const projectSimpleName = options.project.split('/').pop();
|
|
68
108
|
if (options.projectType === 'server') {
|
|
69
109
|
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files/server/common'), options.e2eProjectRoot, {
|
|
70
110
|
...options,
|
|
71
|
-
...(0, devkit_1.names)(options.rootProject ? 'server' :
|
|
72
|
-
|
|
111
|
+
...(0, devkit_1.names)(options.rootProject ? 'server' : projectSimpleName),
|
|
112
|
+
tsConfigFile,
|
|
113
|
+
offsetFromRoot: rootOffset,
|
|
73
114
|
jestPreset,
|
|
115
|
+
coverageDirectory,
|
|
74
116
|
tmpl: '',
|
|
75
117
|
});
|
|
76
118
|
if (options.isNest) {
|
|
77
119
|
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files/server/nest'), options.e2eProjectRoot, {
|
|
78
120
|
...options,
|
|
79
|
-
...(0, devkit_1.names)(options.rootProject ? 'server' :
|
|
80
|
-
|
|
121
|
+
...(0, devkit_1.names)(options.rootProject ? 'server' : projectSimpleName),
|
|
122
|
+
tsConfigFile,
|
|
123
|
+
offsetFromRoot: rootOffset,
|
|
81
124
|
tmpl: '',
|
|
82
125
|
});
|
|
83
126
|
}
|
|
@@ -86,20 +129,38 @@ async function e2eProjectGeneratorInternal(host, _options) {
|
|
|
86
129
|
const mainFile = appProject.targets.build?.options?.outputPath;
|
|
87
130
|
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files/cli'), options.e2eProjectRoot, {
|
|
88
131
|
...options,
|
|
89
|
-
...(0, devkit_1.names)(options.rootProject ? 'cli' :
|
|
132
|
+
...(0, devkit_1.names)(options.rootProject ? 'cli' : projectSimpleName),
|
|
90
133
|
mainFile,
|
|
91
|
-
|
|
134
|
+
tsConfigFile,
|
|
135
|
+
offsetFromRoot: rootOffset,
|
|
92
136
|
jestPreset,
|
|
137
|
+
coverageDirectory,
|
|
138
|
+
tmpl: '',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (options.isUsingTsSolutionConfig) {
|
|
142
|
+
(0, add_swc_config_1.addSwcTestConfig)(host, options.e2eProjectRoot, 'es6');
|
|
143
|
+
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files/ts-solution'), options.e2eProjectRoot, {
|
|
144
|
+
...options,
|
|
145
|
+
relativeProjectReferencePath: (0, posix_1.relative)(options.e2eProjectRoot, appProject.root),
|
|
146
|
+
offsetFromRoot: rootOffset,
|
|
147
|
+
tmpl: '',
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
(0, devkit_1.generateFiles)(host, path.join(__dirname, 'files/non-ts-solution'), options.e2eProjectRoot, {
|
|
152
|
+
...options,
|
|
153
|
+
offsetFromRoot: rootOffset,
|
|
93
154
|
tmpl: '',
|
|
94
155
|
});
|
|
95
156
|
}
|
|
96
157
|
// axios is more than likely used in the application code, so install it as a regular dependency.
|
|
97
158
|
const installTask = (0, devkit_1.addDependenciesToPackageJson)(host, { axios: versions_1.axiosVersion }, {});
|
|
98
159
|
tasks.push(installTask);
|
|
99
|
-
if (options.linter ===
|
|
160
|
+
if (options.linter === 'eslint') {
|
|
100
161
|
const linterTask = await (0, eslint_1.lintProjectGenerator)(host, {
|
|
101
162
|
project: options.e2eProjectName,
|
|
102
|
-
linter:
|
|
163
|
+
linter: 'eslint',
|
|
103
164
|
skipFormat: true,
|
|
104
165
|
tsConfigPaths: [
|
|
105
166
|
(0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'tsconfig.json'),
|
|
@@ -118,6 +179,21 @@ async function e2eProjectGeneratorInternal(host, _options) {
|
|
|
118
179
|
]);
|
|
119
180
|
}
|
|
120
181
|
}
|
|
182
|
+
if (options.isUsingTsSolutionConfig) {
|
|
183
|
+
(0, devkit_1.updateJson)(host, 'tsconfig.json', (json) => {
|
|
184
|
+
json.references ??= [];
|
|
185
|
+
const e2eRef = `./${options.e2eProjectRoot}`;
|
|
186
|
+
if (!json.references.find((ref) => ref.path === e2eRef)) {
|
|
187
|
+
json.references.push({ path: e2eRef });
|
|
188
|
+
}
|
|
189
|
+
return json;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// If we are using the new TS solution
|
|
193
|
+
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
|
194
|
+
if (options.isUsingTsSolutionConfig) {
|
|
195
|
+
await (0, ts_solution_setup_1.addProjectToTsSolutionWorkspace)(host, options.e2eProjectRoot);
|
|
196
|
+
}
|
|
121
197
|
if (!options.skipFormat) {
|
|
122
198
|
await (0, devkit_1.formatFiles)(host);
|
|
123
199
|
}
|
|
@@ -127,26 +203,30 @@ async function e2eProjectGeneratorInternal(host, _options) {
|
|
|
127
203
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
128
204
|
}
|
|
129
205
|
async function normalizeOptions(tree, options) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
directory
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
206
|
+
let directory = options.rootProject ? 'e2e' : options.directory;
|
|
207
|
+
if (!directory) {
|
|
208
|
+
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
209
|
+
directory = `${projectConfig.root}-e2e`;
|
|
210
|
+
}
|
|
211
|
+
const { projectName: e2eProjectName, projectRoot: e2eProjectRoot, importPath, } = await (0, project_name_and_root_utils_1.determineProjectNameAndRootOptions)(tree, {
|
|
212
|
+
name: options.name,
|
|
213
|
+
projectType: 'application',
|
|
214
|
+
directory,
|
|
139
215
|
});
|
|
140
216
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
141
217
|
const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
142
218
|
nxJson.useInferencePlugins !== false;
|
|
219
|
+
const isUsingTsSolutionConfig = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
|
|
143
220
|
return {
|
|
144
221
|
addPlugin,
|
|
145
222
|
...options,
|
|
146
223
|
e2eProjectRoot,
|
|
147
224
|
e2eProjectName,
|
|
225
|
+
importPath,
|
|
148
226
|
port: options.port ?? 3000,
|
|
149
227
|
rootProject: !!options.rootProject,
|
|
228
|
+
isUsingTsSolutionConfig,
|
|
229
|
+
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionConfig,
|
|
150
230
|
};
|
|
151
231
|
}
|
|
152
232
|
exports.default = e2eProjectGenerator;
|
|
@@ -1,13 +1,26 @@
|
|
|
1
|
+
<%_ if (isUsingTsSolutionConfig) { _%>
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
|
|
5
|
+
// Reading the SWC compilation config for the spec files
|
|
6
|
+
const swcJestConfig = JSON.parse(
|
|
7
|
+
readFileSync(`${__dirname}/.spec.swcrc`, 'utf-8')
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
// Disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves
|
|
11
|
+
swcJestConfig.swcrc = false;
|
|
12
|
+
|
|
13
|
+
<%_ } _%>
|
|
1
14
|
export default {
|
|
2
15
|
displayName: '<%= e2eProjectName %>',
|
|
3
16
|
preset: '<%= offsetFromRoot %><%= jestPreset %>',
|
|
4
17
|
setupFiles: ['<rootDir>/src/test-setup.ts'],
|
|
5
18
|
testEnvironment: 'node',
|
|
6
19
|
transform: {
|
|
7
|
-
'^.+\\.[tj]s$': ['ts-jest', {
|
|
8
|
-
tsconfig: '<rootDir
|
|
9
|
-
}]
|
|
20
|
+
'^.+\\.[tj]s$': <% if (isUsingTsSolutionConfig) { %>['@swc/jest', swcJestConfig]<% } else { %>['ts-jest', {
|
|
21
|
+
tsconfig: '<rootDir>/<%= tsConfigFile %>',
|
|
22
|
+
}]<% } %>,
|
|
10
23
|
},
|
|
11
24
|
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
12
|
-
coverageDirectory: '<%=
|
|
25
|
+
coverageDirectory: '<%= coverageDirectory %>',
|
|
13
26
|
};
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
<%_ if (isUsingTsSolutionConfig) { _%>
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
|
|
5
|
+
// Reading the SWC compilation config for the spec files
|
|
6
|
+
const swcJestConfig = JSON.parse(
|
|
7
|
+
readFileSync(`${__dirname}/.spec.swcrc`, 'utf-8')
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
// Disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves
|
|
11
|
+
swcJestConfig.swcrc = false;
|
|
12
|
+
|
|
13
|
+
<%_ } _%>
|
|
1
14
|
export default {
|
|
2
15
|
displayName: '<%= e2eProjectName %>',
|
|
3
16
|
preset: '<%= offsetFromRoot %><%= jestPreset %>',
|
|
@@ -6,10 +19,10 @@ export default {
|
|
|
6
19
|
setupFiles: ['<rootDir>/src/support/test-setup.ts'],
|
|
7
20
|
testEnvironment: 'node',
|
|
8
21
|
transform: {
|
|
9
|
-
'^.+\\.[tj]s$': ['ts-jest', {
|
|
10
|
-
tsconfig: '<rootDir
|
|
11
|
-
}]
|
|
22
|
+
'^.+\\.[tj]s$': <% if (isUsingTsSolutionConfig) { %>['@swc/jest', swcJestConfig]<% } else { %>['ts-jest', {
|
|
23
|
+
tsconfig: '<rootDir>/<%= tsConfigFile %>',
|
|
24
|
+
}]<% } %>,
|
|
12
25
|
},
|
|
13
26
|
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
14
|
-
coverageDirectory: '<%=
|
|
27
|
+
coverageDirectory: '<%= coverageDirectory %>',
|
|
15
28
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { waitForPortOpen } from '@nx/node/utils';
|
|
2
|
+
|
|
1
3
|
/* eslint-disable */
|
|
2
4
|
var __TEARDOWN_MESSAGE__: string;
|
|
3
5
|
|
|
@@ -5,6 +7,10 @@ module.exports = async function() {
|
|
|
5
7
|
// Start services that that the app needs to run (e.g. database, docker-compose, etc.).
|
|
6
8
|
console.log('\nSetting up...\n');
|
|
7
9
|
|
|
10
|
+
const host = process.env.HOST ?? 'localhost';
|
|
11
|
+
const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>;
|
|
12
|
+
await waitForPortOpen(port, { host });
|
|
13
|
+
|
|
8
14
|
// Hint: Use `globalThis` to pass variables to global teardown.
|
|
9
15
|
globalThis.__TEARDOWN_MESSAGE__ = '\nTearing down...\n';
|
|
10
16
|
};
|
package/src/generators/e2e-project/files/server/common/src/support/global-teardown.ts__tmpl__
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { killPort } from '@nx/node/utils';
|
|
1
2
|
/* eslint-disable */
|
|
2
3
|
|
|
3
4
|
module.exports = async function() {
|
|
4
5
|
// Put clean up logic here (e.g. stopping services, docker-compose, etc.).
|
|
5
6
|
// Hint: `globalThis` is shared between setup and teardown.
|
|
7
|
+
const port = process.env.PORT ? Number(process.env.PORT) : <%= port %>;
|
|
8
|
+
await killPort(port);
|
|
6
9
|
console.log(globalThis.__TEARDOWN_MESSAGE__);
|
|
7
10
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "<%= offsetFromRoot %>tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "out-tsc/<%= e2eProjectName %>",
|
|
5
|
+
"esModuleInterop": true,
|
|
6
|
+
"noUnusedLocals": false,
|
|
7
|
+
"noImplicitAny": false
|
|
8
|
+
},
|
|
9
|
+
"include": [
|
|
10
|
+
"jest.config.ts",
|
|
11
|
+
"src/**/*.ts"
|
|
12
|
+
],
|
|
13
|
+
"references": []
|
|
14
|
+
}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
|
2
|
-
|
|
3
1
|
export interface Schema {
|
|
4
2
|
project: string;
|
|
5
3
|
projectType: 'server' | 'cli';
|
|
6
4
|
directory?: string;
|
|
7
|
-
projectNameAndRootFormat?: ProjectNameAndRootFormat;
|
|
8
5
|
name?: string;
|
|
9
6
|
port?: number;
|
|
10
7
|
linter?: 'eslint' | 'none';
|
|
@@ -12,4 +9,5 @@ export interface Schema {
|
|
|
12
9
|
isNest?: boolean;
|
|
13
10
|
skipFormat?: boolean;
|
|
14
11
|
addPlugin?: boolean;
|
|
12
|
+
useProjectJson?: boolean;
|
|
15
13
|
}
|
|
@@ -18,11 +18,6 @@
|
|
|
18
18
|
"type": "string",
|
|
19
19
|
"x-priority": "important"
|
|
20
20
|
},
|
|
21
|
-
"projectNameAndRootFormat": {
|
|
22
|
-
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
|
|
23
|
-
"type": "string",
|
|
24
|
-
"enum": ["as-provided", "derived"]
|
|
25
|
-
},
|
|
26
21
|
"name": {
|
|
27
22
|
"description": "The name of the e2e project. Defaults to the project name with '-e2e' suffix.",
|
|
28
23
|
"type": "string"
|
|
@@ -64,6 +59,10 @@
|
|
|
64
59
|
"default": false,
|
|
65
60
|
"hidden": true,
|
|
66
61
|
"x-priority": "internal"
|
|
62
|
+
},
|
|
63
|
+
"useProjectJson": {
|
|
64
|
+
"type": "boolean",
|
|
65
|
+
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
|
67
66
|
}
|
|
68
67
|
},
|
|
69
68
|
"required": ["project"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"baseUrl": ".",
|
|
5
|
+
"rootDir": "src",
|
|
6
|
+
"module": "nodenext",
|
|
7
|
+
"moduleResolution": "nodenext",
|
|
8
|
+
"outDir": "dist",
|
|
9
|
+
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
|
|
10
|
+
"emitDeclarationOnly": false,
|
|
11
|
+
"types": ["node"]
|
|
12
|
+
},
|
|
13
|
+
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
|
|
14
|
+
"include": ["src/**/*.ts"]
|
|
15
|
+
}
|
|
@@ -6,6 +6,7 @@ export interface NormalizedSchema extends Schema {
|
|
|
6
6
|
projectRoot: string;
|
|
7
7
|
parsedTags: string[];
|
|
8
8
|
compiler: 'swc' | 'tsc';
|
|
9
|
+
isUsingTsSolutionConfig: boolean;
|
|
9
10
|
}
|
|
10
11
|
export declare function libraryGenerator(tree: Tree, schema: Schema): Promise<GeneratorCallback>;
|
|
11
12
|
export declare function libraryGeneratorInternal(tree: Tree, schema: Schema): Promise<GeneratorCallback>;
|
|
@@ -11,40 +11,63 @@ const path_1 = require("path");
|
|
|
11
11
|
const versions_1 = require("../../utils/versions");
|
|
12
12
|
const init_1 = require("../init/init");
|
|
13
13
|
const target_defaults_utils_1 = require("@nx/devkit/src/generators/target-defaults-utils");
|
|
14
|
+
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
|
|
15
|
+
const sort_fields_1 = require("@nx/js/src/utils/package-json/sort-fields");
|
|
14
16
|
async function libraryGenerator(tree, schema) {
|
|
15
17
|
return await libraryGeneratorInternal(tree, {
|
|
16
18
|
addPlugin: false,
|
|
17
|
-
|
|
19
|
+
useProjectJson: true,
|
|
18
20
|
...schema,
|
|
19
21
|
});
|
|
20
22
|
}
|
|
21
23
|
async function libraryGeneratorInternal(tree, schema) {
|
|
22
24
|
const options = await normalizeOptions(tree, schema);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
];
|
|
25
|
+
// If we are using the new TS solution
|
|
26
|
+
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
|
27
|
+
if (options.isUsingTsSolutionConfig) {
|
|
28
|
+
await (0, ts_solution_setup_1.addProjectToTsSolutionWorkspace)(tree, options.projectRoot);
|
|
29
|
+
}
|
|
30
|
+
const tasks = [];
|
|
29
31
|
if (options.publishable === true && !schema.importPath) {
|
|
30
32
|
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)`);
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
// Create `package.json` first because @nx/js:lib generator will update it.
|
|
35
|
+
if (!options.useProjectJson ||
|
|
36
|
+
options.isUsingTsSolutionConfig ||
|
|
37
|
+
options.publishable ||
|
|
38
|
+
options.buildable) {
|
|
39
|
+
(0, devkit_1.writeJson)(tree, (0, devkit_1.joinPathFragments)(options.projectRoot, 'package.json'), {
|
|
40
|
+
name: options.importPath,
|
|
41
|
+
version: '0.0.1',
|
|
42
|
+
private: true,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
tasks.push(await (0, js_1.libraryGenerator)(tree, {
|
|
46
|
+
...schema,
|
|
47
|
+
bundler: schema.buildable || schema.publishable ? 'tsc' : 'none',
|
|
35
48
|
includeBabelRc: schema.babelJest,
|
|
36
|
-
importPath:
|
|
49
|
+
importPath: schema.importPath,
|
|
37
50
|
testEnvironment: 'node',
|
|
38
51
|
skipFormat: true,
|
|
39
|
-
setParserOptionsProject:
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
setParserOptionsProject: schema.setParserOptionsProject,
|
|
53
|
+
useProjectJson: options.useProjectJson,
|
|
54
|
+
}));
|
|
55
|
+
updatePackageJson(tree, options);
|
|
56
|
+
tasks.push(await (0, init_1.initGenerator)(tree, {
|
|
57
|
+
...options,
|
|
58
|
+
skipFormat: true,
|
|
59
|
+
}));
|
|
42
60
|
createFiles(tree, options);
|
|
43
61
|
if (options.js) {
|
|
44
62
|
(0, devkit_1.updateTsConfigsToJs)(tree, options);
|
|
45
63
|
}
|
|
46
64
|
updateProject(tree, options);
|
|
47
65
|
tasks.push(ensureDependencies(tree));
|
|
66
|
+
// Always run install to link packages.
|
|
67
|
+
if (options.isUsingTsSolutionConfig) {
|
|
68
|
+
tasks.push(() => (0, devkit_1.installPackagesTask)(tree, true));
|
|
69
|
+
}
|
|
70
|
+
(0, sort_fields_1.sortPackageJsonFields)(tree, options.projectRoot);
|
|
48
71
|
if (!schema.skipFormat) {
|
|
49
72
|
await (0, devkit_1.formatFiles)(tree);
|
|
50
73
|
}
|
|
@@ -52,41 +75,35 @@ async function libraryGeneratorInternal(tree, schema) {
|
|
|
52
75
|
}
|
|
53
76
|
exports.default = libraryGenerator;
|
|
54
77
|
async function normalizeOptions(tree, options) {
|
|
55
|
-
|
|
78
|
+
await (0, project_name_and_root_utils_1.ensureRootProjectName)(options, 'library');
|
|
79
|
+
const { projectName, names: projectNames, projectRoot, importPath, } = await (0, project_name_and_root_utils_1.determineProjectNameAndRootOptions)(tree, {
|
|
56
80
|
name: options.name,
|
|
57
81
|
projectType: 'library',
|
|
58
82
|
directory: options.directory,
|
|
59
83
|
importPath: options.importPath,
|
|
60
|
-
projectNameAndRootFormat: options.projectNameAndRootFormat,
|
|
61
|
-
callingGenerator: '@nx/node:library',
|
|
62
84
|
});
|
|
63
|
-
options.projectNameAndRootFormat = projectNameAndRootFormat;
|
|
64
85
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
65
86
|
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
66
87
|
nxJson.useInferencePlugins !== false;
|
|
67
88
|
options.addPlugin ??= addPluginDefault;
|
|
68
|
-
const fileName =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
: projectNames.projectFileName,
|
|
72
|
-
pascalCaseFiles: options.pascalCaseFiles,
|
|
73
|
-
});
|
|
89
|
+
const fileName = (0, devkit_1.names)(options.simpleModuleName
|
|
90
|
+
? projectNames.projectSimpleName
|
|
91
|
+
: projectNames.projectFileName).fileName;
|
|
74
92
|
const parsedTags = options.tags
|
|
75
93
|
? options.tags.split(',').map((s) => s.trim())
|
|
76
94
|
: [];
|
|
95
|
+
const isUsingTsSolutionConfig = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(tree);
|
|
77
96
|
return {
|
|
78
97
|
...options,
|
|
79
98
|
fileName,
|
|
80
|
-
projectName,
|
|
99
|
+
projectName: isUsingTsSolutionConfig && !options.name ? importPath : projectName,
|
|
81
100
|
projectRoot,
|
|
82
101
|
parsedTags,
|
|
83
102
|
importPath,
|
|
103
|
+
isUsingTsSolutionConfig,
|
|
104
|
+
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionConfig,
|
|
84
105
|
};
|
|
85
106
|
}
|
|
86
|
-
function getCaseAwareFileName(options) {
|
|
87
|
-
const normalized = (0, devkit_1.names)(options.fileName);
|
|
88
|
-
return options.pascalCaseFiles ? normalized.className : normalized.fileName;
|
|
89
|
-
}
|
|
90
107
|
function createFiles(tree, options) {
|
|
91
108
|
const { className, name, propertyName } = (0, devkit_1.names)(options.fileName);
|
|
92
109
|
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, './files/lib'), options.projectRoot, {
|
|
@@ -100,9 +117,6 @@ function createFiles(tree, options) {
|
|
|
100
117
|
if (options.unitTestRunner === 'none') {
|
|
101
118
|
tree.delete((0, path_1.join)(options.projectRoot, `./src/lib/${options.fileName}.spec.ts`));
|
|
102
119
|
}
|
|
103
|
-
if (!options.publishable && !options.buildable) {
|
|
104
|
-
tree.delete((0, path_1.join)(options.projectRoot, 'package.json'));
|
|
105
|
-
}
|
|
106
120
|
if (options.js) {
|
|
107
121
|
(0, devkit_1.toJS)(tree);
|
|
108
122
|
}
|
|
@@ -115,17 +129,25 @@ function updateProject(tree, options) {
|
|
|
115
129
|
const rootProject = options.projectRoot === '.' || options.projectRoot === '';
|
|
116
130
|
project.targets = project.targets || {};
|
|
117
131
|
(0, target_defaults_utils_1.addBuildTargetDefaults)(tree, `@nx/js:${options.compiler}`);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
// For TS solution, we want tsc build to be inferred by `@nx/js/typescript` plugin.
|
|
133
|
+
if (!options.isUsingTsSolutionConfig || options.compiler === 'swc') {
|
|
134
|
+
project.targets.build = {
|
|
135
|
+
executor: `@nx/js:${options.compiler}`,
|
|
136
|
+
outputs: ['{options.outputPath}'],
|
|
137
|
+
options: {
|
|
138
|
+
outputPath: options.isUsingTsSolutionConfig
|
|
139
|
+
? (0, devkit_1.joinPathFragments)(options.projectRoot, 'dist')
|
|
140
|
+
: (0, devkit_1.joinPathFragments)('dist', rootProject ? options.projectName : options.projectRoot),
|
|
141
|
+
tsConfig: `${options.projectRoot}/tsconfig.lib.json`,
|
|
142
|
+
packageJson: `${options.projectRoot}/package.json`,
|
|
143
|
+
main: `${options.projectRoot}/src/index` + (options.js ? '.js' : '.ts'),
|
|
144
|
+
assets: options.isUsingTsSolutionConfig
|
|
145
|
+
? undefined
|
|
146
|
+
: [`${options.projectRoot}/*.md`],
|
|
147
|
+
stripLeadingPaths: options.isUsingTsSolutionConfig ? true : undefined,
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
129
151
|
if (options.compiler === 'swc') {
|
|
130
152
|
(0, add_swc_dependencies_1.addSwcDependencies)(tree);
|
|
131
153
|
(0, add_swc_config_1.addSwcConfig)(tree, options.projectRoot);
|
|
@@ -138,3 +160,16 @@ function updateProject(tree, options) {
|
|
|
138
160
|
function ensureDependencies(tree) {
|
|
139
161
|
return (0, devkit_1.addDependenciesToPackageJson)(tree, { tslib: versions_1.tslibVersion }, { '@types/node': versions_1.typesNodeVersion });
|
|
140
162
|
}
|
|
163
|
+
function updatePackageJson(tree, options) {
|
|
164
|
+
const packageJsonPath = (0, devkit_1.joinPathFragments)(options.projectRoot, 'package.json');
|
|
165
|
+
if (!tree.exists(packageJsonPath)) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const packageJson = (0, devkit_1.readJson)(tree, packageJsonPath);
|
|
169
|
+
if (packageJson.type === 'module') {
|
|
170
|
+
// The @nx/js:lib generator can set the type to 'module' which would
|
|
171
|
+
// potentially break consumers of the library.
|
|
172
|
+
delete packageJson.type;
|
|
173
|
+
}
|
|
174
|
+
(0, devkit_1.writeJson)(tree, packageJsonPath, packageJson);
|
|
175
|
+
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
|
2
1
|
import type { Linter, LinterType } from '@nx/eslint';
|
|
3
2
|
|
|
4
3
|
export interface Schema {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
projectNameAndRootFormat?: ProjectNameAndRootFormat;
|
|
4
|
+
directory: string;
|
|
5
|
+
name?: string;
|
|
8
6
|
simpleModuleName?: boolean;
|
|
9
7
|
skipTsConfig?: boolean;
|
|
10
8
|
skipFormat?: boolean;
|
|
@@ -18,10 +16,10 @@ export interface Schema {
|
|
|
18
16
|
rootDir?: string;
|
|
19
17
|
babelJest?: boolean;
|
|
20
18
|
js?: boolean;
|
|
21
|
-
pascalCaseFiles?: boolean;
|
|
22
19
|
strict?: boolean;
|
|
23
20
|
standaloneConfig?: boolean;
|
|
24
21
|
setParserOptionsProject?: boolean;
|
|
25
22
|
compiler: 'tsc' | 'swc';
|
|
26
23
|
addPlugin?: boolean;
|
|
24
|
+
useProjectJson?: boolean;
|
|
27
25
|
}
|