@nx/angular 21.0.0-canary.20250206-8bd0bcd → 21.0.0-canary.20250418-8619c1d
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/fesm2022/nx-angular.mjs +0 -352
- package/fesm2022/nx-angular.mjs.map +1 -1
- package/generators.json +7 -2
- package/index.d.ts +1 -1
- package/migrations.json +199 -69
- package/ng-package.json +1 -1
- package/package.json +11 -14
- package/src/builders/dev-server/dev-server.impl.js +2 -3
- package/src/builders/dev-server/lib/normalize-options.js +1 -0
- package/src/builders/dev-server/schema.d.ts +4 -0
- package/src/builders/dev-server/schema.json +9 -4
- package/src/builders/webpack-browser/schema.d.ts +1 -4
- package/src/builders/webpack-browser/schema.json +5 -0
- package/src/builders/webpack-browser/webpack-browser.impl.js +5 -5
- package/src/executors/delegate-build/delegate-build.impl.d.ts +1 -3
- package/src/executors/delegate-build/delegate-build.impl.js +0 -3
- package/src/executors/module-federation-dev-server/schema.d.ts +3 -0
- package/src/executors/module-federation-dev-server/schema.json +1 -1
- package/src/executors/package/package.impl.js +1 -4
- package/src/generators/add-linting/add-linting.js +1 -16
- package/src/generators/add-linting/lib/create-eslint-configuration.d.ts +2 -2
- package/src/generators/add-linting/lib/create-eslint-configuration.js +2 -2
- package/src/generators/add-linting/schema.d.ts +1 -0
- package/src/generators/application/application.js +20 -1
- package/src/generators/application/files/rspack-ssr/server.ts__tmpl__ +72 -0
- package/src/generators/application/lib/add-e2e.js +2 -9
- package/src/generators/application/lib/add-linting.js +1 -0
- package/src/generators/application/lib/add-serve-static-target.js +1 -0
- package/src/generators/application/lib/add-unit-test-runner.js +2 -0
- package/src/generators/application/lib/create-project.js +1 -0
- package/src/generators/application/lib/normalize-options.d.ts +1 -1
- package/src/generators/application/lib/normalize-options.js +9 -2
- package/src/generators/application/schema.d.ts +2 -2
- package/src/generators/application/schema.json +1 -7
- package/src/generators/component-test/component-test.js +1 -1
- package/src/generators/convert-to-rspack/convert-to-rspack.d.ts +4 -0
- package/src/generators/convert-to-rspack/convert-to-rspack.js +314 -0
- package/src/generators/convert-to-rspack/lib/create-config.d.ts +2 -0
- package/src/generators/convert-to-rspack/lib/create-config.js +48 -0
- package/src/generators/convert-to-rspack/lib/get-custom-webpack-config.d.ts +6 -0
- package/src/generators/convert-to-rspack/lib/get-custom-webpack-config.js +75 -0
- package/src/generators/convert-to-rspack/lib/update-tsconfig.d.ts +2 -0
- package/src/generators/convert-to-rspack/lib/update-tsconfig.js +26 -0
- package/src/generators/convert-to-rspack/lib/validate-supported-executor.d.ts +2 -0
- package/src/generators/convert-to-rspack/lib/validate-supported-executor.js +14 -0
- package/src/generators/convert-to-rspack/schema.d.ts +5 -0
- package/src/generators/convert-to-rspack/schema.json +30 -0
- package/src/generators/host/host.js +1 -1
- package/src/generators/host/schema.d.ts +0 -1
- package/src/generators/host/schema.json +0 -6
- package/src/generators/library/lib/add-project.d.ts +1 -1
- package/src/generators/library/lib/add-project.js +7 -1
- package/src/generators/library/lib/normalize-options.js +1 -1
- package/src/generators/library/lib/normalized-schema.d.ts +0 -1
- package/src/generators/library/library.js +5 -1
- package/src/generators/library/schema.d.ts +0 -1
- package/src/generators/library/schema.json +0 -6
- package/src/generators/move/move.d.ts +3 -0
- package/src/generators/move/move.js +3 -0
- package/src/generators/ng-add/migrators/projects/e2e.migrator.js +2 -2
- package/src/generators/ngrx/ngrx.d.ts +3 -0
- package/src/generators/ngrx/ngrx.js +3 -0
- package/src/generators/ngrx/schema.json +1 -1
- package/src/generators/ngrx-feature-store/schema.d.ts +1 -1
- package/src/generators/remote/remote.js +1 -1
- package/src/generators/remote/schema.d.ts +0 -1
- package/src/generators/remote/schema.json +0 -6
- package/src/generators/setup-mf/lib/setup-serve-target.js +1 -0
- package/src/generators/setup-ssr/files/v19+/application-builder/ngmodule-src/app/__rootModuleFileName__ +2 -2
- package/src/generators/setup-ssr/files/v19+/application-builder/server/__serverFileName__ +1 -1
- package/src/generators/setup-ssr/files/v19+/application-builder/standalone-src/app/app.config.server.ts__tpl__ +2 -2
- package/src/generators/setup-ssr/files/v19+/application-builder-common-engine/server/__serverFileName__ +2 -0
- package/src/generators/setup-ssr/lib/generate-files.js +12 -1
- package/src/generators/setup-ssr/lib/update-project-config.js +1 -0
- package/src/generators/stories/stories.js +2 -2
- package/src/generators/utils/add-jest.d.ts +1 -0
- package/src/generators/utils/add-jest.js +2 -2
- package/src/generators/utils/add-vitest.d.ts +1 -0
- package/src/generators/utils/add-vitest.js +1 -1
- package/src/generators/utils/ensure-angular-dependencies.js +0 -1
- package/src/migrations/update-16-2-0/switch-data-persistence-operators-imports-to-ngrx-router-store.js +4 -4
- package/src/migrations/update-19-6-0/turn-off-dts-by-default.js +2 -2
- package/src/migrations/{update-16-1-0 → update-20-5-0}/update-angular-cli.d.ts +1 -1
- package/src/migrations/{update-16-1-0 → update-20-5-0}/update-angular-cli.js +1 -1
- package/src/migrations/{update-16-1-0/remove-ngcc-invocation.d.ts → update-21-0-0/change-data-persistence-operators-imports-to-ngrx-router-store-data-persistence.d.ts} +1 -1
- package/src/migrations/update-21-0-0/change-data-persistence-operators-imports-to-ngrx-router-store-data-persistence.js +122 -0
- package/src/migrations/update-21-0-0/set-continuous-option.d.ts +3 -0
- package/src/migrations/update-21-0-0/set-continuous-option.js +29 -0
- package/src/plugins/plugin.js +2 -0
- package/src/utils/backward-compatible-versions.js +2 -0
- package/src/utils/nx-devkit/ast-utils.d.ts +0 -8
- package/src/utils/nx-devkit/ast-utils.js +7 -12
- package/src/utils/versions.d.ts +7 -6
- package/src/utils/versions.js +8 -7
- package/fesm2022/nx-angular-testing.mjs +0 -45
- package/fesm2022/nx-angular-testing.mjs.map +0 -1
- package/src/migrations/update-16-0-0/remove-karma-defaults.d.ts +0 -2
- package/src/migrations/update-16-0-0/remove-karma-defaults.js +0 -52
- package/src/migrations/update-16-0-0/remove-library-generator-simple-module-name-option.d.ts +0 -2
- package/src/migrations/update-16-0-0/remove-library-generator-simple-module-name-option.js +0 -40
- package/src/migrations/update-16-0-0/remove-protractor-defaults.d.ts +0 -2
- package/src/migrations/update-16-0-0/remove-protractor-defaults.js +0 -52
- 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-1-0/extract-standalone-config-from-bootstrap.d.ts +0 -2
- package/src/migrations/update-16-1-0/extract-standalone-config-from-bootstrap.js +0 -127
- package/src/migrations/update-16-1-0/remove-ngcc-invocation.js +0 -22
- package/src/migrations/update-16-1-0/remove-render-module-platform-server-exports.d.ts +0 -2
- package/src/migrations/update-16-1-0/remove-render-module-platform-server-exports.js +0 -62
- package/src/migrations/update-16-1-0/update-server-executor-config.d.ts +0 -2
- package/src/migrations/update-16-1-0/update-server-executor-config.js +0 -26
- package/src/runtime/nx/data-persistence.d.ts +0 -276
- package/testing/index.d.ts +0 -1
- package/testing/ng-package.json +0 -6
- package/testing/src/testing-utils.d.ts +0 -33
@@ -6,13 +6,18 @@ const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-projec
|
|
6
6
|
const js_1 = require("@nx/js");
|
7
7
|
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
|
8
8
|
const init_1 = require("../init/init");
|
9
|
+
const convert_to_rspack_1 = require("../convert-to-rspack/convert-to-rspack");
|
9
10
|
const setup_ssr_1 = require("../setup-ssr/setup-ssr");
|
10
11
|
const setup_tailwind_1 = require("../setup-tailwind/setup-tailwind");
|
11
12
|
const ensure_angular_dependencies_1 = require("../utils/ensure-angular-dependencies");
|
12
13
|
const lib_1 = require("./lib");
|
13
14
|
async function applicationGenerator(tree, schema) {
|
14
15
|
(0, ts_solution_setup_1.assertNotUsingTsSolutionSetup)(tree, 'angular', 'application');
|
15
|
-
const
|
16
|
+
const isRspack = schema.bundler === 'rspack';
|
17
|
+
if (isRspack) {
|
18
|
+
schema.bundler = 'webpack';
|
19
|
+
}
|
20
|
+
const options = await (0, lib_1.normalizeOptions)(tree, schema, isRspack);
|
16
21
|
const rootOffset = (0, devkit_1.offsetFromRoot)(options.appProjectRoot);
|
17
22
|
await (0, js_1.initGenerator)(tree, {
|
18
23
|
...options,
|
@@ -23,6 +28,7 @@ async function applicationGenerator(tree, schema) {
|
|
23
28
|
await (0, init_1.angularInitGenerator)(tree, {
|
24
29
|
...options,
|
25
30
|
skipFormat: true,
|
31
|
+
addPlugin: options.addPlugin,
|
26
32
|
});
|
27
33
|
if (!options.skipPackageJson) {
|
28
34
|
(0, ensure_angular_dependencies_1.ensureAngularDependencies)(tree);
|
@@ -64,6 +70,19 @@ async function applicationGenerator(tree, schema) {
|
|
64
70
|
serverRouting: options.serverRouting,
|
65
71
|
});
|
66
72
|
}
|
73
|
+
if (isRspack) {
|
74
|
+
await (0, convert_to_rspack_1.convertToRspack)(tree, {
|
75
|
+
project: options.name,
|
76
|
+
skipInstall: options.skipPackageJson,
|
77
|
+
skipFormat: true,
|
78
|
+
});
|
79
|
+
if (options.ssr) {
|
80
|
+
(0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, './files/rspack-ssr'), options.appProjectSourceRoot, {
|
81
|
+
pathToDistFolder: (0, devkit_1.joinPathFragments)((0, devkit_1.offsetFromRoot)(options.appProjectRoot), options.outputPath, 'browser'),
|
82
|
+
tmpl: '',
|
83
|
+
});
|
84
|
+
}
|
85
|
+
}
|
67
86
|
if (!options.skipFormat) {
|
68
87
|
await (0, devkit_1.formatFiles)(tree);
|
69
88
|
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import 'zone.js/node';
|
2
|
+
|
3
|
+
import { APP_BASE_HREF } from '@angular/common';
|
4
|
+
import { CommonEngine } from '@angular/ssr/node';
|
5
|
+
import * as express from 'express';
|
6
|
+
import { existsSync } from 'node:fs';
|
7
|
+
import { join } from 'node:path';
|
8
|
+
import bootstrap from './main.server';
|
9
|
+
|
10
|
+
// The Express app is exported so that it can be used by serverless Functions.
|
11
|
+
export function app(): express.Express {
|
12
|
+
const server = express();
|
13
|
+
const distFolder = join(process.cwd(), "<%= pathToDistFolder %>");
|
14
|
+
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
|
15
|
+
? join(distFolder, 'index.original.html')
|
16
|
+
: join(distFolder, 'index.html');
|
17
|
+
|
18
|
+
const commonEngine = new CommonEngine();
|
19
|
+
|
20
|
+
server.set('view engine', 'html');
|
21
|
+
server.set('views', distFolder);
|
22
|
+
|
23
|
+
// Example Express Rest API endpoints
|
24
|
+
// server.get('/api/**', (req, res) => { });
|
25
|
+
// Serve static files from /browser
|
26
|
+
server.get(
|
27
|
+
'*.*',
|
28
|
+
express.static(distFolder, {
|
29
|
+
maxAge: '1y',
|
30
|
+
})
|
31
|
+
);
|
32
|
+
|
33
|
+
// All regular routes use the Angular engine
|
34
|
+
server.get('*', (req, res, next) => {
|
35
|
+
const { protocol, originalUrl, baseUrl, headers } = req;
|
36
|
+
|
37
|
+
commonEngine
|
38
|
+
.render({
|
39
|
+
bootstrap,
|
40
|
+
documentFilePath: indexHtml,
|
41
|
+
url: `${protocol}://${headers.host}${originalUrl}`,
|
42
|
+
publicPath: distFolder,
|
43
|
+
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
|
44
|
+
})
|
45
|
+
.then((html) => res.send(html))
|
46
|
+
.catch((err) => next(err));
|
47
|
+
});
|
48
|
+
|
49
|
+
return server;
|
50
|
+
}
|
51
|
+
|
52
|
+
function run(): void {
|
53
|
+
const port = process.env['PORT'] || 4000;
|
54
|
+
|
55
|
+
// Start up the Node server
|
56
|
+
const server = app();
|
57
|
+
server.listen(port, () => {
|
58
|
+
console.log(`Node Express server listening on http://localhost:${port}`);
|
59
|
+
});
|
60
|
+
}
|
61
|
+
|
62
|
+
// Webpack will replace 'require' with '__webpack_require__'
|
63
|
+
// '__non_webpack_require__' is a proxy to Node 'require'
|
64
|
+
// The below code is to ensure that the server is run only when not requiring the bundle.
|
65
|
+
declare const __non_webpack_require__: NodeRequire;
|
66
|
+
const mainModule = __non_webpack_require__.main;
|
67
|
+
const moduleFilename = (mainModule && mainModule.filename) || '';
|
68
|
+
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
|
69
|
+
run();
|
70
|
+
}
|
71
|
+
|
72
|
+
export default bootstrap;
|
@@ -3,12 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.addE2e = addE2e;
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
5
5
|
const versions_1 = require("../../../utils/versions");
|
6
|
-
const target_defaults_utils_1 = require("@nx/devkit/src/generators/target-defaults-utils");
|
7
6
|
async function addE2e(tree, options) {
|
8
7
|
// since e2e are separate projects, default to adding plugins
|
9
8
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
10
|
-
const addPlugin =
|
11
|
-
|
9
|
+
const addPlugin = nxJson['useInferencePlugins'] !== false &&
|
10
|
+
process.env.NX_ADD_PLUGINS !== 'false';
|
12
11
|
const e2eWebServerInfo = getAngularE2EWebServerInfo(tree, options.name, options.port);
|
13
12
|
if (options.e2eTestRunner === 'cypress') {
|
14
13
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/cypress', versions_1.nxVersion);
|
@@ -37,9 +36,6 @@ async function addE2e(tree, options) {
|
|
37
36
|
rootProject: options.rootProject,
|
38
37
|
addPlugin,
|
39
38
|
});
|
40
|
-
if (addPlugin) {
|
41
|
-
await (0, target_defaults_utils_1.addE2eCiTargetDefaults)(tree, '@nx/cypress/plugin', '^build', (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'cypress.config.ts'));
|
42
|
-
}
|
43
39
|
}
|
44
40
|
else if (options.e2eTestRunner === 'playwright') {
|
45
41
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/playwright', versions_1.nxVersion);
|
@@ -63,9 +59,6 @@ async function addE2e(tree, options) {
|
|
63
59
|
rootProject: options.rootProject,
|
64
60
|
addPlugin,
|
65
61
|
});
|
66
|
-
if (addPlugin) {
|
67
|
-
await (0, target_defaults_utils_1.addE2eCiTargetDefaults)(tree, '@nx/playwright/plugin', '^build', (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'playwright.config.ts'));
|
68
|
-
}
|
69
62
|
}
|
70
63
|
return e2eWebServerInfo.e2ePort;
|
71
64
|
}
|
@@ -13,6 +13,7 @@ function addFileServerTarget(tree, options, targetName, e2ePort) {
|
|
13
13
|
const isUsingApplicationBuilder = options.bundler === 'esbuild';
|
14
14
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.name);
|
15
15
|
projectConfig.targets[targetName] = {
|
16
|
+
continuous: true,
|
16
17
|
executor: '@nx/web:file-server',
|
17
18
|
options: {
|
18
19
|
buildTarget: `${options.name}:build`,
|
@@ -12,6 +12,7 @@ async function addUnitTestRunner(host, options) {
|
|
12
12
|
projectRoot: options.appProjectRoot,
|
13
13
|
skipPackageJson: options.skipPackageJson,
|
14
14
|
strict: options.strict,
|
15
|
+
addPlugin: options.addPlugin,
|
15
16
|
});
|
16
17
|
break;
|
17
18
|
case test_runners_1.UnitTestRunner.Vitest:
|
@@ -20,6 +21,7 @@ async function addUnitTestRunner(host, options) {
|
|
20
21
|
projectRoot: options.appProjectRoot,
|
21
22
|
skipPackageJson: options.skipPackageJson,
|
22
23
|
strict: options.strict,
|
24
|
+
addPlugin: options.addPlugin,
|
23
25
|
});
|
24
26
|
break;
|
25
27
|
}
|
@@ -1,4 +1,4 @@
|
|
1
1
|
import { type Tree } from '@nx/devkit';
|
2
2
|
import type { Schema } from '../schema';
|
3
3
|
import type { NormalizedSchema } from './normalized-schema';
|
4
|
-
export declare function normalizeOptions(host: Tree, options: Partial<Schema
|
4
|
+
export declare function normalizeOptions(host: Tree, options: Partial<Schema>, isRspack?: boolean): Promise<NormalizedSchema>;
|
@@ -5,8 +5,13 @@ const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const project_name_and_root_utils_1 = require("@nx/devkit/src/generators/project-name-and-root-utils");
|
6
6
|
const eslint_1 = require("@nx/eslint");
|
7
7
|
const test_runners_1 = require("../../../utils/test-runners");
|
8
|
-
|
9
|
-
|
8
|
+
function arePluginsExplicitlyDisabled(host) {
|
9
|
+
const { useInferencePlugins } = (0, devkit_1.readNxJson)(host);
|
10
|
+
const addPluginEnvVar = process.env.NX_ADD_PLUGINS;
|
11
|
+
return useInferencePlugins === false || addPluginEnvVar === 'false';
|
12
|
+
}
|
13
|
+
async function normalizeOptions(host, options, isRspack) {
|
14
|
+
await (0, project_name_and_root_utils_1.ensureRootProjectName)(options, 'application');
|
10
15
|
const { projectName: appProjectName, projectRoot: appProjectRoot } = await (0, project_name_and_root_utils_1.determineProjectNameAndRootOptions)(host, {
|
11
16
|
name: options.name,
|
12
17
|
projectType: 'application',
|
@@ -20,8 +25,10 @@ async function normalizeOptions(host, options) {
|
|
20
25
|
? options.tags.split(',').map((s) => s.trim())
|
21
26
|
: [];
|
22
27
|
const bundler = options.bundler ?? 'esbuild';
|
28
|
+
const addPlugin = options.addPlugin ?? (!arePluginsExplicitlyDisabled(host) && isRspack);
|
23
29
|
// Set defaults and then overwrite with user options
|
24
30
|
return {
|
31
|
+
addPlugin,
|
25
32
|
style: 'css',
|
26
33
|
routing: true,
|
27
34
|
inlineStyle: false,
|
@@ -20,15 +20,15 @@ export interface Schema {
|
|
20
20
|
e2eTestRunner?: E2eTestRunner;
|
21
21
|
backendProject?: string;
|
22
22
|
strict?: boolean;
|
23
|
-
standaloneConfig?: boolean;
|
24
23
|
port?: number;
|
25
24
|
setParserOptionsProject?: boolean;
|
26
25
|
skipPackageJson?: boolean;
|
27
26
|
standalone?: boolean;
|
28
27
|
rootProject?: boolean;
|
29
28
|
minimal?: boolean;
|
30
|
-
bundler?: 'webpack' | 'esbuild';
|
29
|
+
bundler?: 'webpack' | 'esbuild' | 'rspack';
|
31
30
|
ssr?: boolean;
|
32
31
|
serverRouting?: boolean;
|
33
32
|
nxCloudToken?: string;
|
33
|
+
addPlugin?: boolean;
|
34
34
|
}
|
@@ -130,12 +130,6 @@
|
|
130
130
|
"description": "Create an application with stricter type checking and build optimization options.",
|
131
131
|
"default": true
|
132
132
|
},
|
133
|
-
"standaloneConfig": {
|
134
|
-
"description": "Split the project configuration into `<projectRoot>/project.json` rather than including it inside `workspace.json`.",
|
135
|
-
"type": "boolean",
|
136
|
-
"default": true,
|
137
|
-
"x-deprecated": "Nx only supports standaloneConfig"
|
138
|
-
},
|
139
133
|
"port": {
|
140
134
|
"type": "number",
|
141
135
|
"description": "The port at which the remote application should be served."
|
@@ -171,7 +165,7 @@
|
|
171
165
|
"bundler": {
|
172
166
|
"description": "Bundler to use to build the application.",
|
173
167
|
"type": "string",
|
174
|
-
"enum": ["esbuild", "webpack"],
|
168
|
+
"enum": ["esbuild", "rspack", "webpack"],
|
175
169
|
"default": "esbuild",
|
176
170
|
"x-prompt": "Which bundler do you want to use to build the application?",
|
177
171
|
"x-priority": "important"
|
@@ -6,7 +6,7 @@ const versions_1 = require("../../utils/versions");
|
|
6
6
|
const storybook_inputs_1 = require("../utils/storybook-ast/storybook-inputs");
|
7
7
|
async function componentTestGenerator(tree, options) {
|
8
8
|
(0, devkit_1.ensurePackage)('@nx/cypress', versions_1.nxVersion);
|
9
|
-
const { assertMinimumCypressVersion } = require('@nx/cypress/src/utils/
|
9
|
+
const { assertMinimumCypressVersion } = require('@nx/cypress/src/utils/versions');
|
10
10
|
assertMinimumCypressVersion(10);
|
11
11
|
const { root } = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
12
12
|
const componentDirPath = (0, devkit_1.joinPathFragments)(root, options.componentDir);
|
@@ -0,0 +1,314 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.convertToRspack = convertToRspack;
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
5
|
+
const versions_1 = require("../../utils/versions");
|
6
|
+
const create_config_1 = require("./lib/create-config");
|
7
|
+
const get_custom_webpack_config_1 = require("./lib/get-custom-webpack-config");
|
8
|
+
const update_tsconfig_1 = require("./lib/update-tsconfig");
|
9
|
+
const validate_supported_executor_1 = require("./lib/validate-supported-executor");
|
10
|
+
const posix_1 = require("path/posix");
|
11
|
+
const path_1 = require("path");
|
12
|
+
const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
|
13
|
+
const enquirer_1 = require("enquirer");
|
14
|
+
const SUPPORTED_EXECUTORS = [
|
15
|
+
'@angular-devkit/build-angular:browser',
|
16
|
+
'@angular-devkit/build-angular:dev-server',
|
17
|
+
'@angular-devkit/build-angular:server',
|
18
|
+
'@nx/angular:webpack-browser',
|
19
|
+
'@nx/angular:webpack-server',
|
20
|
+
'@nx/angular:dev-server',
|
21
|
+
'@nx/angular:module-federation-dev-server',
|
22
|
+
];
|
23
|
+
const RENAMED_OPTIONS = {
|
24
|
+
main: 'browser',
|
25
|
+
ngswConfigPath: 'serviceWorker',
|
26
|
+
};
|
27
|
+
const REMOVED_OPTIONS = ['buildOptimizer', 'buildTarget', 'browserTarget'];
|
28
|
+
function normalizeFromProjectRoot(tree, path, projectRoot) {
|
29
|
+
if (projectRoot === '.') {
|
30
|
+
if (!path.startsWith('./')) {
|
31
|
+
return `./${path}`;
|
32
|
+
}
|
33
|
+
else {
|
34
|
+
return path;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
else if (path.startsWith(projectRoot)) {
|
38
|
+
return path.replace(projectRoot, '.');
|
39
|
+
}
|
40
|
+
else if (!path.startsWith('./')) {
|
41
|
+
if (tree.exists(path)) {
|
42
|
+
const pathWithWorkspaceRoot = (0, devkit_1.joinPathFragments)(devkit_1.workspaceRoot, path);
|
43
|
+
const projectRootWithWorkspaceRoot = (0, devkit_1.joinPathFragments)(devkit_1.workspaceRoot, projectRoot);
|
44
|
+
return (0, path_1.relative)(projectRootWithWorkspaceRoot, pathWithWorkspaceRoot);
|
45
|
+
}
|
46
|
+
return `./${path}`;
|
47
|
+
}
|
48
|
+
return path;
|
49
|
+
}
|
50
|
+
const defaultNormalizer = (tree, path, root) => normalizeFromProjectRoot(tree, path, root);
|
51
|
+
const PATH_NORMALIZER = {
|
52
|
+
index: (tree, path, root) => {
|
53
|
+
if (typeof path === 'string') {
|
54
|
+
return normalizeFromProjectRoot(tree, path, root);
|
55
|
+
}
|
56
|
+
return {
|
57
|
+
input: normalizeFromProjectRoot(tree, path.input, root),
|
58
|
+
output: path.output ?? 'index.html',
|
59
|
+
};
|
60
|
+
},
|
61
|
+
indexHtmlTransformer: defaultNormalizer,
|
62
|
+
main: defaultNormalizer,
|
63
|
+
server: defaultNormalizer,
|
64
|
+
tsConfig: defaultNormalizer,
|
65
|
+
outputPath: (tree, path, root) => {
|
66
|
+
const relativePathFromWorkspaceRoot = (0, path_1.relative)((0, devkit_1.joinPathFragments)(devkit_1.workspaceRoot, root), devkit_1.workspaceRoot);
|
67
|
+
return (0, devkit_1.joinPathFragments)(relativePathFromWorkspaceRoot, path);
|
68
|
+
},
|
69
|
+
proxyConfig: defaultNormalizer,
|
70
|
+
polyfills: (tree, paths, root) => {
|
71
|
+
const normalizedPaths = [];
|
72
|
+
const normalizeFn = (path) => {
|
73
|
+
try {
|
74
|
+
const resolvedPath = require.resolve(path, {
|
75
|
+
paths: [(0, posix_1.join)(devkit_1.workspaceRoot, 'node_modules')],
|
76
|
+
});
|
77
|
+
normalizedPaths.push(path);
|
78
|
+
}
|
79
|
+
catch {
|
80
|
+
normalizedPaths.push(normalizeFromProjectRoot(tree, path, root));
|
81
|
+
}
|
82
|
+
};
|
83
|
+
if (typeof paths === 'string') {
|
84
|
+
normalizeFn(paths);
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
for (const path of paths) {
|
88
|
+
normalizeFn(path);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
return normalizedPaths;
|
92
|
+
},
|
93
|
+
styles: (tree, paths, root) => {
|
94
|
+
const normalizedPaths = [];
|
95
|
+
for (const path of paths) {
|
96
|
+
if (typeof path === 'string') {
|
97
|
+
normalizedPaths.push(normalizeFromProjectRoot(tree, path, root));
|
98
|
+
}
|
99
|
+
else {
|
100
|
+
normalizedPaths.push({
|
101
|
+
input: normalizeFromProjectRoot(tree, path.input, root),
|
102
|
+
bundleName: path.bundleName,
|
103
|
+
inject: path.inject ?? true,
|
104
|
+
});
|
105
|
+
}
|
106
|
+
}
|
107
|
+
return normalizedPaths;
|
108
|
+
},
|
109
|
+
scripts: (tree, paths, root) => {
|
110
|
+
const normalizedPaths = [];
|
111
|
+
for (const path of paths) {
|
112
|
+
if (typeof path === 'string') {
|
113
|
+
normalizedPaths.push(normalizeFromProjectRoot(tree, path, root));
|
114
|
+
}
|
115
|
+
else {
|
116
|
+
normalizedPaths.push({
|
117
|
+
input: normalizeFromProjectRoot(tree, path.input, root),
|
118
|
+
bundleName: path.bundleName,
|
119
|
+
inject: path.inject ?? true,
|
120
|
+
});
|
121
|
+
}
|
122
|
+
}
|
123
|
+
return normalizedPaths;
|
124
|
+
},
|
125
|
+
assets: (tree, paths, root) => {
|
126
|
+
const normalizedPaths = [];
|
127
|
+
for (const path of paths) {
|
128
|
+
if (typeof path === 'string') {
|
129
|
+
normalizedPaths.push(normalizeFromProjectRoot(tree, path, root));
|
130
|
+
}
|
131
|
+
else {
|
132
|
+
normalizedPaths.push({
|
133
|
+
...path,
|
134
|
+
input: normalizeFromProjectRoot(tree, path.input, root),
|
135
|
+
});
|
136
|
+
}
|
137
|
+
}
|
138
|
+
return normalizedPaths;
|
139
|
+
},
|
140
|
+
fileReplacements: (tree, paths, root) => {
|
141
|
+
const normalizedPaths = [];
|
142
|
+
for (const path of paths) {
|
143
|
+
normalizedPaths.push({
|
144
|
+
replace: normalizeFromProjectRoot(tree, 'src' in path ? path.src : path.replace, root),
|
145
|
+
with: normalizeFromProjectRoot(tree, 'replaceWith' in path ? path.replaceWith : path.with, root),
|
146
|
+
});
|
147
|
+
}
|
148
|
+
return normalizedPaths;
|
149
|
+
},
|
150
|
+
};
|
151
|
+
function handleBuildTargetOptions(tree, options, newConfigurationOptions, root) {
|
152
|
+
let customWebpackConfigPath;
|
153
|
+
if (!options || Object.keys(options).length === 0) {
|
154
|
+
return customWebpackConfigPath;
|
155
|
+
}
|
156
|
+
if (options.customWebpackConfig) {
|
157
|
+
customWebpackConfigPath = options.customWebpackConfig.path;
|
158
|
+
delete options.customWebpackConfig;
|
159
|
+
}
|
160
|
+
if (options.outputs) {
|
161
|
+
// handled by the Rspack inference plugin
|
162
|
+
delete options.outputs;
|
163
|
+
}
|
164
|
+
for (const [key, value] of Object.entries(options)) {
|
165
|
+
let optionName = key;
|
166
|
+
let optionValue = key in PATH_NORMALIZER ? PATH_NORMALIZER[key](tree, value, root) : value;
|
167
|
+
if (REMOVED_OPTIONS.includes(key)) {
|
168
|
+
continue;
|
169
|
+
}
|
170
|
+
if (key in RENAMED_OPTIONS) {
|
171
|
+
optionName = RENAMED_OPTIONS[key];
|
172
|
+
}
|
173
|
+
newConfigurationOptions[optionName] = optionValue;
|
174
|
+
}
|
175
|
+
if (typeof newConfigurationOptions.polyfills === 'string') {
|
176
|
+
newConfigurationOptions.polyfills = [newConfigurationOptions.polyfills];
|
177
|
+
}
|
178
|
+
let outputPath = newConfigurationOptions.outputPath;
|
179
|
+
if (typeof outputPath === 'string') {
|
180
|
+
if (!/\/browser\/?$/.test(outputPath)) {
|
181
|
+
console.warn(`The output location of the browser build has been updated from "${outputPath}" to ` +
|
182
|
+
`"${(0, posix_1.join)(outputPath, 'browser')}". ` +
|
183
|
+
'You might need to adjust your deployment pipeline or, as an alternative, ' +
|
184
|
+
'set outputPath.browser to "" in order to maintain the previous functionality.');
|
185
|
+
}
|
186
|
+
else {
|
187
|
+
outputPath = outputPath.replace(/\/browser\/?$/, '');
|
188
|
+
}
|
189
|
+
newConfigurationOptions['outputPath'] = {
|
190
|
+
base: outputPath,
|
191
|
+
};
|
192
|
+
if (typeof newConfigurationOptions.resourcesOutputPath === 'string') {
|
193
|
+
const media = newConfigurationOptions.resourcesOutputPath.replaceAll('/', '');
|
194
|
+
if (media && media !== 'media') {
|
195
|
+
newConfigurationOptions['outputPath'] = {
|
196
|
+
base: outputPath,
|
197
|
+
media,
|
198
|
+
};
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
return customWebpackConfigPath;
|
203
|
+
}
|
204
|
+
function handleDevServerTargetOptions(tree, options, newConfigurationOptions, root) {
|
205
|
+
for (const [key, value] of Object.entries(options)) {
|
206
|
+
let optionName = key;
|
207
|
+
let optionValue = key in PATH_NORMALIZER ? PATH_NORMALIZER[key](tree, value, root) : value;
|
208
|
+
if (REMOVED_OPTIONS.includes(key)) {
|
209
|
+
continue;
|
210
|
+
}
|
211
|
+
if (key in RENAMED_OPTIONS) {
|
212
|
+
optionName = RENAMED_OPTIONS[key];
|
213
|
+
}
|
214
|
+
newConfigurationOptions[optionName] = optionValue;
|
215
|
+
}
|
216
|
+
}
|
217
|
+
async function getProjectToConvert(tree) {
|
218
|
+
const projects = new Set();
|
219
|
+
for (const executor of SUPPORTED_EXECUTORS) {
|
220
|
+
(0, executor_options_utils_1.forEachExecutorOptions)(tree, executor, (_, project) => {
|
221
|
+
projects.add(project);
|
222
|
+
});
|
223
|
+
}
|
224
|
+
const { project } = await (0, enquirer_1.prompt)({
|
225
|
+
type: 'select',
|
226
|
+
name: 'project',
|
227
|
+
message: 'Which project would you like to convert to rspack?',
|
228
|
+
choices: Array.from(projects),
|
229
|
+
});
|
230
|
+
return project;
|
231
|
+
}
|
232
|
+
async function convertToRspack(tree, schema) {
|
233
|
+
let { project: projectName } = schema;
|
234
|
+
if (!projectName) {
|
235
|
+
projectName = await getProjectToConvert(tree);
|
236
|
+
}
|
237
|
+
const project = (0, devkit_1.readProjectConfiguration)(tree, projectName);
|
238
|
+
const tasks = [];
|
239
|
+
const createConfigOptions = {
|
240
|
+
root: project.root,
|
241
|
+
};
|
242
|
+
const configurationOptions = {};
|
243
|
+
const buildTargetNames = [];
|
244
|
+
const serveTargetNames = [];
|
245
|
+
let customWebpackConfigPath;
|
246
|
+
(0, validate_supported_executor_1.validateSupportedBuildExecutor)(Object.values(project.targets));
|
247
|
+
for (const [targetName, target] of Object.entries(project.targets)) {
|
248
|
+
if (target.executor === '@angular-devkit/build-angular:browser' ||
|
249
|
+
target.executor === '@nx/angular:webpack-browser') {
|
250
|
+
customWebpackConfigPath = handleBuildTargetOptions(tree, target.options, createConfigOptions, project.root);
|
251
|
+
if (target.configurations) {
|
252
|
+
for (const [configurationName, configuration] of Object.entries(target.configurations)) {
|
253
|
+
configurationOptions[configurationName] = {};
|
254
|
+
handleBuildTargetOptions(tree, configuration, configurationOptions[configurationName], project.root);
|
255
|
+
}
|
256
|
+
}
|
257
|
+
buildTargetNames.push(targetName);
|
258
|
+
}
|
259
|
+
else if (target.executor === '@angular-devkit/build-angular:server' ||
|
260
|
+
target.executor === '@nx/angular:webpack-server') {
|
261
|
+
createConfigOptions.ssr ??= {};
|
262
|
+
createConfigOptions.ssr.entry ??= normalizeFromProjectRoot(tree, target.options.main, project.root);
|
263
|
+
createConfigOptions.server = './src/main.server.ts';
|
264
|
+
buildTargetNames.push(targetName);
|
265
|
+
}
|
266
|
+
else if (target.executor === '@angular-devkit/build-angular:dev-server' ||
|
267
|
+
target.executor === '@nx/angular:dev-server' ||
|
268
|
+
target.executor === '@nx/angular:module-federation-dev-server') {
|
269
|
+
createConfigOptions.devServer = {};
|
270
|
+
if (target.options) {
|
271
|
+
handleDevServerTargetOptions(tree, target.options, createConfigOptions.devServer, project.root);
|
272
|
+
}
|
273
|
+
if (target.configurations) {
|
274
|
+
for (const [configurationName, configuration] of Object.entries(target.configurations)) {
|
275
|
+
configurationOptions[configurationName] ??= {};
|
276
|
+
configurationOptions[configurationName].devServer ??= {};
|
277
|
+
handleDevServerTargetOptions(tree, configuration, configurationOptions[configurationName].devServer, project.root);
|
278
|
+
}
|
279
|
+
}
|
280
|
+
serveTargetNames.push(targetName);
|
281
|
+
}
|
282
|
+
}
|
283
|
+
const customWebpackConfigInfo = customWebpackConfigPath
|
284
|
+
? await (0, get_custom_webpack_config_1.getCustomWebpackConfig)(tree, project.root, customWebpackConfigPath)
|
285
|
+
: undefined;
|
286
|
+
(0, create_config_1.createConfig)(tree, createConfigOptions, configurationOptions, customWebpackConfigInfo?.normalizedPathToCustomWebpackConfig, customWebpackConfigInfo?.isWebpackConfigFunction);
|
287
|
+
(0, update_tsconfig_1.updateTsconfig)(tree, project.root);
|
288
|
+
for (const targetName of [...buildTargetNames, ...serveTargetNames]) {
|
289
|
+
delete project.targets[targetName];
|
290
|
+
}
|
291
|
+
(0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
|
292
|
+
const { rspackInitGenerator } = (0, devkit_1.ensurePackage)('@nx/rspack', versions_1.nxVersion);
|
293
|
+
await rspackInitGenerator(tree, {
|
294
|
+
addPlugin: true,
|
295
|
+
});
|
296
|
+
// This is needed to prevent a circular execution of the build target
|
297
|
+
const rootPkgJson = (0, devkit_1.readJson)(tree, 'package.json');
|
298
|
+
if (rootPkgJson.scripts?.build === 'nx build') {
|
299
|
+
delete rootPkgJson.scripts.build;
|
300
|
+
(0, devkit_1.writeJson)(tree, 'package.json', rootPkgJson);
|
301
|
+
}
|
302
|
+
if (!schema.skipInstall) {
|
303
|
+
const installTask = (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
304
|
+
'@nx/angular-rspack': versions_1.angularRspackVersion,
|
305
|
+
'ts-node': versions_1.tsNodeVersion,
|
306
|
+
});
|
307
|
+
tasks.push(installTask);
|
308
|
+
}
|
309
|
+
if (!schema.skipFormat) {
|
310
|
+
await (0, devkit_1.formatFiles)(tree);
|
311
|
+
}
|
312
|
+
return (0, devkit_1.runTasksInSerial)(...tasks);
|
313
|
+
}
|
314
|
+
exports.default = convertToRspack;
|
@@ -0,0 +1,48 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.createConfig = createConfig;
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
5
|
+
function createConfig(tree, opts, configurationOptions = {}, existingWebpackConfigPath, isExistingWebpackConfigFunction) {
|
6
|
+
const { root, ...createConfigOptions } = opts;
|
7
|
+
const hasConfigurations = Object.keys(configurationOptions).length > 0;
|
8
|
+
const expandedConfigurationOptions = hasConfigurations
|
9
|
+
? Object.entries(configurationOptions)
|
10
|
+
.map(([configurationName, configurationOptions]) => {
|
11
|
+
return `
|
12
|
+
${configurationName}: {
|
13
|
+
options: {
|
14
|
+
${JSON.stringify(configurationOptions, undefined, 2).slice(1, -1)}
|
15
|
+
}
|
16
|
+
}`;
|
17
|
+
})
|
18
|
+
.join(',\n')
|
19
|
+
: '';
|
20
|
+
const configContents = `
|
21
|
+
import { createConfig }from '@nx/angular-rspack';
|
22
|
+
${existingWebpackConfigPath
|
23
|
+
? `import baseWebpackConfig from '${existingWebpackConfigPath}';
|
24
|
+
${isExistingWebpackConfigFunction
|
25
|
+
? ''
|
26
|
+
: `import webpackMerge from 'webpack-merge';`}`
|
27
|
+
: ''}
|
28
|
+
|
29
|
+
${existingWebpackConfigPath ? 'const baseConfig = ' : 'export default '}createConfig({
|
30
|
+
options: {
|
31
|
+
root: __dirname,
|
32
|
+
${JSON.stringify(createConfigOptions, undefined, 2).slice(1, -1)}
|
33
|
+
}
|
34
|
+
}${hasConfigurations ? `, {${expandedConfigurationOptions}}` : ''});
|
35
|
+
${existingWebpackConfigPath
|
36
|
+
? `
|
37
|
+
export default ${isExistingWebpackConfigFunction
|
38
|
+
? `async function (env, argv) {
|
39
|
+
const oldConfig = await baseWebpackConfig;
|
40
|
+
const browserConfig = baseConfig[0];
|
41
|
+
return oldConfig(browserConfig);
|
42
|
+
}`
|
43
|
+
: 'webpackMerge(baseConfig[0], baseWebpackConfig);'}
|
44
|
+
`
|
45
|
+
: ''}
|
46
|
+
`;
|
47
|
+
tree.write((0, devkit_1.joinPathFragments)(root, 'rspack.config.ts'), configContents);
|
48
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { Tree } from '@nx/devkit';
|
2
|
+
export declare function getCustomWebpackConfig(tree: Tree, projectRoot: string, pathToCustomWebpackConfig: string): Promise<{
|
3
|
+
isWebpackConfigFunction: boolean;
|
4
|
+
normalizedPathToCustomWebpackConfig: string;
|
5
|
+
}>;
|
6
|
+
export declare function convertWebpackConfigToUseNxModuleFederationPlugin(webpackConfigContents: string): string;
|