@nx/rspack 21.1.2 → 21.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  <p style="text-align: center;">
2
2
  <picture>
3
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%">
4
+ <img alt="Nx - Smart Repos · Fast Builds" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
5
5
  </picture>
6
6
  </p>
7
7
 
@@ -20,9 +20,9 @@
20
20
 
21
21
  <hr>
22
22
 
23
- # Nx: Smart Monorepos · Fast CI
23
+ # Nx: Smart Repos · Fast Builds
24
24
 
25
- Nx is a build system, optimized for monorepos, with plugins for popular frameworks and tools and advanced CI capabilities including caching and distribution.
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
 
@@ -64,5 +64,5 @@ npx nx@latest init
64
64
  - [Blog Posts About Nx](https://nx.dev/blog)
65
65
 
66
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"
67
- width="100%" alt="Nx - Smart Monorepos · Fast CI"></a></p>
67
+ width="100%" alt="Nx - Smart Repos · Fast Builds"></a></p>
68
68
 
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.1.2",
4
+ "version": "21.1.3",
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.1.2",
28
- "@nx/devkit": "21.1.2",
29
- "@nx/web": "21.1.2",
30
- "@nx/module-federation": "21.1.2",
27
+ "@nx/js": "21.1.3",
28
+ "@nx/devkit": "21.1.3",
29
+ "@nx/web": "21.1.3",
30
+ "@nx/module-federation": "21.1.3",
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,12 +13,18 @@ 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 is_lib_buildable_1 = require("./is-lib-buildable");
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,
20
20
  ];
21
21
  const extensions = ['...', '.ts', '.tsx', '.mjs', '.js', '.jsx'];
22
+ const extensionAlias = {
23
+ '.js': ['.ts', '.tsx', '.js', '.jsx'],
24
+ '.mjs': ['.mts', '.mjs'],
25
+ '.cjs': ['.cts', '.cjs'],
26
+ '.jsx': ['.tsx', '.jsx'],
27
+ };
22
28
  const mainFields = ['module', 'main'];
23
29
  function applyBaseConfig(options, config = {}, { useNormalizedEntry, } = {}) {
24
30
  // Defaults that was applied from executor schema previously.
@@ -105,39 +111,41 @@ function applyNxIndependentConfig(options, config) {
105
111
  (x) => IGNORED_RSPACK_WARNINGS.some((r) => typeof x === 'string' ? r.test(x) : r.test(x.message)),
106
112
  ...(config.ignoreWarnings ?? []),
107
113
  ];
108
- config.optimization = !isProd
109
- ? undefined
110
- : {
111
- ...(config.optimization ?? {}),
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,
114
+ config.optimization = {
115
+ ...(config.optimization ?? {}),
116
+ ...(isProd
117
+ ? {
118
+ sideEffects: true,
119
+ minimize: typeof options.optimization === 'object'
120
+ ? !!options.optimization.scripts
121
+ : !!options.optimization,
122
+ minimizer: [
123
+ new core_1.SwcJsMinimizerRspackPlugin({
124
+ extractComments: false,
125
+ minimizerOptions: {
126
+ // this needs to be false to allow toplevel variables to be used in the global scope
127
+ // important especially for module-federation which operates as such
128
+ module: false,
129
+ mangle: {
130
+ keep_classnames: true,
131
+ },
132
+ format: {
133
+ ecma: (0, get_terser_ecma_version_1.getTerserEcmaVersion)(path.join(options.root, options.projectRoot)),
134
+ ascii_only: true,
135
+ comments: false,
136
+ webkit: true,
137
+ safari10: true,
138
+ },
132
139
  },
133
- },
134
- }),
135
- ],
136
- concatenateModules: true,
137
- runtimeChunk: isDevServer
138
- ? config.optimization?.runtimeChunk ?? undefined
139
- : false,
140
- };
140
+ }),
141
+ ],
142
+ concatenateModules: true,
143
+ runtimeChunk: isDevServer
144
+ ? config.optimization?.runtimeChunk ?? undefined
145
+ : false,
146
+ }
147
+ : {}),
148
+ };
141
149
  config.stats = {
142
150
  hash: true,
143
151
  timings: false,
@@ -282,27 +290,12 @@ function applyNxDependentConfig(options, config, { useNormalizedEntry } = {}) {
282
290
  const modulesDir = `${options.root}/node_modules`;
283
291
  const graph = options.projectGraph;
284
292
  const projectName = options.projectName;
285
- const deps = graph?.dependencies?.[projectName] ?? [];
286
293
  // Collect non-buildable TS project references so that they are bundled
287
294
  // in the final output. This is needed for projects that are not buildable
288
295
  // but are referenced by buildable projects. This is needed for the new TS
289
296
  // solution setup.
290
297
  const nonBuildableWorkspaceLibs = isUsingTsSolution
291
- ? deps
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)
298
+ ? (0, get_non_buildable_libs_1.getNonBuildableLibs)(graph, projectName)
306
299
  : [];
307
300
  externals.push(nodeExternals({ modulesDir, allowlist: nonBuildableWorkspaceLibs }));
308
301
  }
@@ -319,6 +312,10 @@ function applyNxDependentConfig(options, config, { useNormalizedEntry } = {}) {
319
312
  config.resolve = {
320
313
  ...config.resolve,
321
314
  extensions: [...(config?.resolve?.extensions ?? []), ...extensions],
315
+ extensionAlias: {
316
+ ...(config.resolve?.extensionAlias ?? {}),
317
+ ...extensionAlias,
318
+ },
322
319
  alias: {
323
320
  ...(config.resolve?.alias ?? {}),
324
321
  ...(options.fileReplacements?.reduce((aliases, replacement) => ({
@@ -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');
@@ -16,9 +16,8 @@ const devkit_internals_1 = require("nx/src/devkit-internals");
16
16
  async function readRspackOptions(rspackConfig) {
17
17
  const configs = [];
18
18
  const resolveConfig = async (config) => {
19
- let resolvedConfig;
20
19
  if ((0, config_1.isNxRspackComposablePlugin)(config)) {
21
- resolvedConfig = await config({}, {
20
+ return await config({}, {
22
21
  // These values are only used during build-time, so passing stubs here just to read out
23
22
  // the returned config object.
24
23
  options: {