@nx/react 19.7.0-beta.4 → 19.7.0-beta.6

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 (87) hide show
  1. package/package.json +6 -6
  2. package/src/generators/application/application.js +4 -1
  3. package/src/generators/application/lib/add-routing.js +4 -1
  4. package/src/generators/application/lib/create-application-files.js +5 -2
  5. package/src/generators/federate-module/federate-module.js +5 -1
  6. package/src/generators/federate-module/schema.d.ts +1 -0
  7. package/src/generators/federate-module/schema.json +6 -0
  8. package/src/generators/host/files/rspack-common/src/app/__fileName__.jsx__tmpl__ +33 -0
  9. package/src/generators/host/files/rspack-common/src/main.jsx__tmpl__ +10 -0
  10. package/src/generators/host/files/rspack-module-federation/rspack.config.js__tmpl__ +16 -0
  11. package/src/generators/host/files/rspack-module-federation/rspack.config.prod.js__tmpl__ +36 -0
  12. package/src/generators/host/files/rspack-module-federation-ssr/module-federation.server.config.js__tmpl__ +16 -0
  13. package/src/generators/host/files/rspack-module-federation-ssr/rspack.server.config.js__tmpl__ +16 -0
  14. package/src/generators/host/files/rspack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +13 -0
  15. package/src/generators/host/files/rspack-module-federation-ssr-ts/rspack.server.config.ts__tmpl__ +16 -0
  16. package/src/generators/host/files/rspack-module-federation-ts/module-federation.config.ts__tmpl__ +25 -0
  17. package/src/generators/host/files/rspack-module-federation-ts/rspack.config.prod.ts__tmpl__ +36 -0
  18. package/src/generators/host/files/rspack-module-federation-ts/rspack.config.ts__tmpl__ +16 -0
  19. package/src/generators/host/files/webpack-module-federation/module-federation.config.js__tmpl__ +21 -0
  20. package/src/generators/host/files/webpack-module-federation-ssr/server.ts__tmpl__ +28 -0
  21. package/src/generators/host/files/webpack-module-federation-ssr/tsconfig.server.json__tmpl__ +17 -0
  22. package/src/generators/host/files/webpack-module-federation-ssr-ts/server.ts__tmpl__ +28 -0
  23. package/src/generators/host/files/webpack-module-federation-ssr-ts/tsconfig.server.json__tmpl__ +17 -0
  24. package/src/generators/host/host.js +10 -3
  25. package/src/generators/host/lib/add-module-federation-files.js +23 -11
  26. package/src/generators/host/lib/setup-ssr-for-host.js +6 -3
  27. package/src/generators/host/schema.d.ts +1 -0
  28. package/src/generators/host/schema.json +8 -0
  29. package/src/generators/remote/files/rspack-common/src/main.jsx__tmpl__ +1 -0
  30. package/src/generators/remote/files/rspack-common/src/remote-entry.js__tmpl__ +1 -0
  31. package/src/generators/remote/files/rspack-module-federation/rspack.config.js__tmpl__ +16 -0
  32. package/src/generators/remote/files/rspack-module-federation/rspack.config.prod.js__tmpl__ +1 -0
  33. package/src/generators/remote/files/rspack-module-federation-ssr/module-federation.server.config.js__tmpl__ +6 -0
  34. package/src/generators/remote/files/rspack-module-federation-ssr/rspack.server.config.js__tmpl__ +16 -0
  35. package/src/generators/remote/files/rspack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +10 -0
  36. package/src/generators/remote/files/rspack-module-federation-ssr-ts/rspack.server.config.ts__tmpl__ +16 -0
  37. package/src/generators/remote/files/rspack-module-federation-ssr-ts/tsconfig.lint.json__tmpl__ +19 -0
  38. package/src/generators/remote/files/rspack-module-federation-ts/module-federation.config.ts__tmpl__ +13 -0
  39. package/src/generators/remote/files/rspack-module-federation-ts/rspack.config.prod.ts__tmpl__ +1 -0
  40. package/src/generators/remote/files/rspack-module-federation-ts/rspack.config.ts__tmpl__ +16 -0
  41. package/src/generators/remote/files/rspack-module-federation-ts/tsconfig.lint.json__tmpl__ +19 -0
  42. package/src/generators/remote/files/webpack-module-federation/module-federation.config.js__tmpl__ +9 -0
  43. package/src/generators/remote/files/webpack-module-federation-ssr/server.ts__tmpl__ +45 -0
  44. package/src/generators/remote/files/webpack-module-federation-ssr-ts/server.ts__tmpl__ +45 -0
  45. package/src/generators/remote/files/webpack-module-federation-ts/tsconfig.lint.json__tmpl__ +19 -0
  46. package/src/generators/remote/lib/setup-ssr-for-remote.js +2 -2
  47. package/src/generators/remote/lib/update-host-with-remote.js +4 -0
  48. package/src/generators/remote/remote.js +24 -11
  49. package/src/generators/remote/schema.d.ts +1 -0
  50. package/src/generators/remote/schema.json +8 -0
  51. package/src/generators/setup-ssr/schema.d.ts +1 -0
  52. package/src/generators/setup-ssr/schema.json +6 -0
  53. package/src/generators/setup-ssr/setup-ssr.js +11 -3
  54. package/src/module-federation/utils.js +1 -1
  55. package/src/module-federation/with-module-federation.js +2 -11
  56. package/src/rules/update-module-federation-project.d.ts +1 -0
  57. package/src/rules/update-module-federation-project.js +47 -15
  58. package/src/utils/maybe-js.d.ts +1 -0
  59. package/src/utils/maybe-js.js +1 -1
  60. /package/src/generators/{remote/files/module-federation-ssr-ts → host/files/rspack-common}/tsconfig.lint.json__tmpl__ +0 -0
  61. /package/src/generators/host/files/{module-federation → rspack-module-federation}/module-federation.config.js__tmpl__ +0 -0
  62. /package/src/generators/host/files/{module-federation-ssr → rspack-module-federation-ssr}/server.ts__tmpl__ +0 -0
  63. /package/src/generators/host/files/{module-federation-ssr → rspack-module-federation-ssr}/tsconfig.server.json__tmpl__ +0 -0
  64. /package/src/generators/host/files/{module-federation-ssr-ts → rspack-module-federation-ssr-ts}/server.ts__tmpl__ +0 -0
  65. /package/src/generators/host/files/{module-federation-ssr-ts → rspack-module-federation-ssr-ts}/tsconfig.server.json__tmpl__ +0 -0
  66. /package/src/generators/host/files/{module-federation → webpack-module-federation}/webpack.config.js__tmpl__ +0 -0
  67. /package/src/generators/host/files/{module-federation → webpack-module-federation}/webpack.config.prod.js__tmpl__ +0 -0
  68. /package/src/generators/host/files/{module-federation-ssr → webpack-module-federation-ssr}/module-federation.server.config.js__tmpl__ +0 -0
  69. /package/src/generators/host/files/{module-federation-ssr → webpack-module-federation-ssr}/webpack.server.config.js__tmpl__ +0 -0
  70. /package/src/generators/host/files/{module-federation-ssr-ts → webpack-module-federation-ssr-ts}/module-federation.server.config.ts__tmpl__ +0 -0
  71. /package/src/generators/host/files/{module-federation-ssr-ts → webpack-module-federation-ssr-ts}/webpack.server.config.ts__tmpl__ +0 -0
  72. /package/src/generators/host/files/{module-federation-ts → webpack-module-federation-ts}/module-federation.config.ts__tmpl__ +0 -0
  73. /package/src/generators/host/files/{module-federation-ts → webpack-module-federation-ts}/webpack.config.prod.ts__tmpl__ +0 -0
  74. /package/src/generators/host/files/{module-federation-ts → webpack-module-federation-ts}/webpack.config.ts__tmpl__ +0 -0
  75. /package/src/generators/remote/files/{module-federation → rspack-module-federation}/module-federation.config.js__tmpl__ +0 -0
  76. /package/src/generators/remote/files/{module-federation-ssr → rspack-module-federation-ssr}/server.ts__tmpl__ +0 -0
  77. /package/src/generators/remote/files/{module-federation-ssr-ts → rspack-module-federation-ssr-ts}/server.ts__tmpl__ +0 -0
  78. /package/src/generators/remote/files/{module-federation → webpack-module-federation}/webpack.config.js__tmpl__ +0 -0
  79. /package/src/generators/remote/files/{module-federation → webpack-module-federation}/webpack.config.prod.js__tmpl__ +0 -0
  80. /package/src/generators/remote/files/{module-federation-ssr → webpack-module-federation-ssr}/module-federation.server.config.js__tmpl__ +0 -0
  81. /package/src/generators/remote/files/{module-federation-ssr → webpack-module-federation-ssr}/webpack.server.config.js__tmpl__ +0 -0
  82. /package/src/generators/remote/files/{module-federation-ssr-ts → webpack-module-federation-ssr-ts}/module-federation.server.config.ts__tmpl__ +0 -0
  83. /package/src/generators/remote/files/{module-federation-ts → webpack-module-federation-ssr-ts}/tsconfig.lint.json__tmpl__ +0 -0
  84. /package/src/generators/remote/files/{module-federation-ssr-ts → webpack-module-federation-ssr-ts}/webpack.server.config.ts__tmpl__ +0 -0
  85. /package/src/generators/remote/files/{module-federation-ts → webpack-module-federation-ts}/module-federation.config.ts__tmpl__ +0 -0
  86. /package/src/generators/remote/files/{module-federation-ts → webpack-module-federation-ts}/webpack.config.prod.ts__tmpl__ +0 -0
  87. /package/src/generators/remote/files/{module-federation-ts → webpack-module-federation-ts}/webpack.config.ts__tmpl__ +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/react",
