@nx/react 23.0.0-beta.20 → 23.0.0-beta.22

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 (73) hide show
  1. package/generators.json +16 -3
  2. package/migrations.json +12 -6
  3. package/package.json +16 -16
  4. package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.d.ts.map +1 -1
  5. package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.js +2 -0
  6. package/src/executors/module-federation-dev-server/schema.json +1 -0
  7. package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.d.ts.map +1 -1
  8. package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.js +2 -0
  9. package/src/executors/module-federation-ssr-dev-server/schema.json +1 -0
  10. package/src/executors/module-federation-static-server/module-federation-static-server.impl.d.ts.map +1 -1
  11. package/src/executors/module-federation-static-server/module-federation-static-server.impl.js +2 -0
  12. package/src/executors/module-federation-static-server/schema.json +1 -0
  13. package/src/generators/_utils/mf-dependencies.d.ts +8 -0
  14. package/src/generators/_utils/mf-dependencies.d.ts.map +1 -0
  15. package/src/generators/_utils/mf-dependencies.js +84 -0
  16. package/src/generators/_utils/mf-versions.d.ts +12 -0
  17. package/src/generators/_utils/mf-versions.d.ts.map +1 -0
  18. package/src/generators/_utils/mf-versions.js +29 -0
  19. package/src/generators/_utils/normalize.d.ts +20 -0
  20. package/src/generators/_utils/normalize.d.ts.map +1 -0
  21. package/src/generators/_utils/normalize.js +48 -0
  22. package/src/generators/consumer/consumer.d.ts +5 -0
  23. package/src/generators/consumer/consumer.d.ts.map +1 -0
  24. package/src/generators/consumer/consumer.js +135 -0
  25. package/src/generators/consumer/files/_common/src/App.tsx__tmpl__ +53 -0
  26. package/src/generators/consumer/files/_common/src/bootstrap.tsx__tmpl__ +12 -0
  27. package/src/generators/consumer/files/_common/src/index.ts__tmpl__ +4 -0
  28. package/src/generators/consumer/files/_common/src/mf.ts__tmpl__ +35 -0
  29. package/src/generators/consumer/files/_common/tsconfig.json__tmpl__ +17 -0
  30. package/src/generators/consumer/files/rsbuild/index.html__tmpl__ +12 -0
  31. package/src/generators/consumer/files/rsbuild/package.json__tmpl__ +23 -0
  32. package/src/generators/consumer/files/rsbuild/rsbuild.config.ts__tmpl__ +25 -0
  33. package/src/generators/consumer/files/rspack/index.html__tmpl__ +12 -0
  34. package/src/generators/consumer/files/rspack/package.json__tmpl__ +23 -0
  35. package/src/generators/consumer/files/rspack/rspack.config.ts__tmpl__ +59 -0
  36. package/src/generators/consumer/files/vite/index.html__tmpl__ +12 -0
  37. package/src/generators/consumer/files/vite/package.json__tmpl__ +24 -0
  38. package/src/generators/consumer/files/vite/vite.config.ts__tmpl__ +27 -0
  39. package/src/generators/consumer/schema.d.ts +8 -0
  40. package/src/generators/consumer/schema.json +43 -0
  41. package/src/generators/federate-module/federate-module.d.ts.map +1 -1
  42. package/src/generators/federate-module/federate-module.js +2 -0
  43. package/src/generators/host/host.d.ts.map +1 -1
  44. package/src/generators/host/host.js +2 -0
  45. package/src/generators/provider/files/_common/src/__componentName__.tsx__tmpl__ +11 -0
  46. package/src/generators/provider/files/_common/src/bootstrap.tsx__tmpl__ +12 -0
  47. package/src/generators/provider/files/_common/src/index.ts__tmpl__ +5 -0
  48. package/src/generators/provider/files/_common/tsconfig.json__tmpl__ +17 -0
  49. package/src/generators/provider/files/rsbuild/index.html__tmpl__ +12 -0
  50. package/src/generators/provider/files/rsbuild/package.json__tmpl__ +22 -0
  51. package/src/generators/provider/files/rsbuild/rsbuild.config.ts__tmpl__ +31 -0
  52. package/src/generators/provider/files/rspack/index.html__tmpl__ +12 -0
  53. package/src/generators/provider/files/rspack/package.json__tmpl__ +22 -0
  54. package/src/generators/provider/files/rspack/rspack.config.ts__tmpl__ +69 -0
  55. package/src/generators/provider/files/vite/index.html__tmpl__ +12 -0
  56. package/src/generators/provider/files/vite/package.json__tmpl__ +23 -0
  57. package/src/generators/provider/files/vite/vite.config.ts__tmpl__ +37 -0
  58. package/src/generators/provider/provider.d.ts +5 -0
  59. package/src/generators/provider/provider.d.ts.map +1 -0
  60. package/src/generators/provider/provider.js +92 -0
  61. package/src/generators/provider/schema.d.ts +9 -0
  62. package/src/generators/provider/schema.json +46 -0
  63. package/src/generators/remote/remote.d.ts.map +1 -1
  64. package/src/generators/remote/remote.js +2 -0
  65. package/src/migrations/update-18-0-0/add-mf-env-var-to-target-defaults.md +36 -0
  66. package/src/migrations/update-20-2-0/migrate-mf-imports-to-new-package.md +27 -0
  67. package/src/migrations/update-20-2-0/migrate-with-mf-import-to-new-package.md +25 -0
  68. package/src/migrations/update-20-3-0/ensure-nx-module-federation-package.md +23 -0
  69. package/src/migrations/update-21-0-0/update-babel-loose.md +43 -0
  70. package/src/migrations/update-23-0-0/remove-nx-react-webpack-plugin-import.md +52 -0
  71. package/src/utils/module-federation-deprecation.d.ts +13 -0
  72. package/src/utils/module-federation-deprecation.d.ts.map +1 -0
  73. package/src/utils/module-federation-deprecation.js +46 -0
