@nx/react 21.0.0-beta.1 → 21.0.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.
Files changed (100) hide show
  1. package/package.json +6 -6
  2. package/plugins/nx-react-webpack-plugin/lib/apply-react-config.js +3 -1
  3. package/router-plugin.d.ts +1 -0
  4. package/router-plugin.js +5 -0
  5. package/src/generators/application/application.js +52 -15
  6. package/src/generators/application/files/react-router-ssr/common/app/app-nav.tsx__tmpl__ +14 -0
  7. package/src/generators/application/files/react-router-ssr/common/app/entry.client.tsx__tmpl__ +18 -0
  8. package/src/generators/application/files/react-router-ssr/common/app/entry.server.tsx__tmpl__ +74 -0
  9. package/src/generators/application/files/react-router-ssr/common/app/root.tsx__tmpl__ +51 -0
  10. package/src/generators/application/files/react-router-ssr/common/app/routes/about.tsx__tmpl__ +7 -0
  11. package/src/generators/application/files/react-router-ssr/common/app/routes.tsx__tmpl__ +6 -0
  12. package/src/generators/application/files/react-router-ssr/common/public/favicon.ico +0 -0
  13. package/src/generators/application/files/react-router-ssr/common/react-router.config.ts__tmpl__ +5 -0
  14. package/src/generators/application/files/react-router-ssr/common/tests/routes/_index.spec.tsx__tmpl__ +16 -0
  15. package/src/generators/application/files/react-router-ssr/common/tsconfig.app.json__tmpl__ +23 -0
  16. package/src/generators/application/files/react-router-ssr/common/tsconfig.json__tmpl__ +27 -0
  17. package/src/generators/application/files/react-router-ssr/non-root/.gitignore__tmpl__ +5 -0
  18. package/src/generators/application/files/react-router-ssr/non-root/package.json__tmpl__ +24 -0
  19. package/src/generators/application/files/react-router-ssr/nx-welcome/claimed/app/nx-welcome.tsx__tmpl__ +866 -0
  20. package/src/generators/application/files/react-router-ssr/nx-welcome/not-configured/app/nx-welcome.tsx__tmpl__ +866 -0
  21. package/src/generators/application/files/react-router-ssr/nx-welcome/unclaimed/app/nx-welcome.tsx__tmpl__ +864 -0
  22. package/src/generators/application/files/react-router-ssr/ts-solution/package.json__tmpl__ +24 -0
  23. package/src/generators/application/files/react-router-ssr/ts-solution/tsconfig.app.json__tmpl__ +39 -0
  24. package/src/generators/application/lib/add-e2e.js +33 -24
  25. package/src/generators/application/lib/add-jest.js +26 -2
  26. package/src/generators/application/lib/add-linting.d.ts +1 -0
  27. package/src/generators/application/lib/add-linting.js +38 -0
  28. package/src/generators/application/lib/add-project.js +31 -15
  29. package/src/generators/application/lib/add-routing.js +1 -1
  30. package/src/generators/application/lib/bundlers/add-rspack.d.ts +0 -1
  31. package/src/generators/application/lib/bundlers/add-rspack.js +0 -18
  32. package/src/generators/application/lib/bundlers/add-vite.js +15 -6
  33. package/src/generators/application/lib/create-application-files.d.ts +61 -0
  34. package/src/generators/application/lib/create-application-files.js +81 -39
  35. package/src/generators/application/lib/get-app-tests.js +3 -3
  36. package/src/generators/application/lib/install-common-dependencies.js +13 -2
  37. package/src/generators/application/lib/normalize-options.d.ts +0 -2
  38. package/src/generators/application/lib/normalize-options.js +14 -20
  39. package/src/generators/application/schema.d.ts +5 -1
  40. package/src/generators/application/schema.json +10 -1
  41. package/src/generators/component-test/component-test.js +1 -1
  42. package/src/generators/cypress-component-configuration/lib/add-files.d.ts +1 -1
  43. package/src/generators/cypress-component-configuration/lib/add-files.js +7 -4
  44. package/src/generators/host/files/rspack-module-federation/rspack.config.js__tmpl__ +37 -13
  45. package/src/generators/host/files/rspack-module-federation/rspack.config.prod.js__tmpl__ +60 -32
  46. package/src/generators/host/files/rspack-module-federation-ssr/module-federation.server.config.js__tmpl__ +6 -0
  47. package/src/generators/host/files/rspack-module-federation-ssr/rspack.config.js__tmpl__ +66 -0
  48. package/src/generators/host/files/rspack-module-federation-ssr/server.ts__tmpl__ +1 -1
  49. package/src/generators/host/files/rspack-module-federation-ssr/src/main.server.tsx__tmpl__ +49 -0
  50. package/src/generators/host/files/rspack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +6 -0
  51. package/src/generators/host/files/rspack-module-federation-ssr-ts/rspack.config.ts__tmpl__ +66 -0
  52. package/src/generators/host/files/rspack-module-federation-ssr-ts/server.ts__tmpl__ +1 -1
  53. package/src/generators/host/files/rspack-module-federation-ssr-ts/src/main.server.tsx__tmpl__ +49 -0
  54. package/src/generators/host/files/rspack-module-federation-ts/rspack.config.prod.ts__tmpl__ +37 -9
  55. package/src/generators/host/files/rspack-module-federation-ts/rspack.config.ts__tmpl__ +37 -14
  56. package/src/generators/host/host.js +21 -18
  57. package/src/generators/host/lib/add-module-federation-files.js +28 -12
  58. package/src/generators/host/lib/normalize-host-name.d.ts +2 -0
  59. package/src/generators/host/lib/normalize-host-name.js +12 -0
  60. package/src/generators/host/lib/setup-ssr-for-host.d.ts +3 -3
  61. package/src/generators/host/lib/setup-ssr-for-host.js +46 -22
  62. package/src/generators/init/init.js +23 -0
  63. package/src/generators/init/schema.d.ts +2 -0
  64. package/src/generators/library/lib/add-rollup-build-target.d.ts +3 -1
  65. package/src/generators/library/lib/add-rollup-build-target.js +6 -7
  66. package/src/generators/library/lib/create-files.js +2 -1
  67. package/src/generators/library/lib/normalize-options.js +8 -5
  68. package/src/generators/library/library.js +44 -30
  69. package/src/generators/library/schema.d.ts +2 -0
  70. package/src/generators/library/schema.json +4 -0
  71. package/src/generators/remote/files/rspack-module-federation/rspack.config.js__tmpl__ +40 -13
  72. package/src/generators/remote/files/rspack-module-federation-ssr/module-federation.server.config.js__tmpl__ +6 -0
  73. package/src/generators/remote/files/rspack-module-federation-ssr/rspack.config.js__tmpl__ +69 -0
  74. package/src/generators/remote/files/rspack-module-federation-ssr/server.ts__tmpl__ +2 -2
  75. package/src/generators/remote/files/rspack-module-federation-ssr/src/main.server.tsx__tmpl__ +45 -0
  76. package/src/generators/remote/files/rspack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +6 -0
  77. package/src/generators/remote/files/rspack-module-federation-ssr-ts/rspack.config.ts__tmpl__ +69 -0
  78. package/src/generators/remote/files/rspack-module-federation-ssr-ts/server.ts__tmpl__ +2 -2
  79. package/src/generators/remote/files/rspack-module-federation-ssr-ts/src/main.server.tsx__tmpl__ +45 -0
  80. package/src/generators/remote/files/rspack-module-federation-ts/rspack.config.ts__tmpl__ +40 -13
  81. package/src/generators/remote/lib/setup-ssr-for-remote.d.ts +1 -1
  82. package/src/generators/remote/lib/setup-ssr-for-remote.js +37 -15
  83. package/src/generators/remote/remote.js +46 -30
  84. package/src/plugins/router-plugin.d.ts +10 -0
  85. package/src/plugins/router-plugin.js +219 -0
  86. package/src/rules/update-module-federation-project.d.ts +2 -1
  87. package/src/rules/update-module-federation-project.js +28 -47
  88. package/src/utils/assertion.d.ts +2 -0
  89. package/src/utils/assertion.js +6 -0
  90. package/src/utils/ast-utils.d.ts +1 -1
  91. package/src/utils/ast-utils.js +2 -2
  92. package/src/utils/ct-utils.d.ts +1 -1
  93. package/src/utils/versions.d.ts +6 -4
  94. package/src/utils/versions.js +9 -6
  95. package/src/generators/host/files/rspack-module-federation-ssr/rspack.server.config.js__tmpl__ +0 -16
  96. package/src/generators/host/files/rspack-module-federation-ssr-ts/rspack.server.config.ts__tmpl__ +0 -16
  97. package/src/generators/remote/files/rspack-module-federation-ssr/rspack.server.config.js__tmpl__ +0 -16
  98. package/src/generators/remote/files/rspack-module-federation-ssr-ts/rspack.server.config.ts__tmpl__ +0 -16
  99. package/src/utils/format-file.d.ts +0 -1
  100. package/src/utils/format-file.js +0 -11