3
- "version": "19.7.0-beta.4",
3
+ "version": "19.7.0-beta.6",
4
4
  "private": false,
5
5
  "description": "The React plugin for Nx contains executors and generators for managing React applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Vitest, Playwright, Cypress, and Storybook.\n\n- Generators for applications, libraries, components, hooks, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
6
6
  "repository": {
@@ -39,11 +39,11 @@
39
39
  "minimatch": "9.0.3",
40
40
  "tslib": "^2.3.0",
41
41
  "@module-federation/enhanced": "~0.6.0",
42
- "@nx/devkit": "19.7.0-beta.4",
43
- "@nx/js": "19.7.0-beta.4",
44
- "@nx/eslint": "19.7.0-beta.4",
45
- "@nx/web": "19.7.0-beta.4",
46
- "@nrwl/react": "19.7.0-beta.4"
42
+ "@nx/devkit": "19.7.0-beta.6",
43
+ "@nx/js": "19.7.0-beta.6",
44
+ "@nx/eslint": "19.7.0-beta.6",
45
+ "@nx/web": "19.7.0-beta.6",
46
+ "@nrwl/react": "19.7.0-beta.6"
47
47
  },
48
48
  "publishConfig": {
49
49
  "access": "public"
@@ -153,7 +153,10 @@ async function applicationGeneratorInternal(host, schema) {
153
153
  const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/rspack', versions_1.nxRspackVersion);
154
154
  const rspackTask = await configurationGenerator(host, {
155
155
  project: options.projectName,
156
- main: (0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)(options, `src/main.tsx`)),
156
+ main: (0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)({
157
+ js: options.js,
158
+ useJsx: true,
159
+ }, `src/main.tsx`)),
157
160
  tsConfig: (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.app.json'),
158
161
  target: 'web',
159
162
  newProject: true,
@@ -14,7 +14,10 @@ function addRouting(host, options) {
14
14
  if (!tsModule) {
15
15
  tsModule = (0, ensure_typescript_1.ensureTypescript)();
16
16
  }
17
- const appPath = (0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)(options, `src/app/${options.fileName}.tsx`));
17
+ const appPath = (0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)({
18
+ js: options.js,
19
+ useJsx: options.bundler === 'vite' || options.bundler === 'rspack',
20
+ }, `src/app/${options.fileName}.tsx`));
18
21
  const appFileContent = host.read(appPath, 'utf-8');
19
22
  const appSource = tsModule.createSourceFile(appPath, appFileContent, tsModule.ScriptTarget.Latest, true);
20
23
  const changes = (0, devkit_1.applyChangesToString)(appFileContent, (0, ast_utils_1.addInitialRoutes)(appPath, appSource));
@@ -126,7 +126,7 @@ async function createApplicationFiles(host, options) {
126
126
  (0, devkit_1.generateFiles)(host, (0, path_1.join)(__dirname, styleSolutionSpecificAppFiles), options.appProjectRoot, templateVariables);
127
127
  if (options.js) {
128
128
  (0, devkit_1.toJS)(host, {
129
- useJsx: options.bundler === 'vite',
129
+ useJsx: options.bundler === 'vite' || options.bundler === 'rspack',
130
130
  });
131
131
  }
132
132
  (0, create_ts_config_1.createTsConfig)(host, options.appProjectRoot, 'app', options, relativePathToRootTsConfig);
@@ -140,7 +140,10 @@ function createNxWebpackPluginOptions(options) {
140
140
  : options.projectName),
141
141
  index: './src/index.html',
142
142
  baseHref: '/',
143
- main: (0, maybe_js_1.maybeJs)(options, `./src/main.tsx`),
143
+ main: (0, maybe_js_1.maybeJs)({
144
+ js: options.js,
145
+ useJsx: options.bundler === 'vite' || options.bundler === 'rspack',
146
+ }, `./src/main.tsx`),
144
147
  tsConfig: './tsconfig.app.json',
145
148
  assets: ['./src/favicon.ico', './src/assets'],
146
149
  styles: options.styledModule || !options.hasStyles
@@ -29,6 +29,7 @@ async function federateModuleGenerator(tree, schema) {
29
29
  unitTestRunner: schema.unitTestRunner,
30
30
  host: schema.host,
31
31
  projectNameAndRootFormat: schema.projectNameAndRootFormat ?? 'derived',
32
+ bundler: schema.bundler ?? 'rspack',
32
33
  });
33
34
  tasks.push(remoteGenerator);
34
35
  const { projectName, projectRoot: remoteRoot } = await (0, project_name_and_root_utils_1.determineProjectNameAndRootOptions)(tree, {
@@ -46,7 +47,10 @@ async function federateModuleGenerator(tree, schema) {
46
47
  remoteName = remote.name;
47
48
  }
48
49
  // add path to exposes property
49
- (0, utils_1.addPathToExposes)(tree, projectRoot, schema.name, schema.path);
50
+ const normalizedModulePath = schema.bundler === 'rspack'
51
+ ? (0, devkit_1.joinPathFragments)((0, devkit_1.offsetFromRoot)(projectRoot), schema.path)
52
+ : schema.path;
53
+ (0, utils_1.addPathToExposes)(tree, projectRoot, schema.name, normalizedModulePath);
50
54
  // Add new path to tsconfig
51
55
  const rootJSON = (0, devkit_1.readJson)(tree, (0, js_1.getRootTsConfigPathInTree)(tree));
52
56
  if (!rootJSON?.compilerOptions?.paths[`${remoteName}/${schema.name}`]) {
@@ -12,4 +12,5 @@ export interface Schema {
12
12
  skipFormat?: boolean;
13
13
  style?: SupportedStyles;
14
14
  unitTestRunner?: 'jest' | 'vitest' | 'none';
15
+ bundler?: 'rspack' | 'webpack';
15
16
  }
@@ -76,6 +76,12 @@
76
76
  "host": {
77
77
  "type": "string",
78
78
  "description": "The host / shell application for this remote."
79
+ },
80
+ "bundler": {
81
+ "description": "The bundler to use.",
82
+ "type": "string",
83
+ "enum": ["rspack", "webpack"],
84
+ "default": "rspack"
79
85
  }
80
86
  },
81
87
  "required": ["name", "path", "remote"],
@@ -0,0 +1,33 @@
1
+ import * as React from 'react';
2
+ <% if (!minimal) { %>
3
+ import NxWelcome from "./nx-welcome";
4
+ <% } %>
5
+ import { Link, Route, Routes } from 'react-router-dom';
6
+
7
+ <% if (remotes.length > 0) { %>
8
+ <% remotes.forEach(function(r) { %>
9
+ const <%= r.className %> = React.lazy(() => import('<%= r.fileName %>/Module'));
10
+ <% }); %>
11
+ <% } %>
12
+ export function App() {
13
+ return (
14
+ <React.Suspense fallback={null}>
15
+ <ul>
16
+ <li><Link to="/">Home</Link></li>
17
+ <% remotes.forEach(function(r) { %>
18
+ <li><Link to="/<%=r.fileName%>"><%=r.className%></Link></li>
19
+ <% }); %>
20
+ </ul>
21
+ <Routes>
22
+ <% if (!minimal) { %>
23
+ <Route path="/" element={<NxWelcome title="<%= projectName %>"/>} />
24
+ <% } %>
25
+ <% remotes.forEach(function(r) { %>
26
+ <Route path="/<%=r.fileName%>" element={<<%= r.className %>/>} />
27
+ <% }); %>
28
+ </Routes>
29
+ </React.Suspense>
30
+ );
31
+ }
32
+
33
+ export default App;
@@ -0,0 +1,10 @@
1
+ <% if (dynamic) { %>
2
+ import { setRemoteDefinitions } from '@nx/react/mf';
3
+
4
+ fetch('/assets/module-federation.manifest.json')
5
+ .then((res) => res.json())
6
+ .then(definitions => setRemoteDefinitions(definitions))
7
+ .then(() => import('./bootstrap').catch(err => console.error(err)));
8
+ <% } else { %>
9
+ import('./bootstrap').catch(err => console.error(err));
10
+ <% } %>
@@ -0,0 +1,16 @@
1
+ const { composePlugins, withNx, withReact } = require('@nx/rspack');
2
+ const { withModuleFederation } = require('@nx/rspack/module-federation');
3
+
4
+ const baseConfig = require('./module-federation.config');
5
+
6
+ const config = {
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(), withModuleFederation(config, { dts: false }));
@@ -0,0 +1,36 @@
1
+ const { composePlugins, withNx, withReact } = require('@nx/rspack');
2
+ const { withModuleFederation } = require('@nx/rspack/module-federation');
3
+
4
+ const baseConfig = require('./module-federation.config');
5
+
6
+ const prodConfig = {
7
+ ...baseConfig,
8
+ /*
9
+ * Remote overrides for production.
10
+ * Each entry is a pair of a unique name and the URL where it is deployed.
11
+ *
12
+ * e.g.
13
+ * remotes: [
14
+ * ['app1', 'http://app1.example.com'],
15
+ * ['app2', 'http://app2.example.com'],
16
+ * ]
17
+ *
18
+ * You can also use a full path to the remoteEntry.js file if desired.
19
+ *
20
+ * remotes: [
21
+ * ['app1', 'http://example.com/path/to/app1/remoteEntry.js'],
22
+ * ['app2', 'http://example.com/path/to/app2/remoteEntry.js'],
23
+ * ]
24
+ */
25
+ remotes: [
26
+ <% remotes.forEach(function(r) {%>['<%= r.fileName %>', 'http://localhost:<%= r.port %>/'],<% }); %>
27
+ ],
28
+ };
29
+
30
+ // Nx plugins for rspack to build config object from Nx options and context.
31
+ /**
32
+ * DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
33
+ * The DTS Plugin can be enabled by setting dts: true
34
+ * Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
35
+ */
36
+ module.exports = composePlugins(withNx(), withReact(), withModuleFederation(prodConfig, { dts: false }));
@@ -0,0 +1,16 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @type {import('@nx/rspack/module-federation').ModuleFederationConfig}
5
+ **/
6
+ const moduleFederationConfig = {
7
+ name: '<%= projectName %>',
8
+ remotes: [
9
+ <% if (static) {
10
+ remotes.forEach(function(r) { %> "<%= r.fileName %>", <% });
11
+ }
12
+ %>
13
+ ],
14
+ };
15
+
16
+ module.exports = moduleFederationConfig;
@@ -0,0 +1,16 @@
1
+ const {composePlugins, withNx, withReact} = require('@nx/rspack');
2
+ const {withModuleFederationForSSR} = require('@nx/rspack/module-federation');
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 }));
@@ -0,0 +1,13 @@
1
+ import { ModuleFederationConfig } from '@nx/rspack/module-federation';
2
+
3
+ const config: ModuleFederationConfig = {
4
+ name: '<%= projectName %>',
5
+ remotes: [
6
+ <% if (static) {
7
+ remotes.forEach(function(r) { %> "<%= r.fileName %>", <% });
8
+ }
9
+ %>
10
+ ],
11
+ };
12
+
13
+ export default config;
@@ -0,0 +1,16 @@
1
+ import {composePlugins, withNx, withReact} from '@nx/rspack';
2
+ import {withModuleFederationForSSR} from '@nx/rspack/module-federation';
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 }));
@@ -0,0 +1,25 @@
1
+ import { ModuleFederationConfig } from '@nx/rspack/module-federation';
2
+
3
+ const config: ModuleFederationConfig = {
4
+ name: '<%= projectName %>',
5
+ /**
6
+ * To use a remote that does not exist in your current Nx Workspace
7
+ * You can use the tuple-syntax to define your remote
8
+ *
9
+ * remotes: [['my-external-remote', 'https://nx-angular-remote.netlify.app']]
10
+ *
11
+ * You _may_ need to add a `remotes.d.ts` file to your `src/` folder declaring the external remote for tsc, with the
12
+ * following content:
13
+ *
14
+ * declare module 'my-external-remote';
15
+ *
16
+ */
17
+ remotes: [
18
+ <% if (static) {
19
+ remotes.forEach(function(r) { %> "<%= r.fileName %>", <% });
20
+ }
21
+ %>
22
+ ],
23
+ };
24
+
25
+ export default config;
@@ -0,0 +1,36 @@
1
+ import { composePlugins, withNx, withReact } from '@nx/rspack';
2
+ import { withModuleFederation, ModuleFederationConfig } from '@nx/rspack/module-federation';
3
+
4
+ import baseConfig from './module-federation.config';
5
+
6
+ const prodConfig: ModuleFederationConfig = {
7
+ ...baseConfig,
8
+ /*
9
+ * Remote overrides for production.
10
+ * Each entry is a pair of a unique name and the URL where it is deployed.
11
+ *
12
+ * e.g.
13
+ * remotes: [
14
+ * ['app1', 'http://app1.example.com'],
15
+ * ['app2', 'http://app2.example.com'],
16
+ * ]
17
+ *
18
+ * You can also use a full path to the remoteEntry.js file if desired.
19
+ *
20
+ * remotes: [
21
+ * ['app1', 'http://example.com/path/to/app1/remoteEntry.js'],
22
+ * ['app2', 'http://example.com/path/to/app2/remoteEntry.js'],
23
+ * ]
24
+ */
25
+ remotes: [
26
+ <% remotes.forEach(function(r) {%>['<%= r.fileName %>', 'http://localhost:<%= r.port %>/'],<% }); %>
27
+ ],
28
+ };
29
+
30
+ // Nx plugins for rspack to build config object from Nx options and context.
31
+ /**
32
+ * DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
33
+ * The DTS Plugin can be enabled by setting dts: true
34
+ * Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
35
+ */
36
+ export default composePlugins(withNx(), withReact(), withModuleFederation(prodConfig, { dts: false }));
@@ -0,0 +1,16 @@
1
+ import {composePlugins, withNx, withReact} from '@nx/rspack';
2
+ import {withModuleFederation, ModuleFederationConfig} from '@nx/rspack/module-federation';
3
+
4
+ import baseConfig from './module-federation.config';
5
+
6
+ const config: ModuleFederationConfig = {
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(), withModuleFederation(config, { dts: false }));
@@ -0,0 +1,21 @@
1
+ module.exports = {
2
+ name: '<%= projectName %>',
3
+ /**
4
+ * To use a remote that does not exist in your current Nx Workspace
5
+ * You can use the tuple-syntax to define your remote
6
+ *
7
+ * remotes: [['my-external-remote', 'https://nx-angular-remote.netlify.app']]
8
+ *
9
+ * You _may_ need to add a `remotes.d.ts` file to your `src/` folder declaring the external remote for tsc, with the
10
+ * following content:
11
+ *
12
+ * declare module 'my-external-remote';
13
+ *
14
+ */
15
+ remotes: [
16
+ <% if (static) {
17
+ remotes.forEach(function(r) { %> "<%= r.fileName %>", <% });
18
+ }
19
+ %>
20
+ ],
21
+ };
@@ -0,0 +1,28 @@
1
+ import * as path from 'path';
2
+ import express from 'express';
3
+ import cors from 'cors';
4
+
5
+ import { handleRequest } from './src/main.server';
6
+
7
+ const port = process.env['PORT'] || <%= port %>;
8
+ const app = express();
9
+
10
+ const browserDist = path.join(process.cwd(), '<%= browserBuildOutputPath %>');
11
+ const indexPath = path.join(browserDist, 'index.html');
12
+
13
+ app.use(cors());
14
+
15
+ app.get(
16
+ '*.*',
17
+ express.static(browserDist, {
18
+ maxAge: '1y',
19
+ })
20
+ );
21
+
22
+ app.use('*', handleRequest(indexPath));
23
+
24
+ const server = app.listen(port, () => {
25
+ console.log(`Express server listening on http://localhost:${port}`);
26
+ });
27
+
28
+ server.on('error', console.error);
@@ -0,0 +1,17 @@
1
+ {
2
+ "extends": "./tsconfig.app.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../out-tsc/server",
5
+ "target": "es2019",
6
+ "types": [
7
+ "node",
8
+ "@nx/react/typings/cssmodule.d.ts",
9
+ "@nx/react/typings/image.d.ts"
10
+ ]
11
+ },
12
+ "include": [
13
+ "src/remotes.d.ts",
14
+ "src/main.server.tsx",
15
+ "server.ts"
16
+ ]
17
+ }
@@ -0,0 +1,28 @@
1
+ import * as path from 'path';
2
+ import express from 'express';
3
+ import cors from 'cors';
4
+
5
+ import { handleRequest } from './src/main.server';
6
+
7
+ const port = process.env['PORT'] || <%= port %>;
8
+ const app = express();
9
+
10
+ const browserDist = path.join(process.cwd(), '<%= browserBuildOutputPath %>');
11
+ const indexPath = path.join(browserDist, 'index.html');
12
+
13
+ app.use(cors());
14
+
15
+ app.get(
16
+ '*.*',
17
+ express.static(browserDist, {
18
+ maxAge: '1y',
19
+ })
20
+ );
21
+
22
+ app.use('*', handleRequest(indexPath));
23
+
24
+ const server = app.listen(port, () => {
25
+ console.log(`Express server listening on http://localhost:${port}`);
26
+ });
27
+
28
+ server.on('error', console.error);
@@ -0,0 +1,17 @@
1
+ {
2
+ "extends": "./tsconfig.app.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../out-tsc/server",
5
+ "target": "es2019",
6
+ "types": [
7
+ "node",
8
+ "@nx/react/typings/cssmodule.d.ts",
9
+ "@nx/react/typings/image.d.ts"
10
+ ]
11
+ },
12
+ "include": [
13
+ "src/remotes.d.ts",
14
+ "src/main.server.tsx",
15
+ "server.ts"
16
+ ]
17
+ }
@@ -32,6 +32,7 @@ async function hostGeneratorInternal(host, schema) {
32
32
  dynamic: schema.dynamic ?? false,
33
33
  // TODO(colum): remove when MF works with Crystal
34
34
  addPlugin: false,
35
+ bundler: schema.bundler ?? 'rspack',
35
36
  };