@@ -0,0 +1,53 @@
1
+ import { Component, Suspense, type ReactNode } from 'react';
2
+ import { lazyProvider } from './mf';
3
+
4
+ // ProviderBoundary catches the lazy() rejection that fires when a provider's
5
+ // remoteEntry.js can't be fetched (provider not running, network error,
6
+ // etc.). Without it any one missing provider unmounts the whole consumer
7
+ // tree. React has no built-in functional error boundary so this is a class.
8
+ // Wrap each <ProviderBoundary> in your router of choice if you need routing.
9
+ class ProviderBoundary extends Component<
10
+ { children: ReactNode; name: string },
11
+ { error: Error | null }
12
+ > {
13
+ state = { error: null as Error | null };
14
+ static getDerivedStateFromError(error: Error) {
15
+ return { error };
16
+ }
17
+ render() {
18
+ if (this.state.error) {
19
+ return (
20
+ <div role="alert">
21
+ <p>
22
+ Provider &quot;{this.props.name}&quot; unavailable:{' '}
23
+ {this.state.error.message}
24
+ </p>
25
+ </div>
26
+ );
27
+ }
28
+ return (
29
+ <Suspense fallback={<p>Loading {this.props.name}...</p>}>
30
+ {this.props.children}
31
+ </Suspense>
32
+ );
33
+ }
34
+ }
35
+
36
+ <% providers.forEach((p) => { -%>
37
+ const <%= p.componentName %> = lazyProvider('<%= p.name %>', 'App');
38
+ <% }); -%>
39
+
40
+ export function App() {
41
+ return (
42
+ <main>
43
+ <h1><%= projectName %></h1>
44
+ <% providers.forEach((p) => { -%>
45
+ <ProviderBoundary name="<%= p.name %>">
46
+ <<%= p.componentName %> />
47
+ </ProviderBoundary>
48
+ <% }); -%>
49
+ </main>
50
+ );
51
+ }
52
+
53
+ export default App;
@@ -0,0 +1,12 @@
1
+ import { StrictMode } from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import { App } from './App';
4
+
5
+ const container = document.getElementById('root');
6
+ if (!container) throw new Error('#root element not found');
7
+
8
+ createRoot(container).render(
9
+ <StrictMode>
10
+ <App />
11
+ </StrictMode>
12
+ );
@@ -0,0 +1,4 @@
1
+ // Indirection required by Module Federation: the federation runtime must boot
2
+ // before any shared dependency (React, react-dom) is evaluated.
3
+ import('./bootstrap');
4
+ export {};
@@ -0,0 +1,35 @@
1
+ import { lazy, type ComponentType } from 'react';
2
+ import { registerRemotes, loadRemote } from '@module-federation/runtime';
3
+
4
+ // The providers this consumer loads at runtime. Edit `entry` to point at a
5
+ // different URL (`remoteEntry.js` is what every supported bundler emits at dev
6
+ // + build time). `name` is the provider build's federation container name and
7
+ // must match the provider's federation `name`; `alias` is the key you pass to
8
+ // loadRemote()/lazyProvider().
9
+ const PROVIDERS: Array<{ alias: string; name: string; entry: string }> =
10
+ <%- JSON.stringify(remotes, null, 2) %>;
11
+
12
+ <% if (remoteType === 'module') { -%>
13
+ // `type: 'module'` is required because the providers in this workspace are
14
+ // vite-built and emit ESM remoteEntry.js. The federation runtime would load
15
+ // it as a classic `<script>` tag otherwise and the browser would throw
16
+ // `Cannot use import statement outside a module` (#RUNTIME-001).
17
+ registerRemotes(PROVIDERS.map((remote) => ({ ...remote, type: 'module' })));
18
+ <% } else { -%>
19
+ // `type` is omitted so the federation runtime auto-detects the entry format.
20
+ // The providers in this workspace are <%= bundler %>-built and emit UMD;
21
+ // setting `type: 'module'` here breaks them with #RUNTIME-002.
22
+ registerRemotes(PROVIDERS.map((remote) => ({ ...remote })));
23
+ <% } -%>
24
+
25
+ export function lazyProvider<Props = unknown>(
26
+ alias: string,
27
+ exposeName: string
28
+ ) {
29
+ return lazy(async () => {
30
+ const mod = await loadRemote<{ default: ComponentType<Props> }>(
31
+ `${alias}/${exposeName}`
32
+ );
33
+ return { default: mod!.default };
34
+ });
35
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["DOM", "DOM.Iterable", "ES2022"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "jsx": "react-jsx",
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true
15
+ },
16
+ "include": ["src"]
17
+ }
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title><%= projectName %></title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <!-- Rsbuild's html plugin injects the entry script automatically. -->
11
+ </body>
12
+ </html>
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "<%= projectName %>",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "rsbuild dev --port <%= port %>",
7
+ "build": "rsbuild build",
8
+ "preview": "rsbuild preview --port <%= port %>"
9
+ },
10
+ "dependencies": {
11
+ "@module-federation/runtime": "<%= versions.moduleFederationRuntimeVersion %>",
12
+ "react": "<%= versions.reactVersion %>",
13
+ "react-dom": "<%= versions.reactDomVersion %>"
14
+ },
15
+ "devDependencies": {
16
+ "@module-federation/rsbuild-plugin": "<%= versions.moduleFederationRsbuildPluginVersion %>",
17
+ "@rsbuild/core": "<%= versions.rsbuildCoreVersion %>",
18
+ "@rsbuild/plugin-react": "<%= versions.rsbuildPluginReactVersion %>",
19
+ "@types/react": "<%= versions.typesReactVersion %>",
20
+ "@types/react-dom": "<%= versions.typesReactDomVersion %>",
21
+ "typescript": "<%= versions.typescriptVersion %>"
22
+ }
23
+ }
@@ -0,0 +1,25 @@
1
+ import { defineConfig } from '@rsbuild/core';
2
+ import { pluginReact } from '@rsbuild/plugin-react';
3
+ import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
4
+
5
+ const PORT = <%= port %>;
6
+ const NAME = '<%= federationName %>';
7
+
8
+ export default defineConfig({
9
+ server: { port: PORT },
10
+ // assetPrefix:true keeps chunk URLs aligned with the dev-server origin -
11
+ // mirrors the provider config so a consumer that also exposes federated
12
+ // modules later doesn't need a separate fix.
13
+ dev: { assetPrefix: true },
14
+ html: { template: './index.html' },
15
+ source: { entry: { index: './src/index.ts' } },
16
+ plugins: [
17
+ pluginReact(),
18
+ pluginModuleFederation({
19
+ name: NAME,
20
+ // No build-time `remotes:` block - registered at runtime in src/mf.ts
21
+ // at module load time.
22
+ shared: ['react', 'react-dom'],
23
+ }),
24
+ ],
25
+ });
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title><%= projectName %></title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <!-- HtmlRspackPlugin injects the entry script automatically; do not add it here. -->
11
+ </body>
12
+ </html>
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "<%= projectName %>",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "rspack serve --mode=development",
7
+ "build": "rspack build --mode=production"
8
+ },
9
+ "dependencies": {
10
+ "@module-federation/enhanced": "<%= versions.moduleFederationEnhancedVersion %>",
11
+ "@module-federation/runtime": "<%= versions.moduleFederationRuntimeVersion %>",
12
+ "react": "<%= versions.reactVersion %>",
13
+ "react-dom": "<%= versions.reactDomVersion %>"
14
+ },
15
+ "devDependencies": {
16
+ "@rspack/cli": "<%= versions.rspackCliVersion %>",
17
+ "@rspack/core": "<%= versions.rspackCoreVersion %>",
18
+ "@rspack/dev-server": "<%= versions.rspackDevServerVersion %>",
19
+ "@types/react": "<%= versions.typesReactVersion %>",
20
+ "@types/react-dom": "<%= versions.typesReactDomVersion %>",
21
+ "typescript": "<%= versions.typescriptVersion %>"
22
+ }
23
+ }
@@ -0,0 +1,59 @@
1
+ import { defineConfig } from '@rspack/cli';
2
+ import { rspack } from '@rspack/core';
3
+ import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack';
4
+ import * as path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ // __dirname is undefined when @rspack/cli loads this config as ESM (it
8
+ // does, because the file uses `import` statements). Derive it from the
9
+ // module URL so the config works regardless of how the loader interprets it.
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+
12
+ const PORT = <%= port %>;
13
+ const NAME = '<%= federationName %>';
14
+
15
+ // Read mode from the rspack CLI arg (`--mode=development|production`) so the
16
+ // config works the same on Windows + POSIX without depending on a shell
17
+ // `NODE_ENV=...` prefix.
18
+ export default defineConfig((_env, argv) => {
19
+ const isDev = argv.mode !== 'production';
20
+ return {
21
+ context: __dirname,
22
+ entry: { main: './src/index.ts' },
23
+ output: {
24
+ path: path.resolve(__dirname, 'dist'),
25
+ publicPath: 'auto',
26
+ uniqueName: NAME,
27
+ clean: true,
28
+ },
29
+ devServer: { port: PORT, historyApiFallback: true, hot: true },
30
+ resolve: { extensions: ['...', '.ts', '.tsx', '.jsx'] },
31
+ module: {
32
+ rules: [
33
+ {
34
+ test: /\.(j|t)sx?$/,
35
+ exclude: [/node_modules/],
36
+ use: {
37
+ loader: 'builtin:swc-loader',
38
+ options: {
39
+ jsc: {
40
+ parser: { syntax: 'typescript', tsx: true },
41
+ transform: { react: { runtime: 'automatic', development: isDev } },
42
+ },
43
+ env: { targets: 'Chrome >= 87, Firefox >= 78, Edge >= 88, Safari >= 14' },
44
+ },
45
+ },
46
+ },
47
+ ],
48
+ },
49
+ plugins: [
50
+ new rspack.HtmlRspackPlugin({ template: './index.html' }),
51
+ new ModuleFederationPlugin({
52
+ name: NAME,
53
+ // No build-time `remotes:` block - registered at runtime in
54
+ // src/mf.ts at module load time.
55
+ shared: ['react', 'react-dom'],
56
+ }),
57
+ ],
58
+ };
59
+ });
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title><%= projectName %></title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/index.ts"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "<%= projectName %>",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite --port <%= port %> --strictPort",
8
+ "build": "vite build",
9
+ "preview": "vite preview --port <%= port %> --strictPort"
10
+ },
11
+ "dependencies": {
12
+ "@module-federation/runtime": "<%= versions.moduleFederationRuntimeVersion %>",
13
+ "react": "<%= versions.reactVersion %>",
14
+ "react-dom": "<%= versions.reactDomVersion %>"
15
+ },
16
+ "devDependencies": {
17
+ "@module-federation/vite": "<%= versions.moduleFederationVitePluginVersion %>",
18
+ "@types/react": "<%= versions.typesReactVersion %>",
19
+ "@types/react-dom": "<%= versions.typesReactDomVersion %>",
20
+ "@vitejs/plugin-react": "<%= versions.vitejsPluginReactVersion %>",
21
+ "typescript": "<%= versions.typescriptVersion %>",
22
+ "vite": "<%= versions.viteVersion %>"
23
+ }
24
+ }
@@ -0,0 +1,27 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+ import { federation } from '@module-federation/vite';
4
+
5
+ const PORT = <%= port %>;
6
+
7
+ export default defineConfig({
8
+ server: {
9
+ port: PORT,
10
+ strictPort: true,
11
+ host: '127.0.0.1',
12
+ },
13
+ preview: { port: PORT, strictPort: true },
14
+ build: { target: 'chrome89' },
15
+ plugins: [
16
+ federation({
17
+ name: '<%= federationName %>',
18
+ // No build-time `remotes:` block - the consumer registers them at
19
+ // runtime in src/mf.ts at module load time.
20
+ shared: {
21
+ react: { singleton: true },
22
+ 'react-dom': { singleton: true },
23
+ },
24
+ }),
25
+ react(),
26
+ ],
27
+ });
@@ -0,0 +1,8 @@
1
+ import type { SupportedBundler } from '../_utils/normalize';
2
+
3
+ export interface ConsumerGeneratorSchema {
4
+ directory: string;
5
+ bundler?: SupportedBundler;
6
+ port?: number;
7
+ providerNames?: string[];
8
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxReactConsumer",
4
+ "title": "Create a Module Federation consumer",
5
+ "description": "Scaffold a React Module Federation consumer. The bundler is selected at generation time; remotes are registered dynamically at runtime from an inline PROVIDERS list in src/mf.ts (no build-time remotes list).",
6
+ "cli": "nx",
7
+ "type": "object",
8
+ "properties": {
9
+ "directory": {
10
+ "type": "string",
11
+ "description": "Directory the consumer is generated in, e.g. `apps/my-consumer`. The project name is inferred from the trailing path segment.",
12
+ "alias": "dir",
13
+ "$default": { "$source": "argv", "index": 0 },
14
+ "x-prompt": "Which directory do you want to create the consumer in?"
15
+ },
16
+ "bundler": {
17
+ "type": "string",
18
+ "description": "Bundler used by the consumer. Final choice; cannot be switched later.",
19
+ "enum": ["vite", "rsbuild", "rspack"],
20
+ "default": "vite",
21
+ "x-prompt": {
22
+ "message": "Which bundler should the consumer use?",
23
+ "type": "list",
24
+ "items": [
25
+ { "value": "vite", "label": "Vite (default)" },
26
+ { "value": "rsbuild", "label": "Rsbuild" },
27
+ { "value": "rspack", "label": "Rspack" }
28
+ ]
29
+ }
30
+ },
31
+ "port": {
32
+ "type": "number",
33
+ "description": "Dev-server port the consumer listens on."
34
+ },
35
+ "providerNames": {
36
+ "type": "array",
37
+ "items": { "type": "string" },
38
+ "description": "Comma-separated list of provider project names to generate alongside this consumer. Each becomes an `@nx/react:provider` app sibling to the consumer and an entry in the `PROVIDERS` list in `src/mf.ts`. Defaults to `[my-provider]` as a placeholder (no provider is generated until you pass the flag explicitly).",
39
+ "alias": "providers"
40
+ }
41
+ },
42
+ "required": ["directory"]
43
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"federate-module.d.ts","sourceRoot":"","sources":["../../../../../../packages/react/src/generators/federate-module/federate-module.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EACjB,IAAI,EAQL,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMlC,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,8BAiEvE;AAED,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"federate-module.d.ts","sourceRoot":"","sources":["../../../../../../packages/react/src/generators/federate-module/federate-module.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EACjB,IAAI,EAQL,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOlC,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,8BAkEvE;AAED,eAAe,uBAAuB,CAAC"}
@@ -6,7 +6,9 @@ const devkit_1 = require("@nx/devkit");
6
6
  const remote_1 = require("../remote/remote");
7
7
  const utils_1 = require("./lib/utils");
8
8
  const js_1 = require("@nx/js");
9
+ const module_federation_deprecation_1 = require("../../utils/module-federation-deprecation");
9
10
  async function federateModuleGenerator(tree, schema) {
11
+ (0, module_federation_deprecation_1.warnReactFederateModuleGeneratorDeprecation)();
10
12
  // Check if the file exists
11
13
  if (!tree.exists(schema.path)) {
12
14
  throw new Error((0, devkit_1.stripIndents) `The "path" provided does not exist. Please verify the path is correct and pointing to a file that exists in the workspace.
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../../../../../packages/react/src/generators/host/host.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,iBAAiB,EAKjB,IAAI,EAGL,MAAM,YAAY,CAAC;AAapB,OAAO,EAAoB,MAAM,EAAE,MAAM,UAAU,CAAC;AAWpD,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC,CAmJ5B;AAmCD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../../../../../packages/react/src/generators/host/host.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,iBAAiB,EAKjB,IAAI,EAGL,MAAM,YAAY,CAAC;AAapB,OAAO,EAAoB,MAAM,EAAE,MAAM,UAAU,CAAC;AAYpD,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,iBAAiB,CAAC,CAoJ5B;AAmCD,eAAe,aAAa,CAAC"}
@@ -19,7 +19,9 @@ const internal_2 = require("@nx/js/internal");
19
19
  const versions_1 = require("../../utils/versions");
20
20
  const update_module_federation_tsconfig_1 = require("./lib/update-module-federation-tsconfig");
21
21
  const normalize_host_name_1 = require("./lib/normalize-host-name");
22
+ const module_federation_deprecation_1 = require("../../utils/module-federation-deprecation");
22
23
  async function hostGenerator(host, schema) {
24
+ (0, module_federation_deprecation_1.warnReactHostGeneratorDeprecation)();
23
25
  const tasks = [];
24
26
  const name = await (0, normalize_host_name_1.normalizeHostName)(host, schema.directory, schema.name);
25
27
  const options = {
@@ -0,0 +1,11 @@
1
+ // Exposed by the federation plugin as '<%= projectName %>/<%= exposeName %>'.
2
+ // Consumers render it lazily via `lazyProvider('<%= projectName %>', '<%= exposeName %>')`.
3
+ export function <%= componentName %>() {
4
+ return (
5
+ <section data-testid="<%= projectName %>">
6
+ <h1>Hello from <%= projectName %></h1>
7
+ </section>
8
+ );
9
+ }
10
+
11
+ export default <%= componentName %>;
@@ -0,0 +1,12 @@
1
+ import { StrictMode } from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import { <%= componentName %> } from './<%= componentName %>';
4
+
5
+ const container = document.getElementById('root');
6
+ if (!container) throw new Error('#root element not found');
7
+
8
+ createRoot(container).render(
9
+ <StrictMode>
10
+ <<%= componentName %> />
11
+ </StrictMode>
12
+ );
@@ -0,0 +1,5 @@
1
+ // Indirection required by Module Federation: the federation runtime must boot
2
+ // before any shared dependency (React, react-dom, etc.) is evaluated. Dynamic
3
+ // `import('./bootstrap')` defers the real entry until federation is ready.
4
+ import('./bootstrap');
5
+ export {};
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["DOM", "DOM.Iterable", "ES2022"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "jsx": "react-jsx",
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true
15
+ },
16
+ "include": ["src"]
17
+ }
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title><%= projectName %> (standalone)</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <!-- Rsbuild's html plugin injects the entry script automatically. -->
11
+ </body>
12
+ </html>
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "<%= projectName %>",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "rsbuild dev --port <%= port %>",
7
+ "build": "rsbuild build",
8
+ "preview": "rsbuild preview --port <%= port %>"
9
+ },
10
+ "dependencies": {
11
+ "react": "<%= versions.reactVersion %>",
12
+ "react-dom": "<%= versions.reactDomVersion %>"
13
+ },
14
+ "devDependencies": {
15
+ "@module-federation/rsbuild-plugin": "<%= versions.moduleFederationRsbuildPluginVersion %>",
16
+ "@rsbuild/core": "<%= versions.rsbuildCoreVersion %>",
17
+ "@rsbuild/plugin-react": "<%= versions.rsbuildPluginReactVersion %>",
18
+ "@types/react": "<%= versions.typesReactVersion %>",
19
+ "@types/react-dom": "<%= versions.typesReactDomVersion %>",
20
+ "typescript": "<%= versions.typescriptVersion %>"
21
+ }
22
+ }
@@ -0,0 +1,31 @@
1
+ import { defineConfig } from '@rsbuild/core';
2
+ import { pluginReact } from '@rsbuild/plugin-react';
3
+ import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
4
+
5
+ const PORT = <%= port %>;
6
+ const NAME = '<%= federationName %>';
7
+
8
+ export default defineConfig({
9
+ server: {
10
+ port: PORT,
11
+ // Allow cross-origin fetches from a consumer on a different port.
12
+ headers: { 'Access-Control-Allow-Origin': '*' },
13
+ },
14
+ // assetPrefix:true tells rsbuild to emit chunks with the dev-server URL as
15
+ // their public path. Without it a consumer on a different port asks its
16
+ // own origin for the federated chunks and gets the SPA-fallback HTML.
17
+ dev: { assetPrefix: true },
18
+ html: { template: './index.html' },
19
+ source: { entry: { index: './src/index.ts' } },
20
+ plugins: [
21
+ pluginReact(),
22
+ pluginModuleFederation({
23
+ name: NAME,
24
+ filename: 'remoteEntry.js',
25
+ exposes: {
26
+ './<%= exposeName %>': './src/<%= componentName %>.tsx',
27
+ },
28
+ shared: ['react', 'react-dom'],
29
+ }),
30
+ ],
31
+ });
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title><%= projectName %> (standalone)</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <!-- HtmlRspackPlugin injects the entry script automatically; do not add it here. -->
11
+ </body>
12
+ </html>
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "<%= projectName %>",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "rspack serve --mode=development",
7
+ "build": "rspack build --mode=production"
8
+ },
9
+ "dependencies": {
10
+ "@module-federation/enhanced": "<%= versions.moduleFederationEnhancedVersion %>",
11
+ "react": "<%= versions.reactVersion %>",
12
+ "react-dom": "<%= versions.reactDomVersion %>"
13
+ },
14
+ "devDependencies": {
15
+ "@rspack/cli": "<%= versions.rspackCliVersion %>",
16
+ "@rspack/core": "<%= versions.rspackCoreVersion %>",
17
+ "@rspack/dev-server": "<%= versions.rspackDevServerVersion %>",
18
+ "@types/react": "<%= versions.typesReactVersion %>",
19
+ "@types/react-dom": "<%= versions.typesReactDomVersion %>",
20
+ "typescript": "<%= versions.typescriptVersion %>"
21
+ }
22
+ }