@nx/web 17.0.3 → 17.0.5
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 +9 -4
- package/migrations.json +11 -1
- package/package.json +4 -4
- package/src/executors/file-server/file-server.impl.js +67 -30
- package/src/executors/file-server/schema.d.ts +4 -4
- package/src/executors/file-server/schema.json +2 -3
- package/src/generators/application/application.js +128 -46
- package/src/generators/application/files/app-vite/src/app/app.element.__style__ +9 -1
- package/src/generators/application/files/app-vite/src/app/app.element.ts__tmpl__ +39 -5
- package/src/generators/application/files/app-webpack/src/app/app.element.__style__ +9 -1
- package/src/generators/application/files/app-webpack/src/app/app.element.ts__tmpl__ +39 -5
- package/src/generators/application/files/app-webpack/webpack.config.js__tmpl__ +36 -5
- package/src/generators/application/schema.d.ts +1 -0
- package/src/generators/application/schema.json +3 -3
- package/src/generators/init/init.js +7 -40
- package/src/generators/init/schema.d.ts +1 -3
- package/src/generators/init/schema.json +7 -20
- package/src/generators/static-serve/schema.json +6 -1
- package/src/generators/static-serve/static-serve-configuration.d.ts +3 -2
- package/src/generators/static-serve/static-serve-configuration.js +14 -5
- package/src/migrations/update-15-9-1/add-dropped-dependencies.js +2 -2
- package/src/utils/has-webpack-plugin.d.ts +2 -0
- package/src/utils/has-webpack-plugin.js +11 -0
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js +1 -1
- package/src/utils/wait-for-port-open.js +10 -2
- package/src/generators/application/files/app-webpack/src/environments/environment.prod.ts__tmpl__ +0 -3
- package/src/generators/application/files/app-webpack/src/environments/environment.ts__tmpl__ +0 -6
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
<p style="text-align: center;"
|
|
1
|
+
<p style="text-align: center;">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
|
|
4
|
+
<img alt="Nx - Smart Monorepos · Fast CI" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
2
7
|
|
|
3
8
|
<div style="text-align: center;">
|
|
4
9
|
|
|
@@ -15,9 +20,9 @@
|
|
|
15
20
|
|
|
16
21
|
<hr>
|
|
17
22
|
|
|
18
|
-
# Nx: Smart
|
|
23
|
+
# Nx: Smart Monorepos · Fast CI
|
|
19
24
|
|
|
20
|
-
Nx is a
|
|
25
|
+
Nx is a build system with built-in tooling and advanced CI capabilities. It helps you maintain and scale monorepos, both locally and on CI.
|
|
21
26
|
|
|
22
27
|
This package is a [Web plugin for Nx](https://nx.dev/packages/web).
|
|
23
28
|
|
|
@@ -59,5 +64,5 @@ npx nx@latest init
|
|
|
59
64
|
- [Blog Posts About Nx](https://blog.nrwl.io/nx/home)
|
|
60
65
|
|
|
61
66
|
<p style="text-align: center;"><a href="https://nx.dev/#learning-materials" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-courses-and-videos.svg"
|
|
62
|
-
width="100%" alt="Nx - Smart
|
|
67
|
+
width="100%" alt="Nx - Smart Monorepos · Fast CI"></a></p>
|
|
63
68
|
|
package/migrations.json
CHANGED
|
@@ -37,5 +37,15 @@
|
|
|
37
37
|
"implementation": "./src/migrations/update-16-0-0-update-executors/update-16-0-0-update-executors"
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
|
-
"packageJsonUpdates": {
|
|
40
|
+
"packageJsonUpdates": {
|
|
41
|
+
"17.3.0": {
|
|
42
|
+
"version": "17.3.0-beta.3",
|
|
43
|
+
"packages": {
|
|
44
|
+
"@types/node": {
|
|
45
|
+
"version": "18.16.9",
|
|
46
|
+
"alwaysAddToPackageJson": false
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
41
51
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/web",
|
|
3
|
-
"version": "17.0.
|
|
3
|
+
"version": "17.0.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Nx Plugin for Web Components contains generators for managing Web Component applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Scaffolding for creating buildable libraries that can be published to npm.\n\n- Utilities for automatic workspace refactoring.",
|
|
6
6
|
"repository": {
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"detect-port": "^1.5.1",
|
|
35
35
|
"http-server": "^14.1.0",
|
|
36
36
|
"tslib": "^2.3.0",
|
|
37
|
-
"@nx/devkit": "17.0.
|
|
38
|
-
"@nx/js": "17.0.
|
|
39
|
-
"@nrwl/web": "17.0.
|
|
37
|
+
"@nx/devkit": "17.0.5",
|
|
38
|
+
"@nx/js": "17.0.5",
|
|
39
|
+
"@nrwl/web": "17.0.5"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
@@ -9,6 +9,7 @@ const path_1 = require("path");
|
|
|
9
9
|
const package_json_1 = require("nx/src/utils/package-json");
|
|
10
10
|
const detectPort = require("detect-port");
|
|
11
11
|
const client_1 = require("nx/src/daemon/client/client");
|
|
12
|
+
const utils_1 = require("nx/src/tasks-runner/utils");
|
|
12
13
|
// platform specific command name
|
|
13
14
|
const pmCmd = (0, os_1.platform)() === 'win32' ? `npx.cmd` : 'npx';
|
|
14
15
|
function getHttpServerArgs(options) {
|
|
@@ -44,8 +45,15 @@ function getHttpServerArgs(options) {
|
|
|
44
45
|
}
|
|
45
46
|
return args;
|
|
46
47
|
}
|
|
47
|
-
function getBuildTargetCommand(options) {
|
|
48
|
-
const
|
|
48
|
+
function getBuildTargetCommand(options, context) {
|
|
49
|
+
const target = (0, devkit_1.parseTargetString)(options.buildTarget, context);
|
|
50
|
+
const cmd = ['nx', 'run'];
|
|
51
|
+
if (target.configuration) {
|
|
52
|
+
cmd.push(`${target.project}:${target.target}:${target.configuration}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
cmd.push(`${target.project}:${target.target}`);
|
|
56
|
+
}
|
|
49
57
|
if (options.parallel) {
|
|
50
58
|
cmd.push(`--parallel`);
|
|
51
59
|
}
|
|
@@ -58,16 +66,27 @@ function getBuildTargetOutputPath(options, context) {
|
|
|
58
66
|
if (options.staticFilePath) {
|
|
59
67
|
return options.staticFilePath;
|
|
60
68
|
}
|
|
61
|
-
let
|
|
69
|
+
let outputPath;
|
|
62
70
|
try {
|
|
63
71
|
const target = (0, devkit_1.parseTargetString)(options.buildTarget, context);
|
|
64
|
-
buildOptions = (0, devkit_1.readTargetOptions)(target, context);
|
|
72
|
+
const buildOptions = (0, devkit_1.readTargetOptions)(target, context);
|
|
73
|
+
if (buildOptions?.outputPath) {
|
|
74
|
+
outputPath = buildOptions.outputPath;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const project = context.projectGraph.nodes[context.projectName];
|
|
78
|
+
const buildTarget = project.data.targets[target.target];
|
|
79
|
+
outputPath = buildTarget.outputs?.[0];
|
|
80
|
+
if (outputPath)
|
|
81
|
+
outputPath = (0, utils_1.interpolate)(outputPath, {
|
|
82
|
+
projectName: project.data.name,
|
|
83
|
+
projectRoot: project.data.root,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
65
86
|
}
|
|
66
87
|
catch (e) {
|
|
67
88
|
throw new Error(`Invalid buildTarget: ${options.buildTarget}`);
|
|
68
89
|
}
|
|
69
|
-
// TODO: vsavkin we should also check outputs
|
|
70
|
-
const outputPath = buildOptions.outputPath;
|
|
71
90
|
if (!outputPath) {
|
|
72
91
|
throw new Error(`Unable to get the outputPath from buildTarget ${options.buildTarget}. Make sure ${options.buildTarget} has an outputPath property or manually provide an staticFilePath property`);
|
|
73
92
|
}
|
|
@@ -78,50 +97,69 @@ function createFileWatcher(project, changeHandler) {
|
|
|
78
97
|
watchProjects: project ? [project] : 'all',
|
|
79
98
|
includeGlobalWorkspaceFiles: true,
|
|
80
99
|
includeDependentProjects: true,
|
|
81
|
-
}, async (error,
|
|
100
|
+
}, async (error, val) => {
|
|
82
101
|
if (error === 'closed') {
|
|
83
102
|
throw new Error('Watch error: Daemon closed the connection');
|
|
84
103
|
}
|
|
85
104
|
else if (error) {
|
|
86
105
|
throw new Error(`Watch error: ${error?.message ?? 'Unknown'}`);
|
|
87
106
|
}
|
|
88
|
-
else if (changedFiles.length > 0) {
|
|
107
|
+
else if (val?.changedFiles.length > 0) {
|
|
89
108
|
changeHandler();
|
|
90
109
|
}
|
|
91
110
|
});
|
|
92
111
|
}
|
|
93
112
|
async function* fileServerExecutor(options, context) {
|
|
113
|
+
if (!options.buildTarget && !options.staticFilePath) {
|
|
114
|
+
throw new Error("You must set either 'buildTarget' or 'staticFilePath'.");
|
|
115
|
+
}
|
|
116
|
+
if (options.watch && !options.buildTarget) {
|
|
117
|
+
throw new Error("Watch error: You can only specify 'watch' when 'buildTarget' is set.");
|
|
118
|
+
}
|
|
94
119
|
let running = false;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
120
|
+
let disposeWatch;
|
|
121
|
+
if (options.buildTarget) {
|
|
122
|
+
const run = () => {
|
|
123
|
+
if (!running) {
|
|
124
|
+
running = true;
|
|
125
|
+
/**
|
|
126
|
+
* Expose a variable to the build target to know if it's being run by the serve-static executor
|
|
127
|
+
* This is useful because a config might need to change if it's being run by serve-static without the user's input
|
|
128
|
+
* or if being ran by another executor (eg. E2E tests)
|
|
129
|
+
* */
|
|
130
|
+
process.env.NX_SERVE_STATIC_BUILD_RUNNING = 'true';
|
|
131
|
+
try {
|
|
132
|
+
const args = getBuildTargetCommand(options, context);
|
|
133
|
+
(0, child_process_1.execFileSync)(pmCmd, args, {
|
|
134
|
+
stdio: [0, 1, 2],
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
throw new Error(`Build target failed: ${chalk.bold(options.buildTarget)}`);
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
process.env.NX_SERVE_STATIC_BUILD_RUNNING = undefined;
|
|
142
|
+
running = false;
|
|
143
|
+
}
|
|
109
144
|
}
|
|
145
|
+
};
|
|
146
|
+
if (options.watch) {
|
|
147
|
+
const projectRoot = context.projectsConfigurations.projects[context.projectName].root;
|
|
148
|
+
disposeWatch = await createFileWatcher(context.projectName, run);
|
|
110
149
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (options.watch) {
|
|
114
|
-
const projectRoot = context.projectsConfigurations.projects[context.projectName].root;
|
|
115
|
-
disposeWatch = await createFileWatcher(context.projectName, run);
|
|
150
|
+
// perform initial run
|
|
151
|
+
run();
|
|
116
152
|
}
|
|
117
|
-
|
|
118
|
-
run();
|
|
153
|
+
const port = await detectPort(options.port || 8080);
|
|
119
154
|
const outputPath = getBuildTargetOutputPath(options, context);
|
|
120
155
|
if (options.spa) {
|
|
121
156
|
const src = (0, path_1.join)(outputPath, 'index.html');
|
|
122
157
|
const dst = (0, path_1.join)(outputPath, '404.html');
|
|
123
158
|
// See: https://github.com/http-party/http-server#magic-files
|
|
124
159
|
(0, fs_1.copyFileSync)(src, dst);
|
|
160
|
+
// We also need to ensure the proxyUrl is set, otherwise the browser will continue to throw a 404 error
|
|
161
|
+
// This can cause unexpected behaviors and failures especially in automated test suites
|
|
162
|
+
options.proxyUrl ??= `http${options.ssl ? 's' : ''}://localhost:${port}?`;
|
|
125
163
|
}
|
|
126
164
|
const args = getHttpServerArgs(options);
|
|
127
165
|
const { path: pathToHttpServerPkgJson, packageJson } = (0, package_json_1.readModulePackageJson)('http-server', module.paths);
|
|
@@ -129,7 +167,6 @@ async function* fileServerExecutor(options, context) {
|
|
|
129
167
|
const pathToHttpServer = (0, path_1.resolve)(pathToHttpServerPkgJson.replace('package.json', ''), pathToHttpServerBin);
|
|
130
168
|
// detect port as close to when used to prevent port being used by another process
|
|
131
169
|
// when running in parallel
|
|
132
|
-
const port = await detectPort(options.port || 8080);
|
|
133
170
|
args.push(`-p=${port}`);
|
|
134
171
|
const serve = (0, child_process_1.fork)(pathToHttpServer, [outputPath, ...args], {
|
|
135
172
|
stdio: 'pipe',
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export interface Schema {
|
|
2
|
-
host
|
|
3
|
-
port
|
|
4
|
-
ssl
|
|
2
|
+
host?: string;
|
|
3
|
+
port?: number;
|
|
4
|
+
ssl?: boolean;
|
|
5
5
|
sslKey?: string;
|
|
6
6
|
sslCert?: string;
|
|
7
7
|
proxyUrl?: string;
|
|
8
|
-
buildTarget
|
|
8
|
+
buildTarget?: string;
|
|
9
9
|
parallel: boolean;
|
|
10
10
|
maxParallel?: number;
|
|
11
11
|
withDeps: boolean;
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"proxyUrl": {
|
|
46
46
|
"type": "string",
|
|
47
|
-
"description": "URL to proxy unhandled requests to."
|
|
47
|
+
"description": "URL to proxy unhandled requests to. _Note: If the 'spa' flag is set to true, manually setting this value will override the catch-all redirect functionality from http-server which may lead to unexpected behavior._"
|
|
48
48
|
},
|
|
49
49
|
"proxyOptions": {
|
|
50
50
|
"type": "object",
|
|
@@ -94,6 +94,5 @@
|
|
|
94
94
|
"default": -1
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
|
-
"additionalProperties": false
|
|
98
|
-
"required": ["buildTarget"]
|
|
97
|
+
"additionalProperties": false
|
|
99
98
|
}
|
|
@@ -9,16 +9,45 @@ const path_1 = require("path");
|
|
|
9
9
|
const versions_2 = require("../../utils/versions");
|
|
10
10
|
const init_1 = require("../init/init");
|
|
11
11
|
const get_npm_scope_1 = require("@nx/js/src/utils/package-json/get-npm-scope");
|
|
12
|
+
const has_webpack_plugin_1 = require("../../utils/has-webpack-plugin");
|
|
13
|
+
const add_build_target_defaults_1 = require("@nx/devkit/src/generators/add-build-target-defaults");
|
|
14
|
+
const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-project-command");
|
|
12
15
|
function createApplicationFiles(tree, options) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
if (options.bundler === 'vite') {
|
|
17
|
+
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, './files/app-vite'), options.appProjectRoot, {
|
|
18
|
+
...options,
|
|
19
|
+
...(0, devkit_1.names)(options.name),
|
|
20
|
+
tmpl: '',
|
|
21
|
+
offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.appProjectRoot),
|
|
22
|
+
rootTsConfigPath: (0, js_1.getRelativePathToRootTsConfig)(tree, options.appProjectRoot),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, './files/app-webpack'), options.appProjectRoot, {
|
|
27
|
+
...options,
|
|
28
|
+
...(0, devkit_1.names)(options.name),
|
|
29
|
+
tmpl: '',
|
|
30
|
+
offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.appProjectRoot),
|
|
31
|
+
rootTsConfigPath: (0, js_1.getRelativePathToRootTsConfig)(tree, options.appProjectRoot),
|
|
32
|
+
webpackPluginOptions: (0, has_webpack_plugin_1.hasWebpackPlugin)(tree)
|
|
33
|
+
? {
|
|
34
|
+
compiler: options.compiler,
|
|
35
|
+
target: 'web',
|
|
36
|
+
outputPath: (0, devkit_1.joinPathFragments)('dist', options.appProjectRoot != '.'
|
|
37
|
+
? options.appProjectRoot
|
|
38
|
+
: options.projectName),
|
|
39
|
+
tsConfig: './tsconfig.app.json',
|
|
40
|
+
main: './src/main.ts',
|
|
41
|
+
assets: ['./src/favicon.ico', './src/assets'],
|
|
42
|
+
index: './src/index.html',
|
|
43
|
+
baseHref: '/',
|
|
44
|
+
styles: [`./src/styles.${options.style}`],
|
|
45
|
+
}
|
|
46
|
+
: null,
|
|
47
|
+
});
|
|
48
|
+
if (options.unitTestRunner === 'none') {
|
|
49
|
+
tree.delete((0, path_1.join)(options.appProjectRoot, './src/app/app.element.spec.ts'));
|
|
50
|
+
}
|
|
22
51
|
}
|
|
23
52
|
}
|
|
24
53
|
async function setupBundler(tree, options) {
|
|
@@ -31,6 +60,7 @@ async function setupBundler(tree, options) {
|
|
|
31
60
|
if (options.bundler === 'webpack') {
|
|
32
61
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/webpack', versions_2.nxVersion);
|
|
33
62
|
await configurationGenerator(tree, {
|
|
63
|
+
target: 'web',
|
|
34
64
|
project: options.projectName,
|
|
35
65
|
main,
|
|
36
66
|
tsConfig,
|
|
@@ -38,38 +68,42 @@ async function setupBundler(tree, options) {
|
|
|
38
68
|
devServer: true,
|
|
39
69
|
webpackConfig: (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'webpack.config.js'),
|
|
40
70
|
skipFormat: true,
|
|
71
|
+
addPlugin: options.addPlugin,
|
|
41
72
|
});
|
|
42
73
|
const project = (0, devkit_1.readProjectConfiguration)(tree, options.projectName);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
if (project.targets.build) {
|
|
75
|
+
const prodConfig = project.targets.build.configurations.production;
|
|
76
|
+
const buildOptions = project.targets.build.options;
|
|
77
|
+
buildOptions.assets = assets;
|
|
78
|
+
buildOptions.index = (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'src/index.html');
|
|
79
|
+
buildOptions.baseHref = '/';
|
|
80
|
+
buildOptions.styles = [
|
|
81
|
+
(0, devkit_1.joinPathFragments)(options.appProjectRoot, `src/styles.${options.style}`),
|
|
82
|
+
];
|
|
83
|
+
// We can delete that, because this projest is an application
|
|
84
|
+
// and applications have a .babelrc file in their root dir.
|
|
85
|
+
// So Nx will find it and use it
|
|
86
|
+
delete buildOptions.babelUpwardRootMode;
|
|
87
|
+
buildOptions.scripts = [];
|
|
88
|
+
prodConfig.fileReplacements = [
|
|
89
|
+
{
|
|
90
|
+
replace: (0, devkit_1.joinPathFragments)(options.appProjectRoot, `src/environments/environment.ts`),
|
|
91
|
+
with: (0, devkit_1.joinPathFragments)(options.appProjectRoot, `src/environments/environment.prod.ts`),
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
prodConfig.optimization = true;
|
|
95
|
+
prodConfig.outputHashing = 'all';
|
|
96
|
+
prodConfig.sourceMap = false;
|
|
97
|
+
prodConfig.namedChunks = false;
|
|
98
|
+
prodConfig.extractLicenses = true;
|
|
99
|
+
prodConfig.vendorChunk = false;
|
|
100
|
+
(0, devkit_1.updateProjectConfiguration)(tree, options.projectName, project);
|
|
101
|
+
}
|
|
102
|
+
// TODO(jack): Flush this out... no bundler should be possible for web but the experience isn't holistic due to missing features (e.g. writing index.html).
|
|
69
103
|
}
|
|
70
104
|
else if (options.bundler === 'none') {
|
|
71
|
-
// TODO(jack): Flush this out... no bundler should be possible for web but the experience isn't holistic due to missing features (e.g. writing index.html).
|
|
72
105
|
const project = (0, devkit_1.readProjectConfiguration)(tree, options.projectName);
|
|
106
|
+
(0, add_build_target_defaults_1.addBuildTargetDefaults)(tree, `@nx/js:${options.compiler}`);
|
|
73
107
|
project.targets.build = {
|
|
74
108
|
executor: `@nx/js:${options.compiler}`,
|
|
75
109
|
outputs: ['{options.outputPath}'],
|
|
@@ -77,7 +111,6 @@ async function setupBundler(tree, options) {
|
|
|
77
111
|
main,
|
|
78
112
|
outputPath: (0, devkit_1.joinPathFragments)('dist', options.appProjectRoot),
|
|
79
113
|
tsConfig,
|
|
80
|
-
assets,
|
|
81
114
|
},
|
|
82
115
|
};
|
|
83
116
|
(0, devkit_1.updateProjectConfiguration)(tree, options.projectName, project);
|
|
@@ -95,9 +128,6 @@ async function addProject(tree, options) {
|
|
|
95
128
|
tags: options.parsedTags,
|
|
96
129
|
targets,
|
|
97
130
|
}, options.standaloneConfig);
|
|
98
|
-
if (options.bundler !== 'vite') {
|
|
99
|
-
await setupBundler(tree, options);
|
|
100
|
-
}
|
|
101
131
|
}
|
|
102
132
|
function setDefaults(tree, options) {
|
|
103
133
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
@@ -113,6 +143,7 @@ function setDefaults(tree, options) {
|
|
|
113
143
|
}
|
|
114
144
|
async function applicationGenerator(host, schema) {
|
|
115
145
|
return await applicationGeneratorInternal(host, {
|
|
146
|
+
addPlugin: false,
|
|
116
147
|
projectNameAndRootFormat: 'derived',
|
|
117
148
|
...schema,
|
|
118
149
|
});
|
|
@@ -121,13 +152,21 @@ exports.applicationGenerator = applicationGenerator;
|
|
|
121
152
|
async function applicationGeneratorInternal(host, schema) {
|
|
122
153
|
const options = await normalizeOptions(host, schema);
|
|
123
154
|
const tasks = [];
|
|
155
|
+
const jsInitTask = await (0, js_1.initGenerator)(host, {
|
|
156
|
+
js: false,
|
|
157
|
+
skipFormat: true,
|
|
158
|
+
});
|
|
159
|
+
tasks.push(jsInitTask);
|
|
124
160
|
const webTask = await (0, init_1.webInitGenerator)(host, {
|
|
125
161
|
...options,
|
|
126
162
|
skipFormat: true,
|
|
127
163
|
});
|
|
128
164
|
tasks.push(webTask);
|
|
129
|
-
createApplicationFiles(host, options);
|
|
130
165
|
await addProject(host, options);
|
|
166
|
+
if (options.bundler !== 'vite') {
|
|
167
|
+
await setupBundler(host, options);
|
|
168
|
+
}
|
|
169
|
+
createApplicationFiles(host, options);
|
|
131
170
|
if (options.bundler === 'vite') {
|
|
132
171
|
const { viteConfigurationGenerator, createOrEditViteConfig } = (0, devkit_1.ensurePackage)('@nx/vite', versions_2.nxVersion);
|
|
133
172
|
// We recommend users use `import.meta.env.MODE` and other variables in their code to differentiate between production and development.
|
|
@@ -142,6 +181,7 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
142
181
|
includeVitest: options.unitTestRunner === 'vitest',
|
|
143
182
|
inSourceTests: options.inSourceTests,
|
|
144
183
|
skipFormat: true,
|
|
184
|
+
addPlugin: options.addPlugin,
|
|
145
185
|
});
|
|
146
186
|
tasks.push(viteTask);
|
|
147
187
|
createOrEditViteConfig(host, {
|
|
@@ -156,9 +196,10 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
156
196
|
const vitestTask = await vitestGenerator(host, {
|
|
157
197
|
uiFramework: 'none',
|
|
158
198
|
project: options.projectName,
|
|
159
|
-
coverageProvider: '
|
|
199
|
+
coverageProvider: 'v8',
|
|
160
200
|
inSourceTests: options.inSourceTests,
|
|
161
201
|
skipFormat: true,
|
|
202
|
+
addPlugin: options.addPlugin,
|
|
162
203
|
});
|
|
163
204
|
tasks.push(vitestTask);
|
|
164
205
|
createOrEditViteConfig(host, {
|
|
@@ -181,9 +222,9 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
181
222
|
(0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.app.json'),
|
|
182
223
|
],
|
|
183
224
|
unitTestRunner: options.unitTestRunner,
|
|
184
|
-
eslintFilePatterns: [`${options.appProjectRoot}/**/*.ts`],
|
|
185
225
|
skipFormat: true,
|
|
186
226
|
setParserOptionsProject: options.setParserOptionsProject,
|
|
227
|
+
addPlugin: options.addPlugin,
|
|
187
228
|
});
|
|
188
229
|
tasks.push(lintTask);
|
|
189
230
|
}
|
|
@@ -200,7 +241,8 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
200
241
|
const cypressTask = await configurationGenerator(host, {
|
|
201
242
|
...options,
|
|
202
243
|
project: options.e2eProjectName,
|
|
203
|
-
devServerTarget: `${options.projectName}
|
|
244
|
+
devServerTarget: `${options.projectName}:${options.e2eWebServerTarget}`,
|
|
245
|
+
baseUrl: options.e2eWebServerAddress,
|
|
204
246
|
directory: 'src',
|
|
205
247
|
skipFormat: true,
|
|
206
248
|
});
|
|
@@ -223,8 +265,9 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
223
265
|
js: false,
|
|
224
266
|
linter: options.linter,
|
|
225
267
|
setParserOptionsProject: options.setParserOptionsProject,
|
|
226
|
-
webServerCommand: `${(0, devkit_1.getPackageManagerCommand)().exec} nx
|
|
227
|
-
webServerAddress:
|
|
268
|
+
webServerCommand: `${(0, devkit_1.getPackageManagerCommand)().exec} nx ${options.e2eWebServerTarget} ${options.name}`,
|
|
269
|
+
webServerAddress: options.e2eWebServerAddress,
|
|
270
|
+
addPlugin: options.addPlugin,
|
|
228
271
|
});
|
|
229
272
|
tasks.push(playwrightTask);
|
|
230
273
|
}
|
|
@@ -236,6 +279,7 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
236
279
|
setupFile: 'web-components',
|
|
237
280
|
compiler: options.compiler,
|
|
238
281
|
skipFormat: true,
|
|
282
|
+
addPlugin: options.addPlugin,
|
|
239
283
|
});
|
|
240
284
|
tasks.push(jestTask);
|
|
241
285
|
}
|
|
@@ -257,9 +301,13 @@ async function applicationGeneratorInternal(host, schema) {
|
|
|
257
301
|
});
|
|
258
302
|
}
|
|
259
303
|
setDefaults(host, options);
|
|
304
|
+
tasks.push((0, devkit_1.addDependenciesToPackageJson)(host, { tslib: versions_2.tsLibVersion }, { '@types/node': versions_2.typesNodeVersion }));
|
|
260
305
|
if (!schema.skipFormat) {
|
|
261
306
|
await (0, devkit_1.formatFiles)(host);
|
|
262
307
|
}
|
|
308
|
+
tasks.push(() => {
|
|
309
|
+
(0, log_show_project_command_1.logShowProjectCommand)(options.projectName);
|
|
310
|
+
});
|
|
263
311
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
264
312
|
}
|
|
265
313
|
exports.applicationGeneratorInternal = applicationGeneratorInternal;
|
|
@@ -272,8 +320,39 @@ async function normalizeOptions(host, options) {
|
|
|
272
320
|
callingGenerator: '@nx/web:application',
|
|
273
321
|
});
|
|
274
322
|
options.projectNameAndRootFormat = projectNameAndRootFormat;
|
|
323
|
+
const nxJson = (0, devkit_1.readNxJson)(host);
|
|
324
|
+
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
325
|
+
nxJson.useInferencePlugins !== false;
|
|
326
|
+
options.addPlugin ??= addPluginDefault;
|
|
327
|
+
let e2eWebServerTarget = 'serve';
|
|
328
|
+
if (options.addPlugin) {
|
|
329
|
+
if (nxJson.plugins) {
|
|
330
|
+
for (const plugin of nxJson.plugins) {
|
|
331
|
+
if (options.bundler === 'vite' &&
|
|
332
|
+
typeof plugin === 'object' &&
|
|
333
|
+
plugin.plugin === '@nx/vite/plugin' &&
|
|
334
|
+
plugin.options.serveTargetName) {
|
|
335
|
+
e2eWebServerTarget = plugin.options
|
|
336
|
+
.serveTargetName;
|
|
337
|
+
}
|
|
338
|
+
else if (options.bundler === 'webpack' &&
|
|
339
|
+
typeof plugin === 'object' &&
|
|
340
|
+
plugin.plugin === '@nx/webpack/plugin' &&
|
|
341
|
+
plugin.options.serveTargetName) {
|
|
342
|
+
e2eWebServerTarget = plugin.options
|
|
343
|
+
.serveTargetName;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
let e2ePort = 4200;
|
|
349
|
+
if (nxJson.targetDefaults?.[e2eWebServerTarget] &&
|
|
350
|
+
nxJson.targetDefaults?.[e2eWebServerTarget].options?.port) {
|
|
351
|
+
e2ePort = nxJson.targetDefaults?.[e2eWebServerTarget].options?.port;
|
|
352
|
+
}
|
|
275
353
|
const e2eProjectName = `${appProjectName}-e2e`;
|
|
276
354
|
const e2eProjectRoot = `${appProjectRoot}-e2e`;
|
|
355
|
+
const e2eWebServerAddress = `http://localhost:${e2ePort}`;
|
|
277
356
|
const npmScope = (0, get_npm_scope_1.getNpmScope)(host);
|
|
278
357
|
const parsedTags = options.tags
|
|
279
358
|
? options.tags.split(',').map((s) => s.trim())
|
|
@@ -295,6 +374,9 @@ async function normalizeOptions(host, options) {
|
|
|
295
374
|
appProjectRoot,
|
|
296
375
|
e2eProjectRoot,
|
|
297
376
|
e2eProjectName,
|
|
377
|
+
e2eWebServerAddress,
|
|
378
|
+
e2eWebServerTarget,
|
|
379
|
+
e2ePort,
|
|
298
380
|
parsedTags,
|
|
299
381
|
};
|
|
300
382
|
}
|
|
@@ -278,7 +278,15 @@
|
|
|
278
278
|
#nx-console svg {
|
|
279
279
|
color: rgba(0, 122, 204, 1);
|
|
280
280
|
}
|
|
281
|
-
|
|
281
|
+
#nx-console-jetbrains {
|
|
282
|
+
margin-top: 2rem;
|
|
283
|
+
}
|
|
284
|
+
#nx-console-jetbrains:hover {
|
|
285
|
+
background-color: rgba(255, 49, 140, 1);
|
|
286
|
+
}
|
|
287
|
+
#nx-console-jetbrains svg {
|
|
288
|
+
color: rgba(255, 49, 140, 1);
|
|
289
|
+
}
|
|
282
290
|
#nx-repo:hover {
|
|
283
291
|
background-color: rgba(24, 23, 23, 1);
|
|
284
292
|
}
|
|
@@ -234,10 +234,44 @@ export class AppElement extends HTMLElement {
|
|
|
234
234
|
/>
|
|
235
235
|
</svg>
|
|
236
236
|
<span>
|
|
237
|
-
Install Nx Console
|
|
238
|
-
<span>
|
|
237
|
+
Install Nx Console for VSCode
|
|
238
|
+
<span>The official VSCode extension for Nx.</span>
|
|
239
239
|
</span>
|
|
240
240
|
</a>
|
|
241
|
+
<a
|
|
242
|
+
id="nx-console-jetbrains"
|
|
243
|
+
class="button-pill rounded shadow"
|
|
244
|
+
href="https://plugins.jetbrains.com/plugin/21060-nx-console"
|
|
245
|
+
target="_blank"
|
|
246
|
+
rel="noreferrer"
|
|
247
|
+
>
|
|
248
|
+
<svg
|
|
249
|
+
height="48"
|
|
250
|
+
width="48"
|
|
251
|
+
viewBox="20 20 60 60"
|
|
252
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
253
|
+
>
|
|
254
|
+
<path d="m22.5 22.5h60v60h-60z" />
|
|
255
|
+
<g fill="#fff">
|
|
256
|
+
<path d="m29.03 71.25h22.5v3.75h-22.5z" />
|
|
257
|
+
<path d="m28.09 38 1.67-1.58a1.88 1.88 0 0 0 1.47.87c.64 0 1.06-.44 1.06-1.31v-5.98h2.58v6a3.48 3.48 0 0 1 -.87 2.6 3.56 3.56 0 0 1 -2.57.95 3.84 3.84 0 0 1 -3.34-1.55z" />
|
|
258
|
+
<path d="m36 30h7.53v2.19h-5v1.44h4.49v2h-4.42v1.49h5v2.21h-7.6z" />
|
|
259
|
+
<path d="m47.23 32.29h-2.8v-2.29h8.21v2.27h-2.81v7.1h-2.6z" />
|
|
260
|
+
<path d="m29.13 43.08h4.42a3.53 3.53 0 0 1 2.55.83 2.09 2.09 0 0 1 .6 1.53 2.16 2.16 0 0 1 -1.44 2.09 2.27 2.27 0 0 1 1.86 2.29c0 1.61-1.31 2.59-3.55 2.59h-4.44zm5 2.89c0-.52-.42-.8-1.18-.8h-1.29v1.64h1.24c.79 0 1.25-.26 1.25-.81zm-.9 2.66h-1.57v1.73h1.62c.8 0 1.24-.31 1.24-.86 0-.5-.4-.87-1.27-.87z" />
|
|
261
|
+
<path d="m38 43.08h4.1a4.19 4.19 0 0 1 3 1 2.93 2.93 0 0 1 .9 2.19 3 3 0 0 1 -1.93 2.89l2.24 3.27h-3l-1.88-2.84h-.87v2.84h-2.56zm4 4.5c.87 0 1.39-.43 1.39-1.11 0-.75-.54-1.12-1.4-1.12h-1.44v2.26z" />
|
|
262
|
+
<path d="m49.59 43h2.5l4 9.44h-2.79l-.67-1.69h-3.63l-.67 1.69h-2.71zm2.27 5.73-1-2.65-1.06 2.65z" />
|
|
263
|
+
<path d="m56.46 43.05h2.6v9.37h-2.6z" />
|
|
264
|
+
<path d="m60.06 43.05h2.42l3.37 5v-5h2.57v9.37h-2.26l-3.53-5.14v5.14h-2.57z" />
|
|
265
|
+
<path d="m68.86 51 1.45-1.73a4.84 4.84 0 0 0 3 1.13c.71 0 1.08-.24 1.08-.65 0-.4-.31-.6-1.59-.91-2-.46-3.53-1-3.53-2.93 0-1.74 1.37-3 3.62-3a5.89 5.89 0 0 1 3.86 1.25l-1.26 1.84a4.63 4.63 0 0 0 -2.62-.92c-.63 0-.94.25-.94.6 0 .42.32.61 1.63.91 2.14.46 3.44 1.16 3.44 2.91 0 1.91-1.51 3-3.79 3a6.58 6.58 0 0 1 -4.35-1.5z" />
|
|
266
|
+
</g>
|
|
267
|
+
</svg>
|
|
268
|
+
<span>
|
|
269
|
+
Install Nx Console for JetBrains
|
|
270
|
+
<span>
|
|
271
|
+
Available for WebStorm, Intellij IDEA Ultimate and more!
|
|
272
|
+
</span>
|
|
273
|
+
</span>
|
|
274
|
+
</a>
|
|
241
275
|
<div id="nx-cloud" class="rounded shadow">
|
|
242
276
|
<div>
|
|
243
277
|
<svg id="nx-cloud-logo" role="img" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" fill="transparent" viewBox="0 0 24 24">
|
|
@@ -245,7 +279,7 @@ export class AppElement extends HTMLElement {
|
|
|
245
279
|
<path stroke-width="2" d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z" />
|
|
246
280
|
</svg>
|
|
247
281
|
<h2>
|
|
248
|
-
|
|
282
|
+
Nx Cloud
|
|
249
283
|
<span>
|
|
250
284
|
Enable faster CI & better DX
|
|
251
285
|
</span>
|
|
@@ -255,7 +289,7 @@ export class AppElement extends HTMLElement {
|
|
|
255
289
|
You can activate distributed tasks executions and caching by
|
|
256
290
|
running:
|
|
257
291
|
</p>
|
|
258
|
-
<pre>nx connect
|
|
292
|
+
<pre>nx connect</pre>
|
|
259
293
|
<a href="https://nx.app/?utm_source=nx-project" target="_blank" rel="noreferrer"> What is Nx Cloud? </a>
|
|
260
294
|
</div>
|
|
261
295
|
<a id="nx-repo" class="button-pill rounded shadow" href="https://github.com/nrwl/nx?utm_source=nx-project" target="_blank" rel="noreferrer">
|
|
@@ -302,7 +336,7 @@ export class AppElement extends HTMLElement {
|
|
|
302
336
|
nx g @nx/angular:lib ui
|
|
303
337
|
|
|
304
338
|
<span># Add a component</span>
|
|
305
|
-
nx g @nx/angular:component button
|
|
339
|
+
nx g @nx/angular:component ui/src/lib/button</pre>
|
|
306
340
|
</details>
|
|
307
341
|
<details>
|
|
308
342
|
<summary>
|
|
@@ -278,7 +278,15 @@
|
|
|
278
278
|
#nx-console svg {
|
|
279
279
|
color: rgba(0, 122, 204, 1);
|
|
280
280
|
}
|
|
281
|
-
|
|
281
|
+
#nx-console-jetbrains {
|
|
282
|
+
margin-top: 2rem;
|
|
283
|
+
}
|
|
284
|
+
#nx-console-jetbrains:hover {
|
|
285
|
+
background-color: rgba(255, 49, 140, 1);
|
|
286
|
+
}
|
|
287
|
+
#nx-console-jetbrains svg {
|
|
288
|
+
color: rgba(255, 49, 140, 1);
|
|
289
|
+
}
|
|
282
290
|
#nx-repo:hover {
|
|
283
291
|
background-color: rgba(24, 23, 23, 1);
|
|
284
292
|
}
|
|
@@ -234,10 +234,44 @@ export class AppElement extends HTMLElement {
|
|
|
234
234
|
/>
|
|
235
235
|
</svg>
|
|
236
236
|
<span>
|
|
237
|
-
Install Nx Console
|
|
238
|
-
<span>
|
|
237
|
+
Install Nx Console for VSCode
|
|
238
|
+
<span>The official VSCode extension for Nx.</span>
|
|
239
239
|
</span>
|
|
240
240
|
</a>
|
|
241
|
+
<a
|
|
242
|
+
id="nx-console-jetbrains"
|
|
243
|
+
class="button-pill rounded shadow"
|
|
244
|
+
href="https://plugins.jetbrains.com/plugin/21060-nx-console"
|
|
245
|
+
target="_blank"
|
|
246
|
+
rel="noreferrer"
|
|
247
|
+
>
|
|
248
|
+
<svg
|
|
249
|
+
height="48"
|
|
250
|
+
width="48"
|
|
251
|
+
viewBox="20 20 60 60"
|
|
252
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
253
|
+
>
|
|
254
|
+
<path d="m22.5 22.5h60v60h-60z" />
|
|
255
|
+
<g fill="#fff">
|
|
256
|
+
<path d="m29.03 71.25h22.5v3.75h-22.5z" />
|
|
257
|
+
<path d="m28.09 38 1.67-1.58a1.88 1.88 0 0 0 1.47.87c.64 0 1.06-.44 1.06-1.31v-5.98h2.58v6a3.48 3.48 0 0 1 -.87 2.6 3.56 3.56 0 0 1 -2.57.95 3.84 3.84 0 0 1 -3.34-1.55z" />
|
|
258
|
+
<path d="m36 30h7.53v2.19h-5v1.44h4.49v2h-4.42v1.49h5v2.21h-7.6z" />
|
|
259
|
+
<path d="m47.23 32.29h-2.8v-2.29h8.21v2.27h-2.81v7.1h-2.6z" />
|
|
260
|
+
<path d="m29.13 43.08h4.42a3.53 3.53 0 0 1 2.55.83 2.09 2.09 0 0 1 .6 1.53 2.16 2.16 0 0 1 -1.44 2.09 2.27 2.27 0 0 1 1.86 2.29c0 1.61-1.31 2.59-3.55 2.59h-4.44zm5 2.89c0-.52-.42-.8-1.18-.8h-1.29v1.64h1.24c.79 0 1.25-.26 1.25-.81zm-.9 2.66h-1.57v1.73h1.62c.8 0 1.24-.31 1.24-.86 0-.5-.4-.87-1.27-.87z" />
|
|
261
|
+
<path d="m38 43.08h4.1a4.19 4.19 0 0 1 3 1 2.93 2.93 0 0 1 .9 2.19 3 3 0 0 1 -1.93 2.89l2.24 3.27h-3l-1.88-2.84h-.87v2.84h-2.56zm4 4.5c.87 0 1.39-.43 1.39-1.11 0-.75-.54-1.12-1.4-1.12h-1.44v2.26z" />
|
|
262
|
+
<path d="m49.59 43h2.5l4 9.44h-2.79l-.67-1.69h-3.63l-.67 1.69h-2.71zm2.27 5.73-1-2.65-1.06 2.65z" />
|
|
263
|
+
<path d="m56.46 43.05h2.6v9.37h-2.6z" />
|
|
264
|
+
<path d="m60.06 43.05h2.42l3.37 5v-5h2.57v9.37h-2.26l-3.53-5.14v5.14h-2.57z" />
|
|
265
|
+
<path d="m68.86 51 1.45-1.73a4.84 4.84 0 0 0 3 1.13c.71 0 1.08-.24 1.08-.65 0-.4-.31-.6-1.59-.91-2-.46-3.53-1-3.53-2.93 0-1.74 1.37-3 3.62-3a5.89 5.89 0 0 1 3.86 1.25l-1.26 1.84a4.63 4.63 0 0 0 -2.62-.92c-.63 0-.94.25-.94.6 0 .42.32.61 1.63.91 2.14.46 3.44 1.16 3.44 2.91 0 1.91-1.51 3-3.79 3a6.58 6.58 0 0 1 -4.35-1.5z" />
|
|
266
|
+
</g>
|
|
267
|
+
</svg>
|
|
268
|
+
<span>
|
|
269
|
+
Install Nx Console for JetBrains
|
|
270
|
+
<span>
|
|
271
|
+
Available for WebStorm, Intellij IDEA Ultimate and more!
|
|
272
|
+
</span>
|
|
273
|
+
</span>
|
|
274
|
+
</a>
|
|
241
275
|
<div id="nx-cloud" class="rounded shadow">
|
|
242
276
|
<div>
|
|
243
277
|
<svg id="nx-cloud-logo" role="img" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" fill="transparent" viewBox="0 0 24 24">
|
|
@@ -245,7 +279,7 @@ export class AppElement extends HTMLElement {
|
|
|
245
279
|
<path stroke-width="2" d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z" />
|
|
246
280
|
</svg>
|
|
247
281
|
<h2>
|
|
248
|
-
|
|
282
|
+
Nx Cloud
|
|
249
283
|
<span>
|
|
250
284
|
Enable faster CI & better DX
|
|
251
285
|
</span>
|
|
@@ -255,7 +289,7 @@ export class AppElement extends HTMLElement {
|
|
|
255
289
|
You can activate distributed tasks executions and caching by
|
|
256
290
|
running:
|
|
257
291
|
</p>
|
|
258
|
-
<pre>nx connect
|
|
292
|
+
<pre>nx connect</pre>
|
|
259
293
|
<a href="https://nx.app/?utm_source=nx-project" target="_blank" rel="noreferrer"> What is Nx Cloud? </a>
|
|
260
294
|
</div>
|
|
261
295
|
<a id="nx-repo" class="button-pill rounded shadow" href="https://github.com/nrwl/nx?utm_source=nx-project" target="_blank" rel="noreferrer">
|
|
@@ -302,7 +336,7 @@ export class AppElement extends HTMLElement {
|
|
|
302
336
|
nx g @nx/angular:lib ui
|
|
303
337
|
|
|
304
338
|
<span># Add a component</span>
|
|
305
|
-
nx g @nx/angular:component button
|
|
339
|
+
nx g @nx/angular:component ui/src/lib/button</pre>
|
|
306
340
|
</details>
|
|
307
341
|
<details>
|
|
308
342
|
<summary>
|
|
@@ -1,8 +1,39 @@
|
|
|
1
|
+
<% if (webpackPluginOptions) { %>
|
|
2
|
+
const { NxWebpackPlugin } = require('@nx/webpack');
|
|
3
|
+
const { join } = require('path');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
output: {
|
|
7
|
+
path: join(__dirname, '<%= offsetFromRoot %><%= webpackPluginOptions.outputPath %>'),
|
|
8
|
+
},
|
|
9
|
+
devServer: {
|
|
10
|
+
port: 4200
|
|
11
|
+
},
|
|
12
|
+
plugins: [
|
|
13
|
+
new NxWebpackPlugin({
|
|
14
|
+
tsConfig: '<%= webpackPluginOptions.tsConfig %>',
|
|
15
|
+
compiler: '<%= webpackPluginOptions.compiler %>',
|
|
16
|
+
main: '<%= webpackPluginOptions.main %>',
|
|
17
|
+
index: '<%= webpackPluginOptions.index %>',
|
|
18
|
+
baseHref: '<%= webpackPluginOptions.baseHref %>',
|
|
19
|
+
assets: <%- JSON.stringify(webpackPluginOptions.assets) %>,
|
|
20
|
+
styles: <%- JSON.stringify(webpackPluginOptions.styles) %>,
|
|
21
|
+
outputHashing: process.env['NODE_ENV'] === 'production' ? 'all' : 'none',
|
|
22
|
+
optimization: process.env['NODE_ENV'] === 'production',
|
|
23
|
+
})
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
<% } else { %>
|
|
1
27
|
const { composePlugins, withNx, withWeb } = require('@nx/webpack');
|
|
2
28
|
|
|
3
29
|
// Nx plugins for webpack.
|
|
4
|
-
module.exports = composePlugins(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
30
|
+
module.exports = composePlugins(
|
|
31
|
+
withNx(),
|
|
32
|
+
withWeb(),
|
|
33
|
+
(config) => {
|
|
34
|
+
// Update the webpack config as needed here.
|
|
35
|
+
// e.g. `config.plugins.push(new MyPlugin())`
|
|
36
|
+
return config;
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
<% } %>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
3
|
"cli": "nx",
|
|
4
4
|
"$id": "NxWebApp",
|
|
5
5
|
"title": "Create a Web Application for Nx",
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
"value": "scss",
|
|
42
|
-
"label": "SASS(.scss) [
|
|
42
|
+
"label": "SASS(.scss) [ https://sass-lang.com ]"
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
"value": "less",
|
|
46
|
-
"label": "LESS [
|
|
46
|
+
"label": "LESS [ https://lesscss.org ]"
|
|
47
47
|
}
|
|
48
48
|
]
|
|
49
49
|
}
|
|
@@ -2,55 +2,22 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.webInitGenerator = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const js_1 = require("@nx/js");
|
|
6
5
|
const versions_1 = require("../../utils/versions");
|
|
7
6
|
function updateDependencies(tree, schema) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
13
|
-
return (0, devkit_1.addDependenciesToPackageJson)(tree, {
|
|
14
|
-
tslib: versions_1.tsLibVersion,
|
|
15
|
-
}, devDependencies);
|
|
7
|
+
const tasks = [];
|
|
8
|
+
tasks.push((0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/web'], []));
|
|
9
|
+
tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@nx/web': versions_1.nxVersion }, undefined, schema.keepExistingVersions));
|
|
10
|
+
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
16
11
|
}
|
|
17
12
|
async function webInitGenerator(tree, schema) {
|
|
18
|
-
|
|
19
|
-
const jsInitTask = await (0, js_1.initGenerator)(tree, {
|
|
20
|
-
js: false,
|
|
21
|
-
skipFormat: true,
|
|
22
|
-
});
|
|
23
|
-
tasks.push(jsInitTask);
|
|
24
|
-
if (!schema.unitTestRunner || schema.unitTestRunner === 'jest') {
|
|
25
|
-
const { jestInitGenerator } = (0, devkit_1.ensurePackage)('@nx/jest', versions_1.nxVersion);
|
|
26
|
-
const jestTask = await jestInitGenerator(tree, {
|
|
27
|
-
skipPackageJson: schema.skipPackageJson,
|
|
28
|
-
});
|
|
29
|
-
tasks.push(jestTask);
|
|
30
|
-
}
|
|
31
|
-
if (!schema.e2eTestRunner || schema.e2eTestRunner === 'cypress') {
|
|
32
|
-
const { cypressInitGenerator } = (0, devkit_1.ensurePackage)('@nx/cypress', versions_1.nxVersion);
|
|
33
|
-
const cypressTask = await cypressInitGenerator(tree, {
|
|
34
|
-
skipPackageJson: schema.skipPackageJson,
|
|
35
|
-
});
|
|
36
|
-
tasks.push(cypressTask);
|
|
37
|
-
}
|
|
38
|
-
else if (schema.e2eTestRunner === 'playwright') {
|
|
39
|
-
const { initGenerator: playwrightInitGenerator } = (0, devkit_1.ensurePackage)('@nx/playwright', versions_1.nxVersion);
|
|
40
|
-
const playwrightConfigTask = await playwrightInitGenerator(tree, {
|
|
41
|
-
skipFormat: true,
|
|
42
|
-
skipPackageJson: schema.skipPackageJson,
|
|
43
|
-
});
|
|
44
|
-
tasks.push(playwrightConfigTask);
|
|
45
|
-
}
|
|
13
|
+
let installTask = () => { };
|
|
46
14
|
if (!schema.skipPackageJson) {
|
|
47
|
-
|
|
48
|
-
tasks.push(installTask);
|
|
15
|
+
installTask = updateDependencies(tree, schema);
|
|
49
16
|
}
|
|
50
17
|
if (!schema.skipFormat) {
|
|
51
18
|
await (0, devkit_1.formatFiles)(tree);
|
|
52
19
|
}
|
|
53
|
-
return
|
|
20
|
+
return installTask;
|
|
54
21
|
}
|
|
55
22
|
exports.webInitGenerator = webInitGenerator;
|
|
56
23
|
exports.default = webInitGenerator;
|
|
@@ -1,30 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
3
|
"$id": "NxWebInit",
|
|
4
4
|
"cli": "nx",
|
|
5
5
|
"title": "Init Web Plugin",
|
|
6
6
|
"description": "Init Web Plugin.",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
9
|
-
"bundler": {
|
|
10
|
-
"type": "string",
|
|
11
|
-
"description": "The bundler to use.",
|
|
12
|
-
"enum": ["webpack", "none", "vite"],
|
|
13
|
-
"default": "webpack"
|
|
14
|
-
},
|
|
15
|
-
"unitTestRunner": {
|
|
16
|
-
"description": "Adds the specified unit test runner",
|
|
17
|
-
"type": "string",
|
|
18
|
-
"enum": ["jest", "none"],
|
|
19
|
-
"default": "jest"
|
|
20
|
-
},
|
|
21
|
-
"e2eTestRunner": {
|
|
22
|
-
"description": "Adds the specified e2e test runner",
|
|
23
|
-
"type": "string",
|
|
24
|
-
"enum": ["cypress", "playwright", "none"],
|
|
25
|
-
"x-prompt": "Which E2E test runner would you like to use?",
|
|
26
|
-
"default": "cypress"
|
|
27
|
-
},
|
|
28
9
|
"skipFormat": {
|
|
29
10
|
"description": "Skip formatting files",
|
|
30
11
|
"type": "boolean",
|
|
@@ -35,6 +16,12 @@
|
|
|
35
16
|
"type": "boolean",
|
|
36
17
|
"default": false,
|
|
37
18
|
"x-priority": "internal"
|
|
19
|
+
},
|
|
20
|
+
"keepExistingVersions": {
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"x-priority": "internal",
|
|
23
|
+
"description": "Keep existing dependencies versions",
|
|
24
|
+
"default": false
|
|
38
25
|
}
|
|
39
26
|
},
|
|
40
27
|
"required": []
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
3
|
"$id": "NxWebStaticServe",
|
|
4
4
|
"cli": "nx",
|
|
5
5
|
"title": "Static Serve Configuration",
|
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
"type": "string",
|
|
19
19
|
"description": "Name of the serve target to add. Defaults to 'serve-static'.",
|
|
20
20
|
"default": "serve-static"
|
|
21
|
+
},
|
|
22
|
+
"spa": {
|
|
23
|
+
"type": "boolean",
|
|
24
|
+
"description": "Whether to set the 'spa' flag on the generated target.",
|
|
25
|
+
"default": true
|
|
21
26
|
}
|
|
22
27
|
},
|
|
23
28
|
"required": ["buildTarget"]
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Tree } from '@nx/devkit';
|
|
1
|
+
import { type Tree } from '@nx/devkit';
|
|
2
2
|
interface WebStaticServeSchema {
|
|
3
3
|
buildTarget: string;
|
|
4
4
|
outputPath?: string;
|
|
5
5
|
targetName?: string;
|
|
6
|
+
spa?: boolean;
|
|
6
7
|
}
|
|
7
|
-
export declare function webStaticServeGenerator(tree: Tree, options: WebStaticServeSchema): void
|
|
8
|
+
export declare function webStaticServeGenerator(tree: Tree, options: WebStaticServeSchema): Promise<void>;
|
|
8
9
|
export default webStaticServeGenerator;
|
|
@@ -2,17 +2,25 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.webStaticServeGenerator = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
function webStaticServeGenerator(tree, options) {
|
|
6
|
-
const opts = normalizeOptions(tree, options);
|
|
5
|
+
async function webStaticServeGenerator(tree, options) {
|
|
6
|
+
const opts = await normalizeOptions(tree, options);
|
|
7
7
|
addStaticConfig(tree, opts);
|
|
8
8
|
}
|
|
9
9
|
exports.webStaticServeGenerator = webStaticServeGenerator;
|
|
10
|
-
function normalizeOptions(tree, options) {
|
|
11
|
-
|
|
10
|
+
async function normalizeOptions(tree, options) {
|
|
11
|
+
let projectGraph;
|
|
12
|
+
try {
|
|
13
|
+
projectGraph = (0, devkit_1.readCachedProjectGraph)();
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
projectGraph = await (0, devkit_1.createProjectGraphAsync)();
|
|
17
|
+
}
|
|
18
|
+
const target = (0, devkit_1.parseTargetString)(options.buildTarget, projectGraph);
|
|
12
19
|
const opts = {
|
|
13
20
|
...options,
|
|
14
21
|
targetName: options.targetName || 'serve-static',
|
|
15
22
|
projectName: target.project,
|
|
23
|
+
spa: options.spa ?? true,
|
|
16
24
|
};
|
|
17
25
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, target.project);
|
|
18
26
|
const buildTargetConfig = projectConfig?.targets?.[target.target];
|
|
@@ -27,7 +35,7 @@ Optionally, you can provide a different name with the --target-name option other
|
|
|
27
35
|
}
|
|
28
36
|
// NOTE: @nx/web:file-server only looks for the outputPath option
|
|
29
37
|
if (!buildTargetConfig.options?.outputPath && !opts.outputPath) {
|
|
30
|
-
// attempt to find the
|
|
38
|
+
// attempt to find the suitable path from the outputs
|
|
31
39
|
let maybeOutputValue;
|
|
32
40
|
for (const o of buildTargetConfig?.outputs || []) {
|
|
33
41
|
const isInterpolatedOutput = o.trim().startsWith('{options.');
|
|
@@ -65,6 +73,7 @@ function addStaticConfig(tree, opts) {
|
|
|
65
73
|
options: {
|
|
66
74
|
buildTarget: opts.buildTarget,
|
|
67
75
|
staticFilePath: opts.outputPath,
|
|
76
|
+
spa: opts.spa,
|
|
68
77
|
},
|
|
69
78
|
};
|
|
70
79
|
projectConfig.targets[opts.targetName] = staticServeOptions;
|
|
@@ -13,7 +13,7 @@ async function addDroppedDependencies(tree) {
|
|
|
13
13
|
for (const [_, projectConfiguration] of projects) {
|
|
14
14
|
for (const [_, targetConfiguration] of Object.entries(projectConfiguration.targets ?? {})) {
|
|
15
15
|
for (const droppedDependency of droppedDependencies) {
|
|
16
|
-
if (targetConfiguration
|
|
16
|
+
if (targetConfiguration?.['executor']?.startsWith(droppedDependency + ':')) {
|
|
17
17
|
devDependencies[droppedDependency] = devkit_1.NX_VERSION;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -22,7 +22,7 @@ async function addDroppedDependencies(tree) {
|
|
|
22
22
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
23
23
|
for (const [_, targetConfiguration] of Object.entries(nxJson?.targetDefaults ?? {})) {
|
|
24
24
|
for (const droppedDependency of droppedDependencies) {
|
|
25
|
-
if (targetConfiguration
|
|
25
|
+
if (targetConfiguration?.['executor']?.startsWith(droppedDependency + ':')) {
|
|
26
26
|
devDependencies[droppedDependency] = devkit_1.NX_VERSION;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasWebpackPlugin = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
function hasWebpackPlugin(tree) {
|
|
6
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
7
|
+
return !!nxJson.plugins?.some((p) => typeof p === 'string'
|
|
8
|
+
? p === '@nx/webpack/plugin'
|
|
9
|
+
: p.plugin === '@nx/webpack/plugin');
|
|
10
|
+
}
|
|
11
|
+
exports.hasWebpackPlugin = hasWebpackPlugin;
|
package/src/utils/versions.d.ts
CHANGED
package/src/utils/versions.js
CHANGED
|
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.tsLibVersion = exports.typesNodeVersion = exports.swcLoaderVersion = exports.nxVersion = void 0;
|
|
4
4
|
exports.nxVersion = require('../../package.json').version;
|
|
5
5
|
exports.swcLoaderVersion = '0.1.15';
|
|
6
|
-
exports.typesNodeVersion = '18.
|
|
6
|
+
exports.typesNodeVersion = '18.16.9';
|
|
7
7
|
exports.tsLibVersion = '^2.3.0';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.waitForPortOpen = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
4
5
|
const net = require("net");
|
|
5
6
|
function waitForPortOpen(port, options = {}) {
|
|
6
|
-
const
|
|
7
|
+
const host = options.host ?? '127.0.0.1';
|
|
8
|
+
const allowedErrorCodes = ['ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT'];
|
|
7
9
|
return new Promise((resolve, reject) => {
|
|
8
10
|
const checkPort = (retries = options.retries ?? 120) => {
|
|
9
11
|
const client = new net.Socket();
|
|
@@ -20,6 +22,9 @@ function waitForPortOpen(port, options = {}) {
|
|
|
20
22
|
});
|
|
21
23
|
client.once('error', (err) => {
|
|
22
24
|
if (retries === 0 || !allowedErrorCodes.includes(err['code'])) {
|
|
25
|
+
if (process.env['NX_VERBOSE_LOGGING'] === 'true') {
|
|
26
|
+
devkit_1.logger.info(`Error connecting on ${host}:${port}: ${err['code'] || err}`);
|
|
27
|
+
}
|
|
23
28
|
cleanupClient();
|
|
24
29
|
reject(err);
|
|
25
30
|
}
|
|
@@ -29,7 +34,10 @@ function waitForPortOpen(port, options = {}) {
|
|
|
29
34
|
});
|
|
30
35
|
// Node will use IPv6 if it is available, but this can cause issues if the server is only listening on IPv4.
|
|
31
36
|
// Hard-coding to look on 127.0.0.1 to avoid using the IPv6 loopback address "::1".
|
|
32
|
-
|
|
37
|
+
if (process.env['NX_VERBOSE_LOGGING'] === 'true') {
|
|
38
|
+
devkit_1.logger.info(`Connecting on ${host}:${port}`);
|
|
39
|
+
}
|
|
40
|
+
client.connect({ port, host });
|
|
33
41
|
};
|
|
34
42
|
checkPort();
|
|
35
43
|
});
|