36
37
  // Check to see if remotes are provided and also check if --dynamic is provided
37
38
  // if both are check that the remotes are valid names else throw an error.
@@ -47,8 +48,6 @@ async function hostGeneratorInternal(host, schema) {
47
48
  ...options,
48
49
  // The target use-case is loading remotes as child routes, thus always enable routing.
49
50
  routing: true,
50
- // Only webpack works with module federation for now.
51
- bundler: 'webpack',
52
51
  skipFormat: true,
53
52
  });
54
53
  tasks.push(initTask);
@@ -74,6 +73,7 @@ async function hostGeneratorInternal(host, schema) {
74
73
  dynamic: options.dynamic,
75
74
  host: options.name,
76
75
  skipPackageJson: options.skipPackageJson,
76
+ bundler: options.bundler,
77
77
  });
78
78
  tasks.push(remoteTask);
79
79
  remotePort++;
@@ -92,7 +92,14 @@ async function hostGeneratorInternal(host, schema) {
92
92
  const setupSsrForHostTask = await (0, setup_ssr_for_host_1.setupSsrForHost)(host, options, options.projectName, remotesWithPorts);
93
93
  tasks.push(setupSsrForHostTask);
94
94
  const projectConfig = (0, devkit_1.readProjectConfiguration)(host, options.projectName);
95
- projectConfig.targets.server.options.webpackConfig = (0, devkit_1.joinPathFragments)(projectConfig.root, `webpack.server.config.${options.typescriptConfiguration ? 'ts' : 'js'}`);
95
+ if (options.bundler === 'rspack') {
96
+ projectConfig.targets.server.executor = '@nx/rspack:rspack';
97
+ projectConfig.targets.server.options.rspackConfig = (0, devkit_1.joinPathFragments)(projectConfig.root, `rspack.server.config.${options.typescriptConfiguration ? 'ts' : 'js'}`);
98
+ delete projectConfig.targets.server.options.webpackConfig;
99
+ }
100
+ else {
101
+ projectConfig.targets.server.options.webpackConfig = (0, devkit_1.joinPathFragments)(projectConfig.root, `webpack.server.config.${options.typescriptConfiguration ? 'ts' : 'js'}`);
102
+ }
96
103
  (0, devkit_1.updateProjectConfiguration)(host, options.projectName, projectConfig);
97
104
  }