@@ -17,12 +17,21 @@ const maybe_js_1 = require("../../utils/maybe-js");
17
17
  const js_1 = require("@nx/js");
18
18
  const versions_1 = require("../../utils/versions");
19
19
  const project_name_and_root_utils_1 = require("@nx/devkit/src/generators/project-name-and-root-utils");
20
+ const create_application_files_1 = require("../application/lib/create-application-files");
20
21
  function addModuleFederationFiles(host, options) {
21
- const templateVariables = {
22
- ...(0, devkit_1.names)(options.projectName),
23
- ...options,
24
- tmpl: '',
25
- };
22
+ const templateVariables = options.bundler === 'rspack'
23
+ ? {
24
+ ...(0, create_application_files_1.getDefaultTemplateVariables)(host, options),
25
+ rspackPluginOptions: {
26
+ ...(0, create_application_files_1.createNxRspackPluginOptions)(options, (0, devkit_1.offsetFromRoot)(options.appProjectRoot), false),
27
+ mainServer: `./server.ts`,
28
+ },
29
+ }
30
+ : {
31
+ ...(0, devkit_1.names)(options.projectName),
32
+ ...options,
33
+ tmpl: '',
34
+ };
26
35
  (0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, `./files/${options.js
27
36
  ? options.bundler === 'rspack'
28
37
  ? 'rspack-common'
@@ -48,43 +57,46 @@ function addModuleFederationFiles(host, options) {
48
57
  async function remoteGenerator(host, schema) {
49
58
  const tasks = [];
50
59
  const options = {
51
- ...(await (0, normalize_options_1.normalizeOptions)(host, schema)),
60
+ ...(await (0, normalize_options_1.normalizeOptions)(host, {
61
+ ...schema,
62
+ useProjectJson: true,
63
+ })),
52
64
  // when js is set to true, we want to use the js configuration
53
65
  js: schema.js ?? false,
54
66
  typescriptConfiguration: schema.js
55
67
  ? false
56
68
  : schema.typescriptConfiguration ?? true,
57
69
  dynamic: schema.dynamic ?? false,
58
- // TODO(colum): remove when MF works with Crystal
59
- addPlugin: false,
70
+ // TODO(colum): remove when Webpack MF works with Crystal
71
+ addPlugin: !schema.bundler || schema.bundler === 'rspack' ? true : false,
60
72
  bundler: schema.bundler ?? 'rspack',
61
73
  };
62
74
  if (options.dynamic) {
63
75
  // Dynamic remotes generate with library { type: 'var' } by default.
64
76
  // We need to ensure that the remote name is a valid variable name.
65
- const isValidRemote = (0, js_1.isValidVariable)(options.name);
77
+ const isValidRemote = (0, js_1.isValidVariable)(options.projectName);
66
78
  if (!isValidRemote.isValid) {
67
- throw new Error(`Invalid remote name provided: ${options.name}. ${isValidRemote.message}`);
79
+ throw new Error(`Invalid remote name provided: ${options.projectName}. ${isValidRemote.message}`);
68
80
  }
69
81
  }
70
- await (0, project_name_and_root_utils_1.ensureProjectName)(host, options, 'application');
82
+ await (0, project_name_and_root_utils_1.ensureRootProjectName)(options, 'application');
71
83
  const REMOTE_NAME_REGEX = '^[a-zA-Z_$][a-zA-Z_$0-9]*$';
72
84
  const remoteNameRegex = new RegExp(REMOTE_NAME_REGEX);
73
- if (!remoteNameRegex.test(options.name)) {
74
- throw new Error((0, devkit_1.stripIndents) `Invalid remote name: ${options.name}. Remote project names must:
85
+ if (!remoteNameRegex.test(options.projectName)) {
86
+ throw new Error((0, devkit_1.stripIndents) `Invalid remote name: ${options.projectName}. Remote project names must:
75
87
  - Start with a letter, dollar sign ($) or underscore (_)
76
88
  - Followed by any valid character (letters, digits, underscores, or dollar signs)
77
89
  The regular expression used is ${REMOTE_NAME_REGEX}.`);
78
90
  }
79
91
  const initAppTask = await (0, application_1.default)(host, {
80
92
  ...options,
81
- name: options.name,
93
+ name: options.projectName,
82
94
  skipFormat: true,
83
- alwaysGenerateProjectJson: true,
95
+ useProjectJson: true,
84
96
  });
85
97
  tasks.push(initAppTask);
86
98
  if (options.host) {
87
- (0, update_host_with_remote_1.updateHostWithRemote)(host, options.host, options.name);
99
+ (0, update_host_with_remote_1.updateHostWithRemote)(host, options.host, options.projectName);
88
100
  }
89
101
  // Module federation requires bootstrap code to be dynamically imported.
90
102
  // Renaming original entry file so we can use `import(./bootstrap)` in
@@ -94,29 +106,33 @@ async function remoteGenerator(host, schema) {
94
106
  (0, update_module_federation_project_1.updateModuleFederationProject)(host, options);
95
107
  (0, setup_tspath_for_remote_1.setupTspathForRemote)(host, options);
96
108
  if (options.ssr) {
97
- const setupSsrTask = await (0, setup_ssr_1.default)(host, {
98
- project: options.projectName,
99
- serverPort: options.devServerPort,
100
- skipFormat: true,
101
- bundler: options.bundler,
102
- });
103
- tasks.push(setupSsrTask);
109
+ if (options.bundler !== 'rspack') {
110
+ const setupSsrTask = await (0, setup_ssr_1.default)(host, {
111
+ project: options.projectName,
112
+ serverPort: options.devServerPort,
113
+ skipFormat: true,
114
+ bundler: options.bundler,
115
+ });
116
+ tasks.push(setupSsrTask);
117
+ }
104
118
  const setupSsrForRemoteTask = await (0, setup_ssr_for_remote_1.setupSsrForRemote)(host, options, options.projectName);
105
119
  tasks.push(setupSsrForRemoteTask);
106
120
  const projectConfig = (0, devkit_1.readProjectConfiguration)(host, options.projectName);
107
- if (options.bundler === 'rspack') {
108
- projectConfig.targets.server.executor = '@nx/rspack:rspack';
109
- projectConfig.targets.server.options.rspackConfig = (0, devkit_1.joinPathFragments)(projectConfig.root, `rspack.server.config.${options.typescriptConfiguration ? 'ts' : 'js'}`);
110
- delete projectConfig.targets.server.options.webpackConfig;
111
- }
112
- else {
121
+ if (options.bundler !== 'rspack') {
113
122
  projectConfig.targets.server.options.webpackConfig = (0, devkit_1.joinPathFragments)(projectConfig.root, `webpack.server.config.${options.typescriptConfiguration ? 'ts' : 'js'}`);
123
+ (0, devkit_1.updateProjectConfiguration)(host, options.projectName, projectConfig);
114
124
  }
115
- (0, devkit_1.updateProjectConfiguration)(host, options.projectName, projectConfig);
116
125
  }
117
126
  if (!options.setParserOptionsProject) {
118
127
  host.delete((0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.lint.json'));
119
128
  }
129
+ if (options.host && options.bundler === 'rspack') {
130
+ const projectConfig = (0, devkit_1.readProjectConfiguration)(host, options.projectName);
131
+ projectConfig.targets.serve ??= {};
132
+ projectConfig.targets.serve.dependsOn ??= [];
133
+ projectConfig.targets.serve.dependsOn.push(`${options.host}:serve`);
134
+ (0, devkit_1.updateProjectConfiguration)(host, options.projectName, projectConfig);
135
+ }
120
136
  if (options.host && options.dynamic) {
121
137
  const hostConfig = (0, devkit_1.readProjectConfiguration)(host, schema.host);
122
138
  const pathToMFManifest = (0, devkit_1.joinPathFragments)(hostConfig.sourceRoot, 'assets/module-federation.manifest.json');
@@ -0,0 +1,10 @@
1
+ import { type CreateNodesV2 } from '@nx/devkit';
2
+ export interface ReactRouterPluginOptions {
3
+ buildTargetName?: string;
4
+ devTargetName?: string;
5
+ startTargetName?: string;
6
+ typecheckTargetName?: string;
7
+ buildDepsTargetName?: string;
8
+ watchDepsTargetName?: string;
9
+ }
10
+ export declare const createNodesV2: CreateNodesV2<ReactRouterPluginOptions>;
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodesV2 = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const path_1 = require("path");
6
+ const fs_1 = require("fs");
7
+ const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
8
+ const cache_directory_1 = require("nx/src/utils/cache-directory");
9
+ const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
10
+ const js_1 = require("@nx/js");
11
+ const devkit_internals_1 = require("nx/src/devkit-internals");
12
+ const util_1 = require("@nx/js/src/plugins/typescript/util");
13
+ const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
14
+ const config_utils_1 = require("@nx/devkit/src/utils/config-utils");
15
+ const pmCommand = (0, devkit_1.getPackageManagerCommand)();
16
+ const reactRouterConfigBlob = '**/react-router.config.{ts,js,cjs,cts,mjs,mts}';
17
+ function readTargetsCache(cachePath) {
18
+ return process.env.NX_CACHE_PROJECT_GRAPH !== 'false' && (0, fs_1.existsSync)(cachePath)
19
+ ? (0, devkit_1.readJsonFile)(cachePath)
20
+ : {};
21
+ }
22
+ function writeTargetsToCache(cachePath, results) {
23
+ (0, devkit_1.writeJsonFile)(cachePath, results);
24
+ }
25
+ exports.createNodesV2 = [
26
+ reactRouterConfigBlob,
27
+ async (configFiles, options, context) => {
28
+ const optionsHash = (0, devkit_internals_1.hashObject)(options);
29
+ const normalizedOptions = normalizeOptions(options);
30
+ const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `react-router-${optionsHash}.hash`);
31
+ const targetsCache = readTargetsCache(cachePath);
32
+ const isUsingTsSolutionSetup = (0, ts_solution_setup_1.isUsingTsSolutionSetup)();
33
+ const { roots: projectRoots, configFiles: validConfigFiles } = configFiles.reduce((acc, configFile) => {
34
+ const potentialRoot = (0, path_1.dirname)(configFile);
35
+ if (checkIfConfigFileShouldBeProject(potentialRoot, context)) {
36
+ acc.roots.push(potentialRoot);
37
+ acc.configFiles.push(configFile);
38
+ }
39
+ return acc;
40
+ }, {
41
+ roots: [],
42
+ configFiles: [],
43
+ });
44
+ const lockfile = (0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot));
45
+ const hashes = await (0, calculate_hash_for_create_nodes_1.calculateHashesForCreateNodes)(projectRoots, { ...normalizedOptions, isUsingTsSolutionSetup }, context, projectRoots.map((_) => [lockfile]));
46
+ try {
47
+ return await (0, devkit_1.createNodesFromFiles)(async (configFile, _, context, idx) => {
48
+ const projectRoot = (0, path_1.dirname)(configFile);
49
+ const siblingFiles = (0, fs_1.readdirSync)((0, devkit_1.joinPathFragments)(context.workspaceRoot, projectRoot));
50
+ const hash = hashes[idx] + configFile;
51
+ const { projectType, metadata, targets } = (targetsCache[hash] ??=
52
+ await buildReactRouterTargets(configFile, projectRoot, normalizedOptions, context, siblingFiles, isUsingTsSolutionSetup));
53
+ const project = {
54
+ root: projectRoot,
55
+ targets,
56
+ metadata,
57
+ };
58
+ if (project.targets[normalizedOptions.buildTargetName]) {
59
+ project.projectType = projectType;
60
+ }
61
+ return {
62
+ projects: {
63
+ [projectRoot]: project,
64
+ },
65
+ };
66
+ }, validConfigFiles, options, context);
67
+ }
68
+ finally {
69
+ writeTargetsToCache(cachePath, targetsCache);
70
+ }
71
+ },
72
+ ];
73
+ async function buildReactRouterTargets(configFilePath, projectRoot, options, context, siblingFiles, isUsingTsSolutionSetup) {
74
+ const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
75
+ const configPath = (0, path_1.join)(context.workspaceRoot, configFilePath);
76
+ if (require.cache[configPath])
77
+ (0, config_utils_1.clearRequireCache)();
78
+ const reactRouterConfig = await (0, config_utils_1.loadConfigFile)(configPath);
79
+ const isLibMode = reactRouterConfig?.ssr !== undefined && reactRouterConfig.ssr === false;
80
+ const { buildDirectory, serverBuildPath } = await getBuildPaths(reactRouterConfig, isLibMode);
81
+ const targets = {};
82
+ targets[options.buildTargetName] = await getBuildTargetConfig(options.buildTargetName, projectRoot, buildDirectory, serverBuildPath, namedInputs, isUsingTsSolutionSetup);
83
+ targets[options.devTargetName] = await devTarget(projectRoot, isUsingTsSolutionSetup);
84
+ if (serverBuildPath) {
85
+ targets[options.startTargetName] = await startTarget(projectRoot, serverBuildPath, options.buildTargetName, isUsingTsSolutionSetup);
86
+ }
87
+ targets[options.typecheckTargetName] = await typecheckTarget(projectRoot, options.typecheckTargetName, namedInputs, siblingFiles, isUsingTsSolutionSetup);
88
+ (0, util_1.addBuildAndWatchDepsTargets)(context.workspaceRoot, projectRoot, targets, options, pmCommand);
89
+ const metadata = {};
90
+ return {
91
+ targets,
92
+ metadata,
93
+ projectType: isLibMode ? 'library' : 'application',
94
+ };
95
+ }
96
+ async function getBuildTargetConfig(buildTargetName, projectRoot, buildDirectory, serverBuildDirectory, namedInputs, isUsingTsSolutionSetup) {
97
+ const basePath = projectRoot === '.'
98
+ ? `{workspaceRoot}`
99
+ : (0, devkit_1.joinPathFragments)(`{workspaceRoot}`, projectRoot);
100
+ const outputs = [
101
+ (0, devkit_1.joinPathFragments)(basePath, buildDirectory),
102
+ ...(serverBuildDirectory
103
+ ? [(0, devkit_1.joinPathFragments)(basePath, serverBuildDirectory)]
104
+ : []),
105
+ ];
106
+ const buildTarget = {
107
+ cache: true,
108
+ dependsOn: [`^${buildTargetName}`],
109
+ inputs: [
110
+ ...('production' in namedInputs
111
+ ? ['production', '^production']
112
+ : ['default', '^default']),
113
+ { externalDependencies: ['@react-router/dev'] },
114
+ ],
115
+ outputs,
116
+ command: 'react-router build',
117
+ options: { cwd: projectRoot },
118
+ };
119
+ if (isUsingTsSolutionSetup) {
120
+ buildTarget.syncGenerators = ['@nx/js:typescript-sync'];
121
+ }
122
+ return buildTarget;
123
+ }
124
+ async function getBuildPaths(reactRouterConfig, isLibMode) {
125
+ return {
126
+ buildDirectory: reactRouterConfig?.buildDirectory ?? 'build/client',
127
+ ...(isLibMode
128
+ ? undefined
129
+ : {
130
+ serverBuildPath: reactRouterConfig?.buildDirectory
131
+ ? (0, path_1.join)((0, path_1.dirname)(reactRouterConfig.buildDirectory), `server`)
132
+ : 'build/server',
133
+ }),
134
+ };
135
+ }
136
+ async function devTarget(projectRoot, isUsingTsSolutionSetup) {
137
+ const devTarget = {
138
+ command: 'react-router dev',
139
+ options: { cwd: projectRoot },
140
+ };
141
+ if (isUsingTsSolutionSetup) {
142
+ devTarget.syncGenerators = ['@nx/js:typescript-sync'];
143
+ }
144
+ return devTarget;
145
+ }
146
+ async function startTarget(projectRoot, serverBuildPath, buildTargetName, isUsingTsSolutionSetup) {
147
+ const serverPath = serverBuildPath === 'build/server'
148
+ ? `${serverBuildPath}/index.js`
149
+ : serverBuildPath;
150
+ const startTarget = {
151
+ dependsOn: [buildTargetName],
152
+ command: `react-router-serve ${serverPath}`,
153
+ options: { cwd: projectRoot },
154
+ };
155
+ if (isUsingTsSolutionSetup) {
156
+ startTarget.syncGenerators = ['@nx/js:typescript-sync'];
157
+ }
158
+ return startTarget;
159
+ }
160
+ async function typecheckTarget(projectRoot, typecheckTargetName, namedInputs, siblingFiles, isUsingTsSolutionSetup) {
161
+ const hasTsConfigAppJson = siblingFiles.includes('tsconfig.app.json');
162
+ const typecheckTarget = {
163
+ cache: true,
164
+ inputs: [
165
+ ...('production' in namedInputs
166
+ ? ['production', '^production']
167
+ : ['default', '^default']),
168
+ { externalDependencies: ['typescript'] },
169
+ ],
170
+ command: isUsingTsSolutionSetup
171
+ ? `tsc --build --emitDeclarationOnly`
172
+ : `tsc${hasTsConfigAppJson ? ` -p tsconfig.app.json` : ``} --noEmit`,
173
+ options: {
174
+ cwd: projectRoot,
175
+ },
176
+ metadata: {
177
+ description: `Runs type-checking for the project.`,
178
+ technologies: ['typescript'],
179
+ help: {
180
+ command: isUsingTsSolutionSetup
181
+ ? `${pmCommand.exec} tsc --build --help`
182
+ : `${pmCommand.exec} tsc${hasTsConfigAppJson ? ` -p tsconfig.app.json` : ``} --help`,
183
+ example: isUsingTsSolutionSetup
184
+ ? { args: ['--force'] }
185
+ : { options: { noEmit: true } },
186
+ },
187
+ },
188
+ };
189
+ if (isUsingTsSolutionSetup) {
190
+ typecheckTarget.dependsOn = [`^${typecheckTargetName}`];
191
+ typecheckTarget.syncGenerators = ['@nx/js:typescript-sync'];
192
+ }
193
+ return typecheckTarget;
194
+ }
195
+ function normalizeOptions(options) {
196
+ options ??= {};
197
+ options.buildTargetName ??= 'build';
198
+ options.devTargetName ??= 'dev';
199
+ options.startTargetName ??= 'start';
200
+ options.typecheckTargetName ??= 'typecheck';
201
+ return options;
202
+ }
203
+ function checkIfConfigFileShouldBeProject(projectRoot, context) {
204
+ // Do not create a project if package.json and project.json isn't there.
205
+ const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
206
+ return hasRequiredConfigs(siblingFiles);
207
+ }
208
+ function hasRequiredConfigs(files) {
209
+ const lowerFiles = files.map((file) => file.toLowerCase());
210
+ // Check if vite.config.{ext} is present
211
+ const hasViteConfig = lowerFiles.some((file) => {
212
+ const parts = file.split('.');
213
+ return parts[0] === 'vite' && parts[1] === 'config' && parts.length > 2;
214
+ });
215
+ if (!hasViteConfig)
216
+ return false;
217
+ const hasProjectOrPackageJson = lowerFiles.includes('project.json') || lowerFiles.includes('package.json');
218
+ return hasProjectOrPackageJson;
219
+ }
@@ -7,4 +7,5 @@ export declare function updateModuleFederationProject(host: Tree, options: {
7
7
  typescriptConfiguration?: boolean;
8
8
  dynamic?: boolean;
9
9
  bundler?: 'rspack' | 'webpack';
10
- }): void;
10
+ ssr?: boolean;
11
+ }, isHost?: boolean): void;
@@ -4,23 +4,9 @@ exports.updateModuleFederationProject = updateModuleFederationProject;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const maybe_js_1 = require("../utils/maybe-js");
6
6
  const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
7
- function updateModuleFederationProject(host, options) {
7
+ function updateModuleFederationProject(host, options, isHost = false) {
8
8
  const projectConfig = (0, devkit_1.readProjectConfiguration)(host, options.projectName);
9
- if (options.bundler === 'rspack') {
10
- projectConfig.targets.build.executor = '@nx/rspack:rspack';
11
- projectConfig.targets.build.options = {
12
- ...(projectConfig.targets.build.options ?? {}),
13
- main: (0, maybe_js_1.maybeJs)({ js: options.js, useJsx: true }, `${options.appProjectRoot}/src/main.ts`),
14
- rspackConfig: `${options.appProjectRoot}/rspack.config.${options.typescriptConfiguration && !options.js ? 'ts' : 'js'}`,
15
- target: 'web',
16
- };
17
- projectConfig.targets.build.configurations ??= {};
18
- projectConfig.targets.build.configurations.production = {
19
- ...(projectConfig.targets.build.configurations?.production ?? {}),
20
- rspackConfig: `${options.appProjectRoot}/rspack.config.prod.${options.typescriptConfiguration && !options.js ? 'ts' : 'js'}`,
21
- };
22
- }
23
- else {
9
+ if (options.bundler !== 'rspack') {
24
10
  projectConfig.targets.build.options = {
25
11
  ...(projectConfig.targets.build.options ?? {}),
26
12
  main: (0, maybe_js_1.maybeJs)(options, `${options.appProjectRoot}/src/main.ts`),
@@ -34,15 +20,7 @@ function updateModuleFederationProject(host, options) {
34
20
  }
35
21
  // If host should be configured to use dynamic federation
36
22
  if (options.dynamic) {
37
- if (options.bundler === 'rspack') {
38
- const pathToProdRspackConfig = (0, devkit_1.joinPathFragments)(projectConfig.root, `rspack.prod.config.${options.typescriptConfiguration && !options.js ? 'ts' : 'js'}`);
39
- if (host.exists(pathToProdRspackConfig)) {
40
- host.delete(pathToProdRspackConfig);
41
- }
42
- delete projectConfig.targets.build.configurations.production
43
- ?.rspackConfig;
44
- }
45
- else {
23
+ if (options.bundler !== 'rspack') {
46
24
  const pathToProdWebpackConfig = (0, devkit_1.joinPathFragments)(projectConfig.root, `webpack.prod.config.${options.typescriptConfiguration && !options.js ? 'ts' : 'js'}`);
47
25
  if (host.exists(pathToProdWebpackConfig)) {
48
26
  host.delete(pathToProdWebpackConfig);
@@ -51,36 +29,39 @@ function updateModuleFederationProject(host, options) {
51
29
  ?.webpackConfig;
52
30
  }
53
31
  }
54
- if (options.bundler === 'rspack') {
55
- projectConfig.targets.serve.executor =
56
- '@nx/rspack:module-federation-dev-server';
57
- }
58
- else {
32
+ if (options.bundler !== 'rspack') {
59
33
  projectConfig.targets.serve.executor =
60
34
  '@nx/react:module-federation-dev-server';
61
35
  }
62
- projectConfig.targets.serve.options.port = options.devServerPort;
36
+ projectConfig.targets.serve ??= {};
37
+ projectConfig.targets.serve.options ??= {};
38
+ projectConfig.targets.serve.options.port =
39
+ options.bundler === 'rspack' && options.ssr && isHost
40
+ ? 4000
41
+ : options.devServerPort;
63
42
  // `serve-static` for remotes that don't need to be in development mode
64
- const serveStaticExecutor = options.bundler === 'rspack'
65
- ? '@nx/rspack:module-federation-static-server'
66
- : '@nx/react:module-federation-static-server';
67
- projectConfig.targets['serve-static'] = {
68
- executor: serveStaticExecutor,
69
- defaultConfiguration: 'production',
70
- options: {
71
- serveTarget: `${options.projectName}:serve`,
72
- },
73
- configurations: {
74
- development: {
75
- serveTarget: `${options.projectName}:serve:development`,
43
+ if (options.bundler !== 'rspack') {
44
+ const serveStaticExecutor = '@nx/react:module-federation-static-server';
45
+ projectConfig.targets['serve-static'] = {
46
+ executor: serveStaticExecutor,
47
+ defaultConfiguration: 'production',
48
+ options: {
49
+ serveTarget: `${options.projectName}:serve`,
76
50
  },
77
- production: {
78
- serveTarget: `${options.projectName}:serve:production`,
51
+ configurations: {
52
+ development: {
53
+ serveTarget: `${options.projectName}:serve:development`,
54
+ },
55
+ production: {
56
+ serveTarget: `${options.projectName}:serve:production`,
57
+ },
79
58
  },
80
- },
81
- };
59
+ };
60
+ }
82
61
  // Typechecks must be performed first before build and serve to generate remote d.ts files.
83
62
  if ((0, ts_solution_setup_1.isUsingTsSolutionSetup)(host)) {
63
+ projectConfig.targets.build ??= {};
64
+ projectConfig.targets.serve ??= {};
84
65
  projectConfig.targets.build.dependsOn = ['^build', 'typecheck'];
85
66
  projectConfig.targets.serve.dependsOn = ['typecheck'];
86
67
  }
@@ -1 +1,3 @@
1
+ import { type Schema } from '../generators/application/schema';
1
2
  export declare function assertValidStyle(style: string): void;
3
+ export declare function assertValidReactRouter(reactRouter: boolean, bundler: Schema['bundler']): void;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.assertValidStyle = assertValidStyle;
4
+ exports.assertValidReactRouter = assertValidReactRouter;
4
5
  const VALID_STYLES = [
5
6
  'css',
6
7
  'scss',
@@ -16,3 +17,8 @@ function assertValidStyle(style) {
16
17
  throw new Error(`Unsupported style option found: ${style}. Valid values are: "${VALID_STYLES.join('", "')}"`);
17
18
  }
18
19
  }
20
+ function assertValidReactRouter(reactRouter, bundler) {
21
+ if (reactRouter && bundler !== 'vite') {
22
+ throw new Error(`Unsupported bundler found: ${bundler}. React Router is only supported with 'vite'.`);
23
+ }
24
+ }
@@ -11,7 +11,7 @@ export declare function findComponentImportPath(componentName: string, source: t
11
11
  export declare function findElements(source: ts.SourceFile, tagName: string): ts.Node[];
12
12
  export declare function findClosestOpening(tagName: string, node: ts.Node): ts.Node;
13
13
  export declare function isTag(tagName: string, node: ts.Node): boolean;
14
- export declare function addInitialRoutes(sourcePath: string, source: ts.SourceFile): StringChange[];
14
+ export declare function addInitialRoutes(sourcePath: string, source: ts.SourceFile, addBrowserRouter?: boolean): StringChange[];
15
15
  export declare function addRoute(sourcePath: string, source: ts.SourceFile, options: {
16
16
  routePath: string;
17
17
  componentName: string;
@@ -234,7 +234,7 @@ function isTag(tagName, node) {
234
234
  }
235
235
  return false;
236
236
  }
237
- function addInitialRoutes(sourcePath, source) {
237
+ function addInitialRoutes(sourcePath, source, addBrowserRouter) {
238
238
  if (!tsModule) {
239
239
  tsModule = (0, ensure_typescript_1.ensureTypescript)();
240
240
  }
@@ -281,7 +281,7 @@ function addInitialRoutes(sourcePath, source) {
281
281
  `,
282
282
  };
283
283
  return [
284
- ...addImport(source, `import { Route, Routes, Link } from 'react-router-dom';`),
284
+ ...addImport(source, `import { Route, Routes, Link ${addBrowserRouter ? ', BrowserRouter ' : ''}} from 'react-router-dom';`),
285
285
  insertRoutes,
286
286
  ];
287
287
  }
@@ -10,5 +10,5 @@ export declare function getBundlerFromTarget(found: FoundTarget, tree: Tree): Pr
10
10
  export declare function getActualBundler(tree: Tree, options: {
11
11
  buildTarget?: string;
12
12
  bundler?: 'vite' | 'webpack';
13
- }, found: FoundTarget): Promise<"vite" | "webpack">;
13
+ }, found: FoundTarget): Promise<"webpack" | "vite">;
14
14
  export declare function isComponent(tree: Tree, filePath: string): boolean;
@@ -14,7 +14,7 @@ export declare const typesReactDomVersion = "19.0.0";
14
14
  export declare const typesReactIsV18Version = "18.3.0";
15
15
  export declare const typesReactIsVersion = "19.0.0";
16
16
  export declare const reactViteVersion = "^4.2.0";
17
- export declare const typesNodeVersion = "18.16.9";
17
+ export declare const typesNodeVersion = "^20.0.0";
18
18
  export declare const babelPresetReactVersion = "^7.14.5";
19
19
  export declare const babelCoreVersion = "^7.14.5";
20
20
  export declare const styledComponentsVersion = "5.3.6";
@@ -23,7 +23,9 @@ export declare const emotionStyledVersion = "11.11.0";
23
23
  export declare const emotionReactVersion = "11.11.1";
24
24
  export declare const emotionBabelPlugin = "11.11.0";
25
25
  export declare const styledJsxVersion = "5.1.2";
26
- export declare const reactRouterDomVersion = "6.11.2";
26
+ export declare const reactRouterDomVersion = "6.29.0";
27
+ export declare const reactRouterVersion = "^7.2.0";
28
+ export declare const reactRouterIsBotVersion = "^4.4.0";
27
29
  export declare const testingLibraryReactVersion = "16.1.0";
28
30
  export declare const testingLibraryDomVersion = "10.4.0";
29
31
  export declare const reduxjsToolkitVersion = "1.9.3";
@@ -42,8 +44,8 @@ export declare const typesExpressVersion = "^4.17.21";
42
44
  export declare const isbotVersion = "^3.6.5";
43
45
  export declare const corsVersion = "~2.8.5";
44
46
  export declare const typesCorsVersion = "~2.8.12";
45
- export declare const moduleFederationNodeVersion = "^2.6.21";
46
- export declare const moduleFederationEnhancedVersion = "^0.8.8";
47
+ export declare const moduleFederationNodeVersion = "^2.6.26";
48
+ export declare const moduleFederationEnhancedVersion = "^0.9.0";
47
49
  export declare const lessVersion = "3.12.2";
48
50
  export declare const sassVersion = "^1.55.0";
49
51
  export declare const rollupPluginUrlVersion = "^8.0.2";
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.svgrRollupVersion = exports.rollupPluginUrlVersion = exports.sassVersion = exports.lessVersion = exports.moduleFederationEnhancedVersion = exports.moduleFederationNodeVersion = exports.typesCorsVersion = exports.corsVersion = exports.isbotVersion = exports.typesExpressVersion = exports.expressVersion = exports.autoprefixerVersion = exports.tailwindcssVersion = exports.postcssVersion = exports.tsLibVersion = exports.babelPluginStyledComponentsVersion = exports.eslintPluginReactHooksVersion = exports.eslintPluginReactVersion = exports.eslintPluginJsxA11yVersion = exports.eslintPluginImportVersion = exports.reactReduxVersion = exports.reduxjsToolkitVersion = exports.testingLibraryDomVersion = exports.testingLibraryReactVersion = exports.reactRouterDomVersion = exports.styledJsxVersion = exports.emotionBabelPlugin = exports.emotionReactVersion = exports.emotionStyledVersion = exports.typesStyledComponentsVersion = exports.styledComponentsVersion = exports.babelCoreVersion = exports.babelPresetReactVersion = exports.typesNodeVersion = exports.reactViteVersion = exports.typesReactIsVersion = exports.typesReactIsV18Version = exports.typesReactDomVersion = exports.typesReactDomV18Version = exports.typesReactVersion = exports.typesReactV18Version = exports.babelLoaderVersion = exports.swcLoaderVersion = exports.reactIsV18Version = exports.reactIsVersion = exports.reactDomV18Version = exports.reactDomVersion = exports.reactV18Version = exports.reactVersion = exports.nxVersion = void 0;
4
- exports.swcPluginStyledComponentsVersion = exports.swcPluginEmotionVersion = exports.swcPluginStyledJsxVersion = void 0;
3
+ exports.sassVersion = exports.lessVersion = exports.moduleFederationEnhancedVersion = exports.moduleFederationNodeVersion = exports.typesCorsVersion = exports.corsVersion = exports.isbotVersion = exports.typesExpressVersion = exports.expressVersion = exports.autoprefixerVersion = exports.tailwindcssVersion = exports.postcssVersion = exports.tsLibVersion = exports.babelPluginStyledComponentsVersion = exports.eslintPluginReactHooksVersion = exports.eslintPluginReactVersion = exports.eslintPluginJsxA11yVersion = exports.eslintPluginImportVersion = exports.reactReduxVersion = exports.reduxjsToolkitVersion = exports.testingLibraryDomVersion = exports.testingLibraryReactVersion = exports.reactRouterIsBotVersion = exports.reactRouterVersion = exports.reactRouterDomVersion = exports.styledJsxVersion = exports.emotionBabelPlugin = exports.emotionReactVersion = exports.emotionStyledVersion = exports.typesStyledComponentsVersion = exports.styledComponentsVersion = exports.babelCoreVersion = exports.babelPresetReactVersion = exports.typesNodeVersion = exports.reactViteVersion = exports.typesReactIsVersion = exports.typesReactIsV18Version = exports.typesReactDomVersion = exports.typesReactDomV18Version = exports.typesReactVersion = exports.typesReactV18Version = exports.babelLoaderVersion = exports.swcLoaderVersion = exports.reactIsV18Version = exports.reactIsVersion = exports.reactDomV18Version = exports.reactDomVersion = exports.reactV18Version = exports.reactVersion = exports.nxVersion = void 0;
4
+ exports.swcPluginStyledComponentsVersion = exports.swcPluginEmotionVersion = exports.swcPluginStyledJsxVersion = exports.svgrRollupVersion = exports.rollupPluginUrlVersion = void 0;
5
5
  exports.nxVersion = require('../../package.json').version;
6
6
  exports.reactVersion = '19.0.0';
7
7
  exports.reactV18Version = '18.3.1';
@@ -18,7 +18,8 @@ exports.typesReactDomVersion = '19.0.0';
18
18
  exports.typesReactIsV18Version = '18.3.0';
19
19
  exports.typesReactIsVersion = '19.0.0';
20
20
  exports.reactViteVersion = '^4.2.0';
21
- exports.typesNodeVersion = '18.16.9';
21
+ // Needed for React-Router
22
+ exports.typesNodeVersion = '^20.0.0';
22
23
  exports.babelPresetReactVersion = '^7.14.5';
23
24
  exports.babelCoreVersion = '^7.14.5';
24
25
  exports.styledComponentsVersion = '5.3.6';
@@ -28,7 +29,9 @@ exports.emotionReactVersion = '11.11.1';
28
29
  exports.emotionBabelPlugin = '11.11.0';
29
30
  // WARNING: This needs to be in sync with Next.js' dependency or else there might be issues.
30
31
  exports.styledJsxVersion = '5.1.2';
31
- exports.reactRouterDomVersion = '6.11.2';
32
+ exports.reactRouterDomVersion = '6.29.0';
33
+ exports.reactRouterVersion = '^7.2.0';
34
+ exports.reactRouterIsBotVersion = '^4.4.0';
32
35
  exports.testingLibraryReactVersion = '16.1.0';
33
36
  exports.testingLibraryDomVersion = '10.4.0';
34
37
  exports.reduxjsToolkitVersion = '1.9.3';
@@ -48,8 +51,8 @@ exports.typesExpressVersion = '^4.17.21';
48
51
  exports.isbotVersion = '^3.6.5';
49
52
  exports.corsVersion = '~2.8.5';
50
53
  exports.typesCorsVersion = '~2.8.12';
51
- exports.moduleFederationNodeVersion = '^2.6.21';
52
- exports.moduleFederationEnhancedVersion = '^0.8.8';
54
+ exports.moduleFederationNodeVersion = '^2.6.26';
55
+ exports.moduleFederationEnhancedVersion = '^0.9.0';
53
56
  // style preprocessors
54
57
  exports.lessVersion = '3.12.2';
55
58
  exports.sassVersion = '^1.55.0';
@@ -1,16 +0,0 @@
1
- const {composePlugins, withNx, withReact} = require('@nx/rspack');
2
- const {withModuleFederationForSSR} = require('@nx/module-federation/rspack');
3
-
4
- const baseConfig = require('./module-federation.config');
5
-
6
- const defaultConfig = {
7
- ...baseConfig
8
- };
9
-
10
- // Nx plugins for rspack to build config object from Nx options and context.
11
- /**
12
- * DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
13
- * The DTS Plugin can be enabled by setting dts: true
14
- * Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
15
- */
16
- module.exports = composePlugins(withNx(), withReact({ssr: true}), withModuleFederationForSSR(defaultConfig, { dts: false }));
@@ -1,16 +0,0 @@
1
- import {composePlugins, withNx, withReact} from '@nx/rspack';
2
- import {withModuleFederationForSSR} from '@nx/module-federation/rspack';
3
-
4
- import baseConfig from './module-federation.config';
5
-
6
- const defaultConfig = {
7
- ...baseConfig
8
- };
9
-
10
- // Nx plugins for rspack to build config object from Nx options and context.
11
- /**
12
- * DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
13
- * The DTS Plugin can be enabled by setting dts: true
14
- * Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
15
- */
16
- export default composePlugins(withNx(), withReact({ssr: true}), withModuleFederationForSSR(defaultConfig, { dts: false }));