@nx/rspack 20.2.0-beta.1 → 20.2.0-beta.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.
Files changed (105) hide show
  1. package/app-plugin.d.ts +2 -0
  2. package/app-plugin.js +5 -0
  3. package/generators.json +10 -0
  4. package/migrations.json +21 -1
  5. package/module-federation.d.ts +4 -1
  6. package/module-federation.js +7 -2
  7. package/package.json +10 -8
  8. package/react-plugin.d.ts +1 -0
  9. package/react-plugin.js +5 -0
  10. package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.js +5 -7
  11. package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.js +5 -7
  12. package/src/executors/module-federation-static-server/module-federation-static-server.impl.d.ts +1 -1
  13. package/src/executors/module-federation-static-server/module-federation-static-server.impl.js +4 -5
  14. package/src/executors/rspack/lib/config.d.ts +6 -0
  15. package/src/executors/rspack/lib/config.js +39 -0
  16. package/src/executors/rspack/rspack.impl.js +11 -12
  17. package/src/executors/rspack/schema.d.ts +39 -18
  18. package/src/executors/rspack/schema.json +191 -0
  19. package/src/generators/convert-config-to-rspack-plugin/convert-config-to-rspack-plugin.d.ts +7 -0
  20. package/src/generators/convert-config-to-rspack-plugin/convert-config-to-rspack-plugin.js +92 -0
  21. package/src/generators/convert-config-to-rspack-plugin/lib/extract-rspack-options.d.ts +6 -0
  22. package/src/generators/convert-config-to-rspack-plugin/lib/extract-rspack-options.js +106 -0
  23. package/src/generators/convert-config-to-rspack-plugin/lib/normalize-path-options.d.ts +2 -0
  24. package/src/generators/convert-config-to-rspack-plugin/lib/normalize-path-options.js +73 -0
  25. package/src/generators/convert-config-to-rspack-plugin/lib/utils.d.ts +1 -0
  26. package/src/generators/convert-config-to-rspack-plugin/lib/utils.js +13 -0
  27. package/src/generators/convert-config-to-rspack-plugin/lib/validate-project.d.ts +9 -0
  28. package/src/generators/convert-config-to-rspack-plugin/lib/validate-project.js +40 -0
  29. package/src/generators/convert-config-to-rspack-plugin/schema.json +19 -0
  30. package/src/generators/convert-to-inferred/__snapshots__/convert-to-inferred.spec.ts.snap +268 -0
  31. package/src/generators/convert-to-inferred/convert-to-inferred.d.ts +12 -0
  32. package/src/generators/convert-to-inferred/convert-to-inferred.js +114 -0
  33. package/src/generators/convert-to-inferred/schema.json +19 -0
  34. package/src/generators/convert-to-inferred/utils/ast.d.ts +3 -0
  35. package/src/generators/convert-to-inferred/utils/ast.js +40 -0
  36. package/src/generators/convert-to-inferred/utils/build-post-target-transformer.d.ts +6 -0
  37. package/src/generators/convert-to-inferred/utils/build-post-target-transformer.js +210 -0
  38. package/src/generators/convert-to-inferred/utils/index.d.ts +3 -0
  39. package/src/generators/convert-to-inferred/utils/index.js +6 -0
  40. package/src/generators/convert-to-inferred/utils/serve-post-target-transformer.d.ts +6 -0
  41. package/src/generators/convert-to-inferred/utils/serve-post-target-transformer.js +207 -0
  42. package/src/generators/convert-to-inferred/utils/types.d.ts +11 -0
  43. package/src/generators/convert-webpack/lib/transform-cjs.js +5 -5
  44. package/src/generators/convert-webpack/lib/transform-esm.js +5 -5
  45. package/src/index.d.ts +1 -0
  46. package/src/index.js +1 -0
  47. package/src/migrations/update-20-2-0/migrate-with-mf-import-to-new-package.d.ts +2 -0
  48. package/src/migrations/update-20-2-0/migrate-with-mf-import-to-new-package.js +35 -0
  49. package/src/plugins/nx-app-rspack-plugin/nx-app-rspack-plugin.d.ts +16 -0
  50. package/src/plugins/nx-app-rspack-plugin/nx-app-rspack-plugin.js +43 -0
  51. package/src/plugins/nx-react-rspack-plugin/nx-react-rspack-plugin.d.ts +8 -0
  52. package/src/plugins/nx-react-rspack-plugin/nx-react-rspack-plugin.js +13 -0
  53. package/src/plugins/use-legacy-nx-plugin/use-legacy-nx-plugin.d.ts +31 -0
  54. package/src/plugins/use-legacy-nx-plugin/use-legacy-nx-plugin.js +73 -0
  55. package/src/plugins/utils/apply-base-config.js +2 -5
  56. package/src/plugins/utils/apply-web-config.d.ts +2 -2
  57. package/src/plugins/utils/apply-web-config.js +1 -8
  58. package/src/plugins/utils/models.d.ts +2 -2
  59. package/src/plugins/utils/plugins/normalize-options.js +1 -1
  60. package/src/plugins/utils/plugins/nx-tsconfig-paths-rspack-plugin.js +3 -2
  61. package/src/utils/create-compiler.d.ts +2 -2
  62. package/src/utils/create-compiler.js +12 -49
  63. package/src/utils/generator-utils.d.ts +2 -2
  64. package/src/utils/generator-utils.js +134 -67
  65. package/src/utils/has-plugin.d.ts +2 -0
  66. package/src/utils/has-plugin.js +10 -0
  67. package/src/utils/module-federation/build-static.remotes.d.ts +1 -1
  68. package/src/utils/versions.d.ts +2 -2
  69. package/src/utils/versions.js +2 -2
  70. package/src/utils/module-federation/dependencies.d.ts +0 -6
  71. package/src/utils/module-federation/dependencies.js +0 -56
  72. package/src/utils/module-federation/get-remotes-for-host.d.ts +0 -16
  73. package/src/utils/module-federation/get-remotes-for-host.js +0 -99
  74. package/src/utils/module-federation/index.d.ts +0 -6
  75. package/src/utils/module-federation/index.js +0 -9
  76. package/src/utils/module-federation/models/index.d.ts +0 -47
  77. package/src/utils/module-federation/package-json.d.ts +0 -8
  78. package/src/utils/module-federation/package-json.js +0 -12
  79. package/src/utils/module-federation/parse-static-remotes-config.d.ts +0 -13
  80. package/src/utils/module-federation/parse-static-remotes-config.js +0 -34
  81. package/src/utils/module-federation/plugins/runtime-library-control.plugin.d.ts +0 -3
  82. package/src/utils/module-federation/plugins/runtime-library-control.plugin.js +0 -54
  83. package/src/utils/module-federation/public-api.d.ts +0 -8
  84. package/src/utils/module-federation/public-api.js +0 -20
  85. package/src/utils/module-federation/remotes.d.ts +0 -19
  86. package/src/utils/module-federation/remotes.js +0 -85
  87. package/src/utils/module-federation/secondary-entry-points.d.ts +0 -12
  88. package/src/utils/module-federation/secondary-entry-points.js +0 -104
  89. package/src/utils/module-federation/share.d.ts +0 -48
  90. package/src/utils/module-federation/share.js +0 -235
  91. package/src/utils/module-federation/start-remote-proxies.d.ts +0 -5
  92. package/src/utils/module-federation/start-remote-proxies.js +0 -45
  93. package/src/utils/module-federation/start-ssr-remote-proxies.d.ts +0 -5
  94. package/src/utils/module-federation/start-ssr-remote-proxies.js +0 -59
  95. package/src/utils/module-federation/typescript.d.ts +0 -4
  96. package/src/utils/module-federation/typescript.js +0 -53
  97. package/src/utils/module-federation/with-module-federation/package-json.d.ts +0 -8
  98. package/src/utils/module-federation/with-module-federation/package-json.js +0 -12
  99. package/src/utils/module-federation/with-module-federation/utils.d.ts +0 -12
  100. package/src/utils/module-federation/with-module-federation/utils.js +0 -76
  101. package/src/utils/module-federation/with-module-federation/with-module-federation-ssr.d.ts +0 -3
  102. package/src/utils/module-federation/with-module-federation/with-module-federation-ssr.js +0 -55
  103. package/src/utils/module-federation/with-module-federation/with-module-federation.d.ts +0 -8
  104. package/src/utils/module-federation/with-module-federation/with-module-federation.js +0 -70
  105. /package/src/{utils/module-federation/models/index.js → generators/convert-to-inferred/utils/types.js} +0 -0
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertConfigToRspackPluginGenerator = convertConfigToRspackPluginGenerator;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
6
+ const extract_rspack_options_1 = require("./lib/extract-rspack-options");
7
+ const normalize_path_options_1 = require("./lib/normalize-path-options");
8
+ const path_1 = require("path");
9
+ const validate_project_1 = require("./lib/validate-project");
10
+ // Make text JSON compatible
11
+ const preprocessText = (text) => {
12
+ return text
13
+ .replace(/(\w+):/g, '"$1":') // Quote property names
14
+ .replace(/'/g, '"') // Convert single quotes to double quotes
15
+ .replace(/,(\s*[}\]])/g, '$1') // Remove trailing commas
16
+ .replace(/(\r\n|\n|\r|\t)/gm, ''); // Remove newlines and tabs
17
+ };
18
+ async function convertConfigToRspackPluginGenerator(tree, options) {
19
+ let migrated = 0;
20
+ const projects = (0, devkit_1.getProjects)(tree);
21
+ (0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nx/rspack:rspack', (currentTargetOptions, projectName, targetName, configurationName) => {
22
+ if (options.project && projectName !== options.project) {
23
+ return;
24
+ }
25
+ if (!configurationName) {
26
+ const project = projects.get(projectName);
27
+ const target = project.targets[targetName];
28
+ const hasError = (0, validate_project_1.validateProject)(tree, project);
29
+ if (hasError) {
30
+ throw new Error(hasError);
31
+ }
32
+ const rspackConfigPath = currentTargetOptions?.rspackConfig || '';
33
+ if (rspackConfigPath && tree.exists(rspackConfigPath)) {
34
+ let { withNxConfig: rspackOptions, withReactConfig } = (0, extract_rspack_options_1.extractRspackOptions)(tree, rspackConfigPath);
35
+ // if rspackOptions === undefined
36
+ // withNx was not found in the rspack.config.js file so we should skip this project
37
+ if (rspackOptions !== undefined) {
38
+ let parsedOptions = {};
39
+ if (rspackOptions) {
40
+ parsedOptions = JSON.parse(preprocessText(rspackOptions.getText()));
41
+ parsedOptions = (0, normalize_path_options_1.normalizePathOptions)(project.root, parsedOptions);
42
+ }
43
+ target.options.standardRspackConfigFunction = true;
44
+ (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
45
+ const { dir, name, ext } = (0, path_1.parse)(rspackConfigPath);
46
+ tree.rename(rspackConfigPath, `${(0, devkit_1.joinPathFragments)(dir, `${name}.old${ext}`)}`);
47
+ tree.write(rspackConfigPath, (0, devkit_1.stripIndents) `
48
+ const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
49
+ const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
50
+ const { useLegacyNxPlugin } = require('@nx/rspack');
51
+
52
+ // This file was migrated using @nx/rspack:convert-config-to-rspack-plugin from your './rspack.config.old.js'
53
+ // Please check that the options here are correct as they were moved from the old rspack.config.js to this file.
54
+ const options = ${rspackOptions ? JSON.stringify(parsedOptions, null, 2) : '{}'};
55
+
56
+ /**
57
+ * @type{import('@rspack/core').RspackOptionsNormalized}
58
+ */
59
+ module.exports = async () => ({
60
+ plugins: [
61
+ ${rspackOptions
62
+ ? 'new NxAppRspackPlugin(options)'
63
+ : 'new NxAppRspackPlugin()'},
64
+ ${withReactConfig
65
+ ? `new NxReactRspackPlugin(${withReactConfig.getText()})`
66
+ : `new NxReactRspackPlugin({
67
+ // Uncomment this line if you don't want to use SVGR
68
+ // See: https://react-svgr.com/
69
+ // svgr: false
70
+ })`},
71
+ // NOTE: useLegacyNxPlugin ensures that the non-standard Rspack configuration file previously used still works.
72
+ // To remove its usage, move options such as "plugins" into this file as standard Rspack configuration options.
73
+ // To enhance configurations after Nx plugins have applied, you can add a new plugin with the \`apply\` method.
74
+ // e.g. \`{ apply: (compiler) => { /* modify compiler.options */ }\`
75
+ // eslint-disable-next-line react-hooks/rules-of-hooks
76
+ await useLegacyNxPlugin(require('./rspack.config.old'), options),
77
+ ],
78
+ });
79
+ `);
80
+ migrated++;
81
+ }
82
+ }
83
+ }
84
+ });
85
+ if (migrated === 0) {
86
+ throw new Error('Could not find any projects to migrate.');
87
+ }
88
+ if (!options.skipFormat) {
89
+ await (0, devkit_1.formatFiles)(tree);
90
+ }
91
+ }
92
+ exports.default = convertConfigToRspackPluginGenerator;
@@ -0,0 +1,6 @@
1
+ import { Tree } from '@nx/devkit';
2
+ import * as ts from 'typescript';
3
+ export declare function extractRspackOptions(tree: Tree, rspackConfigPath: string): {
4
+ withNxConfig: "" | ts.Node;
5
+ withReactConfig: "" | ts.Node;
6
+ };
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractRspackOptions = extractRspackOptions;
4
+ const tslib_1 = require("tslib");
5
+ const tsquery_1 = require("@phenomnomnominal/tsquery");
6
+ const ts = tslib_1.__importStar(require("typescript"));
7
+ function extractRspackOptions(tree, rspackConfigPath) {
8
+ const source = tree.read(rspackConfigPath).toString('utf-8');
9
+ const ast = tsquery_1.tsquery.ast(source);
10
+ const withNxQuery = 'CallExpression:has(Identifier[name="withNx"])';
11
+ const withReactQuery = 'CallExpression:has(Identifier[name="withReact"])';
12
+ const withWebQuery = 'CallExpression:has(Identifier[name="withWeb"])';
13
+ const withNxCall = (0, tsquery_1.tsquery)(ast, withNxQuery);
14
+ const withReactCall = (0, tsquery_1.tsquery)(ast, withReactQuery);
15
+ const withWebCall = (0, tsquery_1.tsquery)(ast, withWebQuery);
16
+ // If the config is empty set to empty string to avoid undefined. Undefined is used to check if the withNx exists inside of the config file.
17
+ let withNxConfig, withReactConfig;
18
+ withWebCall.forEach((node) => {
19
+ const argument = node.arguments[0] || '';
20
+ withNxConfig = argument; // Since withWeb and withNx use the same config object and both should not exist in the same file, we can reuse the withNxConfig variable.
21
+ });
22
+ withNxCall.forEach((node) => {
23
+ const argument = node.arguments[0] || ''; // The first argument is the config object
24
+ withNxConfig = argument;
25
+ });
26
+ withReactCall.forEach((node) => {
27
+ const argument = node.arguments[0] || '';
28
+ withReactConfig = argument;
29
+ });
30
+ if (withNxConfig !== undefined) {
31
+ // Only remove the withNx and withReact calls if they exist
32
+ let updatedSource = removeCallExpressions(source, [
33
+ 'withNx',
34
+ 'withReact',
35
+ 'withWeb',
36
+ ]);
37
+ updatedSource = removeImportDeclarations(updatedSource, 'withNx', '@nx/rspack');
38
+ updatedSource = removeImportDeclarations(updatedSource, 'withWeb', '@nx/rspack');
39
+ updatedSource = removeImportDeclarations(updatedSource, 'withReact', '@nx/rspack');
40
+ tree.write(rspackConfigPath, updatedSource);
41
+ }
42
+ return { withNxConfig, withReactConfig };
43
+ }
44
+ function removeCallExpressions(source, functionNames) {
45
+ let modifiedSource = source;
46
+ functionNames.forEach((functionName) => {
47
+ const callExpressionQuery = `CallExpression:has(Identifier[name="composePlugins"]) > CallExpression:has(Identifier[name="${functionName}"])`;
48
+ modifiedSource = tsquery_1.tsquery.replace(modifiedSource, callExpressionQuery, () => {
49
+ return ''; // Removes the entire CallExpression
50
+ });
51
+ });
52
+ return modifiedSource;
53
+ }
54
+ function removeImportDeclarations(source, importName, moduleName) {
55
+ const sourceFile = tsquery_1.tsquery.ast(source);
56
+ const modifiedStatements = sourceFile.statements
57
+ .map((statement) => {
58
+ if (!ts.isVariableStatement(statement))
59
+ return statement;
60
+ const declarationList = statement.declarationList;
61
+ const newDeclarations = declarationList.declarations
62
+ .map((declaration) => {
63
+ if (!ts.isVariableDeclaration(declaration) ||
64
+ !declaration.initializer)
65
+ return declaration;
66
+ if (ts.isCallExpression(declaration.initializer) &&
67
+ ts.isIdentifier(declaration.initializer.expression)) {
68
+ const callExpr = declaration.initializer.expression;
69
+ if (callExpr.text === 'require' &&
70
+ declaration.initializer.arguments[0]
71
+ ?.getText()
72
+ .replace(/['"]/g, '') === moduleName) {
73
+ if (ts.isObjectBindingPattern(declaration.name)) {
74
+ const bindingElements = declaration.name.elements.filter((element) => {
75
+ const elementName = element.name.getText();
76
+ return elementName !== importName;
77
+ });
78
+ if (bindingElements.length > 0) {
79
+ const newBindingPattern = ts.factory.updateObjectBindingPattern(declaration.name, bindingElements);
80
+ // Update the variable declaration with the new binding pattern without the specified import name
81
+ return ts.factory.updateVariableDeclaration(declaration, newBindingPattern, declaration.exclamationToken, declaration.type, declaration.initializer);
82
+ }
83
+ else {
84
+ return null; // Remove this declaration entirely if no bindings remain
85
+ }
86
+ }
87
+ }
88
+ }
89
+ return declaration;
90
+ })
91
+ .filter(Boolean);
92
+ if (newDeclarations.length > 0) {
93
+ const newDeclarationList = ts.factory.updateVariableDeclarationList(declarationList, newDeclarations);
94
+ return ts.factory.updateVariableStatement(statement, statement.modifiers, newDeclarationList);
95
+ }
96
+ else {
97
+ return null; // Remove the entire statement
98
+ }
99
+ })
100
+ .filter(Boolean);
101
+ // Use printer to format the source code and rewrite the modified
102
+ const newSourceFile = ts.factory.updateSourceFile(sourceFile, modifiedStatements);
103
+ const printer = ts.createPrinter();
104
+ const formattedSource = printer.printFile(newSourceFile);
105
+ return formattedSource;
106
+ }
@@ -0,0 +1,2 @@
1
+ import { RspackExecutorSchema } from '../../../executors/rspack/schema';
2
+ export declare function normalizePathOptions(projectRoot: string, options: Partial<RspackExecutorSchema>): Partial<RspackExecutorSchema>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizePathOptions = normalizePathOptions;
4
+ const utils_1 = require("./utils");
5
+ const executorFieldsToNormalize = [
6
+ 'outputPath',
7
+ 'index',
8
+ 'main',
9
+ 'assets',
10
+ 'tsConfig',
11
+ 'styles',
12
+ 'additionalEntryPoints',
13
+ 'scripts',
14
+ 'fileReplacements',
15
+ 'postcssConfig',
16
+ 'stylePreprocessorOptions',
17
+ 'publicPath',
18
+ ];
19
+ function normalizePathOptions(projectRoot, options) {
20
+ for (const [key, value] of Object.entries(options)) {
21
+ if (!executorFieldsToNormalize.includes(key)) {
22
+ continue;
23
+ }
24
+ options[key] = normalizePath(projectRoot, key, value);
25
+ }
26
+ return options;
27
+ }
28
+ function normalizePath(projectRoot, key, value) {
29
+ if (!value)
30
+ return value;
31
+ switch (key) {
32
+ case 'assets':
33
+ return value.map((asset) => {
34
+ if (typeof asset === 'string') {
35
+ return (0, utils_1.toProjectRelativePath)(asset, projectRoot);
36
+ }
37
+ return {
38
+ ...asset,
39
+ input: (0, utils_1.toProjectRelativePath)(asset.input, projectRoot),
40
+ output: (0, utils_1.toProjectRelativePath)(asset.output, projectRoot),
41
+ };
42
+ });
43
+ case 'styles':
44
+ case 'scripts':
45
+ return value.map((item) => {
46
+ if (typeof item === 'string') {
47
+ return (0, utils_1.toProjectRelativePath)(item, projectRoot);
48
+ }
49
+ return {
50
+ ...item,
51
+ input: (0, utils_1.toProjectRelativePath)(item.input, projectRoot),
52
+ };
53
+ });
54
+ case 'additionalEntryPoints':
55
+ return value.map((entry) => {
56
+ return {
57
+ ...entry,
58
+ entryPath: (0, utils_1.toProjectRelativePath)(entry.entryPath, projectRoot),
59
+ };
60
+ });
61
+ case 'fileReplacements':
62
+ return value.map((replacement) => {
63
+ return {
64
+ replace: (0, utils_1.toProjectRelativePath)(replacement.replace, projectRoot),
65
+ with: (0, utils_1.toProjectRelativePath)(replacement.with, projectRoot),
66
+ };
67
+ });
68
+ default:
69
+ return Array.isArray(value)
70
+ ? value.map((item) => (0, utils_1.toProjectRelativePath)(item, projectRoot))
71
+ : (0, utils_1.toProjectRelativePath)(value, projectRoot);
72
+ }
73
+ }
@@ -0,0 +1 @@
1
+ export declare function toProjectRelativePath(path: string, projectRoot: string): string;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toProjectRelativePath = toProjectRelativePath;
4
+ const posix_1 = require("path/posix");
5
+ const devkit_1 = require("@nx/devkit");
6
+ function toProjectRelativePath(path, projectRoot) {
7
+ if (projectRoot === '.') {
8
+ // workspace and project root are the same, we normalize it to ensure it
9
+ return path.startsWith('.') ? path : `./${path}`;
10
+ }
11
+ const relativePath = (0, posix_1.relative)((0, posix_1.resolve)(devkit_1.workspaceRoot, projectRoot), (0, posix_1.resolve)(devkit_1.workspaceRoot, path));
12
+ return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
13
+ }
@@ -0,0 +1,9 @@
1
+ import { ProjectConfiguration, Tree } from '@nx/devkit';
2
+ /**
3
+ * Validates the project to ensure it can be migrated
4
+ *
5
+ * @param tree The virtual file system
6
+ * @param project the project configuration object for the project
7
+ * @returns A string if there is an error, otherwise undefined
8
+ */
9
+ export declare function validateProject(tree: Tree, project: ProjectConfiguration): string;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateProject = validateProject;
4
+ function hasAnotherRspackConfig(tree, projectRoot) {
5
+ const files = tree.children(projectRoot);
6
+ const projectJsonString = tree.read(`${projectRoot}/project.json`, 'utf-8');
7
+ for (const file of files) {
8
+ if (file !== 'rspack.config.js' &&
9
+ file.endsWith('.js') &&
10
+ file.includes('rspack.config') &&
11
+ projectJsonString.includes(file) &&
12
+ tree.exists(`${projectRoot}/rspack.config.js`)) {
13
+ return 'Cannot convert a project with multiple rspack config files. Please consolidate them into a single rspack.config.js file.';
14
+ }
15
+ }
16
+ }
17
+ function isNestProject(project) {
18
+ for (const target in project.targets) {
19
+ if (project.targets[target].executor === '@nx/js:node') {
20
+ return `The project ${project.name} is using the '@nx/js:node' executor. At the moment, we do not support migrating such projects.`;
21
+ }
22
+ }
23
+ }
24
+ /**
25
+ * Validates the project to ensure it can be migrated
26
+ *
27
+ * @param tree The virtual file system
28
+ * @param project the project configuration object for the project
29
+ * @returns A string if there is an error, otherwise undefined
30
+ */
31
+ function validateProject(tree, project) {
32
+ const containsMfeExecutor = Object.keys(project.targets).some((target) => {
33
+ return ['@nx/rspack:module-federation-dev-server'].includes(project.targets[target].executor);
34
+ });
35
+ if (containsMfeExecutor) {
36
+ return `The project ${project.name} is using Module Federation. At the moment, we don't support migrating projects that use Module Federation.`;
37
+ }
38
+ const hasAnotherConfig = hasAnotherRspackConfig(tree, project.root);
39
+ return hasAnotherConfig || isNestProject(project);
40
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxRspackConvertConfigToRspackPlugin",
4
+ "description": "Convert existing Rspack project(s) using `@nx/rspack:rspack` executor that uses `withNx` to use `NxAppRspackPlugin`. Defaults to migrating all projects. Pass '--project' to migrate only one target.",
5
+ "title": "Convert Rspack project using withNx to NxAppRspackPlugin",
6
+ "type": "object",
7
+ "properties": {
8
+ "project": {
9
+ "type": "string",
10
+ "description": "The project to convert from using the `@nx/rspack:rspack` executor and `withNx` plugin to use `NxAppRspackPlugin`.",
11
+ "x-priority": "important"
12
+ },
13
+ "skipFormat": {
14
+ "type": "boolean",
15
+ "description": "Whether to format files at the end of the migration.",
16
+ "default": false
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,268 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`convert-to-inferred all projects should migrate all projects using the rspack executors 1`] = `
4
+ "const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
5
+ const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
6
+ const { useLegacyNxPlugin } = require('@nx/rspack');
7
+
8
+ // These options were migrated by @nx/rspack:convert-to-inferred from
9
+ // the project.json file and merged with the options in this file
10
+ const configValues = {
11
+ build: {
12
+ default: {
13
+ outputPath: '../../dist/apps/app1',
14
+ index: './src/index.html',
15
+ main: './src/main.tsx',
16
+ tsConfig: './tsconfig.app.json',
17
+ assets: ['./src/favicon.ico', './src/assets'],
18
+ styles: ['./src/styles.scss'],
19
+ },
20
+ development: {
21
+ extractLicenses: false,
22
+ optimization: false,
23
+ sourceMap: true,
24
+ vendorChunk: true,
25
+ },
26
+ production: {
27
+ fileReplacements: [
28
+ {
29
+ replace: './src/environments/environment.ts',
30
+ with: './src/environments/environment.prod.ts',
31
+ },
32
+ ],
33
+ optimization: true,
34
+ outputHashing: 'all',
35
+ sourceMap: false,
36
+ namedChunks: false,
37
+ extractLicenses: true,
38
+ vendorChunk: false,
39
+ },
40
+ },
41
+ serve: {
42
+ default: {
43
+ hmr: true,
44
+ server: {
45
+ type: 'https',
46
+ options: { cert: './server.crt', key: './server.key' },
47
+ },
48
+ port: 4200,
49
+ headers: { 'Access-Control-Allow-Origin': '*' },
50
+ historyApiFallback: {
51
+ index: '/index.html',
52
+ disableDotRule: true,
53
+ htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
54
+ },
55
+ },
56
+ development: { open: true },
57
+ production: { hmr: false },
58
+ },
59
+ };
60
+
61
+ // Determine the correct configValue to use based on the configuration
62
+ const configuration = process.env.NX_TASK_TARGET_CONFIGURATION || 'default';
63
+
64
+ const buildOptions = {
65
+ ...configValues.build.default,
66
+ ...configValues.build[configuration],
67
+ };
68
+ const devServerOptions = {
69
+ ...configValues.serve.default,
70
+ ...configValues.serve[configuration],
71
+ };
72
+
73
+ /**
74
+ * @type{import('@rspack/core').RspackOptionsNormalized}
75
+ */
76
+ module.exports = async () => ({
77
+ devServer: devServerOptions,
78
+ plugins: [
79
+ new NxAppRspackPlugin(buildOptions),
80
+ new NxReactRspackPlugin({
81
+ // Uncomment this line if you don't want to use SVGR
82
+ // See: https://react-svgr.com/
83
+ // svgr: false
84
+ }),
85
+ // eslint-disable-next-line react-hooks/rules-of-hooks
86
+ await useLegacyNxPlugin(require('./rspack.config.old'), buildOptions),
87
+ ],
88
+ });
89
+ "
90
+ `;
91
+
92
+ exports[`convert-to-inferred all projects should migrate all projects using the rspack executors 2`] = `
93
+ "const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
94
+ const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
95
+ const { useLegacyNxPlugin } = require('@nx/rspack');
96
+
97
+ // These options were migrated by @nx/rspack:convert-to-inferred from
98
+ // the project.json file and merged with the options in this file
99
+ const configValues = {
100
+ build: {
101
+ default: {
102
+ outputPath: '../../dist/apps/app2',
103
+ index: './src/index.html',
104
+ main: './src/main.tsx',
105
+ tsConfig: './tsconfig.app.json',
106
+ assets: ['./src/favicon.ico', './src/assets'],
107
+ styles: ['./src/styles.scss'],
108
+ },
109
+ development: {
110
+ extractLicenses: false,
111
+ optimization: false,
112
+ sourceMap: true,
113
+ vendorChunk: true,
114
+ },
115
+ production: {
116
+ fileReplacements: [
117
+ {
118
+ replace: './src/environments/environment.ts',
119
+ with: './src/environments/environment.prod.ts',
120
+ },
121
+ ],
122
+ optimization: true,
123
+ outputHashing: 'all',
124
+ sourceMap: false,
125
+ namedChunks: false,
126
+ extractLicenses: true,
127
+ vendorChunk: false,
128
+ },
129
+ },
130
+ serve: {
131
+ default: {
132
+ hmr: true,
133
+ server: {
134
+ type: 'https',
135
+ options: { cert: './server.crt', key: './server.key' },
136
+ },
137
+ port: 4200,
138
+ headers: { 'Access-Control-Allow-Origin': '*' },
139
+ historyApiFallback: {
140
+ index: '/index.html',
141
+ disableDotRule: true,
142
+ htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
143
+ },
144
+ },
145
+ development: { open: true },
146
+ production: { hmr: false },
147
+ },
148
+ };
149
+
150
+ // Determine the correct configValue to use based on the configuration
151
+ const configuration = process.env.NX_TASK_TARGET_CONFIGURATION || 'default';
152
+
153
+ const buildOptions = {
154
+ ...configValues.build.default,
155
+ ...configValues.build[configuration],
156
+ };
157
+ const devServerOptions = {
158
+ ...configValues.serve.default,
159
+ ...configValues.serve[configuration],
160
+ };
161
+
162
+ /**
163
+ * @type{import('@rspack/core').RspackOptionsNormalized}
164
+ */
165
+ module.exports = async () => ({
166
+ devServer: devServerOptions,
167
+ plugins: [
168
+ new NxAppRspackPlugin(buildOptions),
169
+ new NxReactRspackPlugin({
170
+ // Uncomment this line if you don't want to use SVGR
171
+ // See: https://react-svgr.com/
172
+ // svgr: false
173
+ }),
174
+ // eslint-disable-next-line react-hooks/rules-of-hooks
175
+ await useLegacyNxPlugin(require('./rspack.config.old'), buildOptions),
176
+ ],
177
+ });
178
+ "
179
+ `;
180
+
181
+ exports[`convert-to-inferred all projects should migrate all projects using the rspack executors 3`] = `
182
+ "const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
183
+ const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
184
+ const { useLegacyNxPlugin } = require('@nx/rspack');
185
+
186
+ // These options were migrated by @nx/rspack:convert-to-inferred from
187
+ // the project.json file and merged with the options in this file
188
+ const configValues = {
189
+ build: {
190
+ default: {
191
+ outputPath: '../../dist/apps/app3',
192
+ index: './src/index.html',
193
+ main: './src/main.tsx',
194
+ tsConfig: './tsconfig.app.json',
195
+ assets: ['./src/favicon.ico', './src/assets'],
196
+ styles: ['./src/styles.scss'],
197
+ },
198
+ development: {
199
+ extractLicenses: false,
200
+ optimization: false,
201
+ sourceMap: true,
202
+ vendorChunk: true,
203
+ },
204
+ production: {
205
+ fileReplacements: [
206
+ {
207
+ replace: './src/environments/environment.ts',
208
+ with: './src/environments/environment.prod.ts',
209
+ },
210
+ ],
211
+ optimization: true,
212
+ outputHashing: 'all',
213
+ sourceMap: false,
214
+ namedChunks: false,
215
+ extractLicenses: true,
216
+ vendorChunk: false,
217
+ },
218
+ },
219
+ serve: {
220
+ default: {
221
+ hmr: true,
222
+ server: {
223
+ type: 'https',
224
+ options: { cert: './server.crt', key: './server.key' },
225
+ },
226
+ port: 4200,
227
+ headers: { 'Access-Control-Allow-Origin': '*' },
228
+ historyApiFallback: {
229
+ index: '/index.html',
230
+ disableDotRule: true,
231
+ htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
232
+ },
233
+ },
234
+ development: { open: true },
235
+ production: { hmr: false },
236
+ },
237
+ };
238
+
239
+ // Determine the correct configValue to use based on the configuration
240
+ const configuration = process.env.NX_TASK_TARGET_CONFIGURATION || 'default';
241
+
242
+ const buildOptions = {
243
+ ...configValues.build.default,
244
+ ...configValues.build[configuration],
245
+ };
246
+ const devServerOptions = {
247
+ ...configValues.serve.default,
248
+ ...configValues.serve[configuration],
249
+ };
250
+
251
+ /**
252
+ * @type{import('@rspack/core').RspackOptionsNormalized}
253
+ */
254
+ module.exports = async () => ({
255
+ devServer: devServerOptions,
256
+ plugins: [
257
+ new NxAppRspackPlugin(buildOptions),
258
+ new NxReactRspackPlugin({
259
+ // Uncomment this line if you don't want to use SVGR
260
+ // See: https://react-svgr.com/
261
+ // svgr: false
262
+ }),
263
+ // eslint-disable-next-line react-hooks/rules-of-hooks
264
+ await useLegacyNxPlugin(require('./rspack.config.old'), buildOptions),
265
+ ],
266
+ });
267
+ "
268
+ `;
@@ -0,0 +1,12 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ import { logger as devkitLogger } from 'nx/src/devkit-exports';
3
+ interface Schema {
4
+ project?: string;
5
+ skipFormat?: boolean;
6
+ }
7
+ export declare function convertToInferred(tree: Tree, options: Schema): Promise<import("@nx/devkit").GeneratorCallback>;
8
+ export declare function createCollectingLogger(): typeof devkitLogger & {
9
+ loggedMessages: Map<string, string[]>;
10
+ flushLogs: (filter?: (message: string) => boolean) => void;
11
+ };
12
+ export {};