98
105
  if (!options.setParserOptionsProject) {
@@ -21,11 +21,15 @@ function addModuleFederationFiles(host, options, defaultRemoteManifest) {
21
21
  // Module federation requires bootstrap code to be dynamically imported.
22
22
  // Renaming original entry file so we can use `import(./bootstrap)` in
23
23
  // new entry file.
24
- host.rename((0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)(options, 'src/main.tsx')), (0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)(options, 'src/bootstrap.tsx')));
25
- (0, devkit_1.generateFiles)(host, (0, devkit_1.joinPathFragments)(__dirname, `../files/${options.js ? 'common' : 'common-ts'}`), options.appProjectRoot, templateVariables);
24
+ host.rename((0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)({ js: options.js, useJsx: options.bundler === 'rspack' }, 'src/main.tsx')), (0, devkit_1.joinPathFragments)(options.appProjectRoot, (0, maybe_js_1.maybeJs)({ js: options.js, useJsx: options.bundler === 'rspack' }, 'src/bootstrap.tsx')));
25
+ (0, devkit_1.generateFiles)(host, (0, devkit_1.joinPathFragments)(__dirname, `../files/${options.js
26
+ ? options.bundler === 'rspack'
27
+ ? 'rspack-common'
28
+ : 'common'
29
+ : 'common-ts'}`), options.appProjectRoot, templateVariables);
26
30
  const pathToModuleFederationFiles = options.typescriptConfiguration
