@nx/rspack 21.2.0-beta.1 → 21.2.0-beta.2
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/README.md +1 -1
- package/generators.json +2 -1
- package/package.json +5 -5
- package/src/generators/application/application.js +54 -0
- package/src/generators/application/schema.json +1 -0
- package/src/plugins/utils/apply-base-config.js +36 -49
- package/src/plugins/utils/get-non-buildable-libs.d.ts +10 -0
- package/src/plugins/utils/get-non-buildable-libs.js +38 -0
- package/src/plugins/utils/get-transitive-deps.d.ts +10 -0
- package/src/plugins/utils/get-transitive-deps.js +44 -0
- package/src/utils/generator-utils.js +10 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
# Nx: Smart Repos · Fast Builds
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
An AI-first build platform that connects everything from your editor to CI. Helping you deliver fast, without breaking things.
|
|
26
26
|
|
|
27
27
|
This package is a [Rspack plugin for Nx](https://nx.dev/nx-api/rspack).
|
|
28
28
|
|
package/generators.json
CHANGED
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"schema": "./src/generators/application/schema.json",
|
|
26
26
|
"aliases": ["app"],
|
|
27
27
|
"x-type": "application",
|
|
28
|
-
"description": "React application generator."
|
|
28
|
+
"description": "React application generator.",
|
|
29
|
+
"x-deprecated": "This generator will be removed in Nx 22. Please use the equivalent generator for your application type instead."
|
|
29
30
|
},
|
|
30
31
|
"convert-webpack": {
|
|
31
32
|
"alias": "convert-to-rspack",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/rspack",
|
|
3
3
|
"description": "The Nx Plugin for Rspack contains executors and generators that support building applications using Rspack.",
|
|
4
|
-
"version": "21.2.0-beta.
|
|
4
|
+
"version": "21.2.0-beta.2",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"generators": "./generators.json",
|
|
25
25
|
"executors": "./executors.json",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@nx/js": "21.2.0-beta.
|
|
28
|
-
"@nx/devkit": "21.2.0-beta.
|
|
29
|
-
"@nx/web": "21.2.0-beta.
|
|
30
|
-
"@nx/module-federation": "21.2.0-beta.
|
|
27
|
+
"@nx/js": "21.2.0-beta.2",
|
|
28
|
+
"@nx/devkit": "21.2.0-beta.2",
|
|
29
|
+
"@nx/web": "21.2.0-beta.2",
|
|
30
|
+
"@nx/module-federation": "21.2.0-beta.2",
|
|
31
31
|
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
32
32
|
"@rspack/core": "^1.3.8",
|
|
33
33
|
"@rspack/dev-server": "^1.1.1",
|
|
@@ -7,13 +7,65 @@ const package_json_1 = require("nx/package.json");
|
|
|
7
7
|
const configuration_1 = tslib_1.__importDefault(require("../configuration/configuration"));
|
|
8
8
|
const init_1 = tslib_1.__importDefault(require("../init/init"));
|
|
9
9
|
const normalize_options_1 = require("./lib/normalize-options");
|
|
10
|
+
/**
|
|
11
|
+
* Updates the exclude field for any @nx/rspack/plugin registrations in nx.json
|
|
12
|
+
*/
|
|
13
|
+
function updateRspackPluginExclusion(tree, options) {
|
|
14
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
15
|
+
if (!nxJson.plugins?.length) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
let updated = false;
|
|
19
|
+
// Loop through all plugins to find @nx/rspack/plugin registrations
|
|
20
|
+
for (let i = 0; i < nxJson.plugins.length; i++) {
|
|
21
|
+
const plugin = nxJson.plugins[i];
|
|
22
|
+
const isRspackPlugin = typeof plugin === 'string'
|
|
23
|
+
? plugin === '@nx/rspack/plugin'
|
|
24
|
+
: plugin.plugin === '@nx/rspack/plugin';
|
|
25
|
+
if (!isRspackPlugin) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (typeof plugin === 'string') {
|
|
29
|
+
// Convert string notation to object notation with exclude field
|
|
30
|
+
nxJson.plugins[i] = {
|
|
31
|
+
plugin: '@nx/rspack/plugin',
|
|
32
|
+
exclude: [`${options.appProjectRoot}/**`],
|
|
33
|
+
};
|
|
34
|
+
updated = true;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Object notation
|
|
38
|
+
if (!plugin.exclude) {
|
|
39
|
+
// Add exclude field if it doesn't exist
|
|
40
|
+
plugin.exclude = [`${options.appProjectRoot}/**`];
|
|
41
|
+
updated = true;
|
|
42
|
+
}
|
|
43
|
+
else if (Array.isArray(plugin.exclude)) {
|
|
44
|
+
// Add to existing exclude field if it's an array
|
|
45
|
+
plugin.exclude.push(`${options.appProjectRoot}/**`);
|
|
46
|
+
updated = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (updated) {
|
|
51
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// TODO(v22) - remove this generator
|
|
10
55
|
async function default_1(tree, _options) {
|
|
56
|
+
// Add deprecation warning with alternatives based on framework
|
|
57
|
+
const framework = _options.framework || 'react'; // Default is react
|
|
58
|
+
devkit_1.logger.warn(`The @nx/rspack:application generator is deprecated and will be removed in Nx 22. ` +
|
|
59
|
+
`Please use @nx/${framework === 'nest' ? 'nest' : framework === 'web' ? 'web' : 'react'}:application instead.`);
|
|
11
60
|
const tasks = [];
|
|
12
61
|
const initTask = await (0, init_1.default)(tree, {
|
|
13
62
|
..._options,
|
|
14
63
|
});
|
|
15
64
|
tasks.push(initTask);
|
|
16
65
|
const options = await (0, normalize_options_1.normalizeOptions)(tree, _options);
|
|
66
|
+
if (framework === 'nest') {
|
|
67
|
+
updateRspackPluginExclusion(tree, options);
|
|
68
|
+
}
|
|
17
69
|
options.style ??= 'css';
|
|
18
70
|
if (options.framework === 'nest') {
|
|
19
71
|
const { applicationGenerator: nestAppGenerator } = (0, devkit_1.ensurePackage)('@nx/nest', package_json_1.version);
|
|
@@ -29,6 +81,7 @@ async function default_1(tree, _options) {
|
|
|
29
81
|
newProject: false,
|
|
30
82
|
buildTarget: 'build',
|
|
31
83
|
framework: 'nest',
|
|
84
|
+
addPlugin: false,
|
|
32
85
|
});
|
|
33
86
|
tasks.push(createAppTask, convertAppTask);
|
|
34
87
|
}
|
|
@@ -79,6 +132,7 @@ async function default_1(tree, _options) {
|
|
|
79
132
|
buildTarget: 'build',
|
|
80
133
|
serveTarget: 'serve',
|
|
81
134
|
framework: 'react',
|
|
135
|
+
addPlugin: false,
|
|
82
136
|
});
|
|
83
137
|
tasks.push(createAppTask, convertAppTask);
|
|
84
138
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"title": "Application generator for React + rspack",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"description": "React + Rspack application generator.",
|
|
7
|
+
"x-deprecated": "This generator will be removed in Nx 22. Please use the equivalent generator for your application type instead.",
|
|
7
8
|
"examples": [
|
|
8
9
|
{
|
|
9
10
|
"command": "nx g app myorg/myapp",
|
|
@@ -13,7 +13,7 @@ const nx_tsconfig_paths_rspack_plugin_1 = require("./plugins/nx-tsconfig-paths-r
|
|
|
13
13
|
const get_terser_ecma_version_1 = require("./get-terser-ecma-version");
|
|
14
14
|
const nodeExternals = require("webpack-node-externals");
|
|
15
15
|
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
|
|
16
|
-
const
|
|
16
|
+
const get_non_buildable_libs_1 = require("./get-non-buildable-libs");
|
|
17
17
|
const IGNORED_RSPACK_WARNINGS = [
|
|
18
18
|
/The comment file/i,
|
|
19
19
|
/could not find any license/i,
|
|
@@ -105,39 +105,41 @@ function applyNxIndependentConfig(options, config) {
|
|
|
105
105
|
(x) => IGNORED_RSPACK_WARNINGS.some((r) => typeof x === 'string' ? r.test(x) : r.test(x.message)),
|
|
106
106
|
...(config.ignoreWarnings ?? []),
|
|
107
107
|
];
|
|
108
|
-
config.optimization =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
108
|
+
config.optimization = {
|
|
109
|
+
...(config.optimization ?? {}),
|
|
110
|
+
...(isProd
|
|
111
|
+
? {
|
|
112
|
+
sideEffects: true,
|
|
113
|
+
minimize: typeof options.optimization === 'object'
|
|
114
|
+
? !!options.optimization.scripts
|
|
115
|
+
: !!options.optimization,
|
|
116
|
+
minimizer: [
|
|
117
|
+
new core_1.SwcJsMinimizerRspackPlugin({
|
|
118
|
+
extractComments: false,
|
|
119
|
+
minimizerOptions: {
|
|
120
|
+
// this needs to be false to allow toplevel variables to be used in the global scope
|
|
121
|
+
// important especially for module-federation which operates as such
|
|
122
|
+
module: false,
|
|
123
|
+
mangle: {
|
|
124
|
+
keep_classnames: true,
|
|
125
|
+
},
|
|
126
|
+
format: {
|
|
127
|
+
ecma: (0, get_terser_ecma_version_1.getTerserEcmaVersion)(path.join(options.root, options.projectRoot)),
|
|
128
|
+
ascii_only: true,
|
|
129
|
+
comments: false,
|
|
130
|
+
webkit: true,
|
|
131
|
+
safari10: true,
|
|
132
|
+
},
|
|
132
133
|
},
|
|
133
|
-
},
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
}),
|
|
135
|
+
],
|
|
136
|
+
concatenateModules: true,
|
|
137
|
+
runtimeChunk: isDevServer
|
|
138
|
+
? config.optimization?.runtimeChunk ?? undefined
|
|
139
|
+
: false,
|
|
140
|
+
}
|
|
141
|
+
: {}),
|
|
142
|
+
};
|
|
141
143
|
config.stats = {
|
|
142
144
|
hash: true,
|
|
143
145
|
timings: false,
|
|
@@ -282,27 +284,12 @@ function applyNxDependentConfig(options, config, { useNormalizedEntry } = {}) {
|
|
|
282
284
|
const modulesDir = `${options.root}/node_modules`;
|
|
283
285
|
const graph = options.projectGraph;
|
|
284
286
|
const projectName = options.projectName;
|
|
285
|
-
const deps = graph?.dependencies?.[projectName] ?? [];
|
|
286
287
|
// Collect non-buildable TS project references so that they are bundled
|
|
287
288
|
// in the final output. This is needed for projects that are not buildable
|
|
288
289
|
// but are referenced by buildable projects. This is needed for the new TS
|
|
289
290
|
// solution setup.
|
|
290
291
|
const nonBuildableWorkspaceLibs = isUsingTsSolution
|
|
291
|
-
?
|
|
292
|
-
.filter((dep) => {
|
|
293
|
-
const node = graph.nodes?.[dep.target];
|
|
294
|
-
if (!node || node.type !== 'lib')
|
|
295
|
-
return false;
|
|
296
|
-
const hasBuildTarget = 'build' in (node.data?.targets ?? {});
|
|
297
|
-
if (hasBuildTarget) {
|
|
298
|
-
return false;
|
|
299
|
-
}
|
|
300
|
-
// If there is no build target we check the package exports to see if they reference
|
|
301
|
-
// source files
|
|
302
|
-
return !(0, is_lib_buildable_1.isBuildableLibrary)(node);
|
|
303
|
-
})
|
|
304
|
-
.map((dep) => graph.nodes?.[dep.target]?.data?.metadata?.js?.packageName)
|
|
305
|
-
.filter((name) => !!name)
|
|
292
|
+
? (0, get_non_buildable_libs_1.getNonBuildableLibs)(graph, projectName)
|
|
306
293
|
: [];
|
|
307
294
|
externals.push(nodeExternals({ modulesDir, allowlist: nonBuildableWorkspaceLibs }));
|
|
308
295
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ProjectGraph } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* Get all non-buildable libraries in the project graph for a given project.
|
|
4
|
+
* This function retrieves all direct and transitive dependencies of a project,
|
|
5
|
+
* filtering out only those that are libraries and not buildable.
|
|
6
|
+
* @param graph Project graph
|
|
7
|
+
* @param projectName The project name to get dependencies for
|
|
8
|
+
* @returns A list of all non-buildable libraries that the project depends on, including transitive dependencies.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getNonBuildableLibs(graph: ProjectGraph, projectName: string): string[];
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getNonBuildableLibs = getNonBuildableLibs;
|
|
4
|
+
const get_transitive_deps_1 = require("./get-transitive-deps");
|
|
5
|
+
const is_lib_buildable_1 = require("./is-lib-buildable");
|
|
6
|
+
/**
|
|
7
|
+
* Get all non-buildable libraries in the project graph for a given project.
|
|
8
|
+
* This function retrieves all direct and transitive dependencies of a project,
|
|
9
|
+
* filtering out only those that are libraries and not buildable.
|
|
10
|
+
* @param graph Project graph
|
|
11
|
+
* @param projectName The project name to get dependencies for
|
|
12
|
+
* @returns A list of all non-buildable libraries that the project depends on, including transitive dependencies.
|
|
13
|
+
*/
|
|
14
|
+
function getNonBuildableLibs(graph, projectName) {
|
|
15
|
+
const deps = graph?.dependencies?.[projectName] ?? [];
|
|
16
|
+
const allNonBuildable = new Set();
|
|
17
|
+
// First, find all direct non-buildable deps and add them App -> library
|
|
18
|
+
const directNonBuildable = deps.filter((dep) => {
|
|
19
|
+
const node = graph.nodes?.[dep.target];
|
|
20
|
+
if (!node || node.type !== 'lib')
|
|
21
|
+
return false;
|
|
22
|
+
const hasBuildTarget = 'build' in (node.data?.targets ?? {});
|
|
23
|
+
if (hasBuildTarget)
|
|
24
|
+
return false;
|
|
25
|
+
return !(0, is_lib_buildable_1.isBuildableLibrary)(node);
|
|
26
|
+
});
|
|
27
|
+
// Add direct non-buildable dependencies
|
|
28
|
+
for (const dep of directNonBuildable) {
|
|
29
|
+
const packageName = graph.nodes?.[dep.target]?.data?.metadata?.js?.packageName;
|
|
30
|
+
if (packageName) {
|
|
31
|
+
allNonBuildable.add(packageName);
|
|
32
|
+
}
|
|
33
|
+
// Get all transitive non-buildable dependencies App -> library1 -> library2
|
|
34
|
+
const transitiveDeps = (0, get_transitive_deps_1.getAllTransitiveDeps)(graph, dep.target);
|
|
35
|
+
transitiveDeps.forEach((pkg) => allNonBuildable.add(pkg));
|
|
36
|
+
}
|
|
37
|
+
return Array.from(allNonBuildable);
|
|
38
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ProjectGraph } from '@nx/devkit';
|
|
2
|
+
/**
|
|
3
|
+
* Get all transitive dependencies of a target that are non-buildable libraries.
|
|
4
|
+
* This function traverses the project graph to find all dependencies of a given target,
|
|
5
|
+
* @param graph Graph of the project
|
|
6
|
+
* @param targetName The project name to get dependencies for
|
|
7
|
+
* @param visited Set to keep track of visited nodes to prevent infinite loops in circular dependencies
|
|
8
|
+
* @returns string[] - List of all transitive dependencies that are non-buildable libraries
|
|
9
|
+
*/
|
|
10
|
+
export declare function getAllTransitiveDeps(graph: ProjectGraph, targetName: string, visited?: Set<string>): string[];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAllTransitiveDeps = getAllTransitiveDeps;
|
|
4
|
+
const is_lib_buildable_1 = require("./is-lib-buildable");
|
|
5
|
+
/**
|
|
6
|
+
* Get all transitive dependencies of a target that are non-buildable libraries.
|
|
7
|
+
* This function traverses the project graph to find all dependencies of a given target,
|
|
8
|
+
* @param graph Graph of the project
|
|
9
|
+
* @param targetName The project name to get dependencies for
|
|
10
|
+
* @param visited Set to keep track of visited nodes to prevent infinite loops in circular dependencies
|
|
11
|
+
* @returns string[] - List of all transitive dependencies that are non-buildable libraries
|
|
12
|
+
*/
|
|
13
|
+
function getAllTransitiveDeps(graph, targetName, visited = new Set()) {
|
|
14
|
+
if (visited.has(targetName)) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
visited.add(targetName);
|
|
18
|
+
const node = graph.nodes?.[targetName];
|
|
19
|
+
if (!node) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
// Get direct dependencies of this target
|
|
23
|
+
const directDeps = graph.dependencies?.[targetName] || [];
|
|
24
|
+
const transitiveDeps = [];
|
|
25
|
+
for (const dep of directDeps) {
|
|
26
|
+
const depNode = graph.nodes?.[dep.target];
|
|
27
|
+
// Only consider library dependencies
|
|
28
|
+
if (!depNode || depNode.type !== 'lib') {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// Check if this dependency is non-buildable
|
|
32
|
+
const hasBuildTarget = 'build' in (depNode.data?.targets ?? {});
|
|
33
|
+
const isBuildable = hasBuildTarget || (0, is_lib_buildable_1.isBuildableLibrary)(depNode);
|
|
34
|
+
if (!isBuildable) {
|
|
35
|
+
const packageName = depNode.data?.metadata?.js?.packageName;
|
|
36
|
+
if (packageName) {
|
|
37
|
+
transitiveDeps.push(packageName);
|
|
38
|
+
}
|
|
39
|
+
const nestedDeps = getAllTransitiveDeps(graph, dep.target, visited);
|
|
40
|
+
transitiveDeps.push(...nestedDeps);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return transitiveDeps;
|
|
44
|
+
}
|
|
@@ -144,6 +144,13 @@ function addOrChangeBuildTarget(tree, options, target) {
|
|
|
144
144
|
rspackConfig: (0, devkit_1.joinPathFragments)(project.root, 'rspack.config.js'),
|
|
145
145
|
assets,
|
|
146
146
|
};
|
|
147
|
+
const existingProjectConfigurations = {};
|
|
148
|
+
const buildTarget = project.targets.build;
|
|
149
|
+
if (buildTarget && buildTarget.configurations) {
|
|
150
|
+
for (const [configurationName, configuration] of Object.entries(buildTarget.configurations)) {
|
|
151
|
+
existingProjectConfigurations[configurationName] = configuration;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
147
154
|
project.targets ??= {};
|
|
148
155
|
project.targets[target] = {
|
|
149
156
|
executor: '@nx/rspack:rspack',
|
|
@@ -152,9 +159,11 @@ function addOrChangeBuildTarget(tree, options, target) {
|
|
|
152
159
|
options: buildOptions,
|
|
153
160
|
configurations: {
|
|
154
161
|
development: {
|
|
162
|
+
...(existingProjectConfigurations['development'] ?? {}),
|
|
155
163
|
mode: 'development',
|
|
156
164
|
},
|
|
157
165
|
production: {
|
|
166
|
+
...(existingProjectConfigurations['production'] ?? {}),
|
|
158
167
|
mode: 'production',
|
|
159
168
|
optimization: options.target === 'web' ? true : undefined,
|
|
160
169
|
sourceMap: false,
|
|
@@ -265,7 +274,7 @@ module.exports = composePlugins(withNx(), withReact(${stylePreprocessorOptions
|
|
|
265
274
|
`;
|
|
266
275
|
}
|
|
267
276
|
function generateNestConfig(tree, options, project, buildOptions) {
|
|
268
|
-
if ((0, has_plugin_1.hasPlugin)(tree)) {
|
|
277
|
+
if ((0, has_plugin_1.hasPlugin)(tree) && options.addPlugin !== false) {
|
|
269
278
|
return `
|
|
270
279
|
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
|
|
271
280
|
const rspack = require('@rspack/core');
|