27
- ? 'module-federation-ts'
28
- : 'module-federation';
31
+ ? `${options.bundler === 'rspack' ? 'rspack-' : 'webpack-'}module-federation-ts`
32
+ : `${options.bundler === 'rspack' ? 'rspack-' : 'webpack-'}module-federation`;
29
33
  // New entry file is created here.
30
34
  (0, devkit_1.generateFiles)(host, (0, devkit_1.joinPathFragments)(__dirname, `../files/${pathToModuleFederationFiles}`), options.appProjectRoot, templateVariables);
31
35
  function deleteFileIfExists(host, filePath) {
@@ -33,17 +37,25 @@ function addModuleFederationFiles(host, options, defaultRemoteManifest) {
33
37
  host.delete(filePath);
34
38
  }
35
39
  }
36
- function processWebpackConfig(options, host, fileName) {
37
- const pathToWebpackConfig = (0, devkit_1.joinPathFragments)(options.appProjectRoot, fileName);
38
- deleteFileIfExists(host, pathToWebpackConfig);
40
+ function processBundlerConfigFile(options, host, fileName) {
41
+ const pathToBundlerConfig = (0, devkit_1.joinPathFragments)(options.appProjectRoot, fileName);
42
+ deleteFileIfExists(host, pathToBundlerConfig);
39
43
  }
40
44
  if (options.typescriptConfiguration) {
41
- processWebpackConfig(options, host, 'webpack.config.js');
42
- processWebpackConfig(options, host, 'webpack.config.prod.js');
45
+ if (options.bundler === 'rspack') {
46
+ processBundlerConfigFile(options, host, 'rspack.config.js');
47
+ processBundlerConfigFile(options, host, 'rspack.config.prod.js');
48
+ }
49
+ else {
50
+ processBundlerConfigFile(options, host, 'webpack.config.js');
51
+ processBundlerConfigFile(options, host, 'webpack.config.prod.js');
52
+ }
43
53
  }
44
54
  if (options.dynamic) {
45
- processWebpackConfig(options, host, 'webpack.config.prod.js');
46
- processWebpackConfig(options, host, 'webpack.config.prod.ts');
55
+ processBundlerConfigFile(options, host, 'webpack.config.prod.js');
56
+ processBundlerConfigFile(options, host, 'webpack.config.prod.ts');
57
+ processBundlerConfigFile(options, host, 'rspack.config.prod.js');
58
+ processBundlerConfigFile(options, host, 'rspack.config.prod.ts');
47
59
  if (!host.exists(pathToMFManifest)) {
48
60
  host.write(pathToMFManifest, `{
49
61
  ${defaultRemoteManifest
@@ -6,11 +6,14 @@ const versions_1 = require("../../../utils/versions");
6
6
  async function setupSsrForHost(tree, options, appName, defaultRemoteManifest) {
7
7
  const tasks = [];
8
8
  let project = (0, devkit_1.readProjectConfiguration)(tree, appName);
9
- project.targets.serve.executor = '@nx/react:module-federation-ssr-dev-server';
9
+ project.targets.serve.executor =
10
+ options.bundler === 'rspack'
11
+ ? '@nx/rspack:module-federation-ssr-dev-server'
12
+ : '@nx/react:module-federation-ssr-dev-server';
10
13
  (0, devkit_1.updateProjectConfiguration)(tree, appName, project);
11
14
  const pathToModuleFederationSsrFiles = options.typescriptConfiguration
12
- ? 'module-federation-ssr-ts'
13
- : 'module-federation-ssr';
15
+ ? `${options.bundler === 'rspack' ? 'rspack-' : 'webpack-'}module-federation-ssr-ts`
16
+ : `${options.bundler === 'rspack' ? 'rspack-' : 'webpack-'}module-federation-ssr`;
14
17
  (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, `../files/${pathToModuleFederationSsrFiles}`), project.root, {
15
18
  ...options,
16
19
  static: !options?.dynamic,
@@ -28,6 +28,7 @@ export interface Schema {
28
28
  typescriptConfiguration?: boolean;
29
29
  dynamic?: boolean;
30
30
  addPlugin?: boolean;
31
+ bundler?: 'rspack' | 'webpack';
31
32
  }
32
33
 
33
34
  export interface NormalizedSchema extends Schema {
@@ -183,6 +183,14 @@
183
183
  "type": "boolean",
184
184
  "default": false,
185
185
  "x-priority": "internal"
186
+ },
187
+ "bundler": {
188
+ "description": "The bundler to use.",
189
+ "type": "string",
190
+ "enum": ["rspack", "webpack"],
191
+ "x-prompt": "Which bundler do you want to use to build the application?",
192
+ "default": "rspack",
193
+ "x-priority": "important"
186
194
  }
187
195
  },
188
196
  "required": ["name"],
@@ -0,0 +1 @@
1
+ import('./bootstrap');
@@ -0,0 +1 @@
1
+ export { default } from './app/app';
@@ -0,0 +1,16 @@
1
+ const { composePlugins, withNx, withReact } = require('@nx/rspack');
2
+ const { withModuleFederation } = require('@nx/rspack/module-federation');
3
+
4
+ const baseConfig = require('./module-federation.config');
5
+
6
+ const config = {
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 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(), withModuleFederation(config, { dts: false }));