@nx/react 23.0.0-beta.2 → 23.0.0-beta.21

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 (166) hide show
  1. package/generators.json +16 -3
  2. package/index.d.ts +0 -3
  3. package/index.d.ts.map +1 -1
  4. package/index.js +1 -4
  5. package/migrations.json +6 -0
  6. package/package.json +18 -18
  7. package/plugins/component-testing/index.js +7 -7
  8. package/plugins/component-testing/webpack-fallback.js +2 -2
  9. package/plugins/storybook/index.js +3 -3
  10. package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.d.ts.map +1 -1
  11. package/src/executors/module-federation-dev-server/module-federation-dev-server.impl.js +6 -4
  12. package/src/executors/module-federation-dev-server/schema.json +1 -0
  13. package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.d.ts.map +1 -1
  14. package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.js +7 -5
  15. package/src/executors/module-federation-ssr-dev-server/schema.json +1 -0
  16. package/src/executors/module-federation-static-server/module-federation-static-server.impl.d.ts.map +1 -1
  17. package/src/executors/module-federation-static-server/module-federation-static-server.impl.js +6 -4
  18. package/src/executors/module-federation-static-server/schema.json +1 -0
  19. package/src/generators/_utils/mf-dependencies.d.ts +8 -0
  20. package/src/generators/_utils/mf-dependencies.d.ts.map +1 -0
  21. package/src/generators/_utils/mf-dependencies.js +84 -0
  22. package/src/generators/_utils/mf-versions.d.ts +12 -0
  23. package/src/generators/_utils/mf-versions.d.ts.map +1 -0
  24. package/src/generators/_utils/mf-versions.js +29 -0
  25. package/src/generators/_utils/normalize.d.ts +20 -0
  26. package/src/generators/_utils/normalize.d.ts.map +1 -0
  27. package/src/generators/_utils/normalize.js +48 -0
  28. package/src/generators/application/application.d.ts.map +1 -1
  29. package/src/generators/application/application.js +32 -18
  30. package/src/generators/application/lib/add-e2e.d.ts.map +1 -1
  31. package/src/generators/application/lib/add-linting.js +10 -11
  32. package/src/generators/application/lib/add-project.d.ts.map +1 -1
  33. package/src/generators/application/lib/add-project.js +10 -0
  34. package/src/generators/application/lib/add-routing.js +2 -2
  35. package/src/generators/application/lib/bundlers/add-vite.d.ts.map +1 -1
  36. package/src/generators/application/lib/bundlers/add-vite.js +10 -2
  37. package/src/generators/application/lib/create-application-files.d.ts +1 -1
  38. package/src/generators/application/lib/create-application-files.js +2 -2
  39. package/src/generators/application/lib/normalize-options.js +5 -5
  40. package/src/generators/component/component.js +2 -2
  41. package/src/generators/component/lib/normalize-options.d.ts.map +1 -1
  42. package/src/generators/component/lib/normalize-options.js +5 -6
  43. package/src/generators/component/schema.d.ts +2 -7
  44. package/src/generators/component/schema.json +0 -5
  45. package/src/generators/component-story/component-story.d.ts.map +1 -1
  46. package/src/generators/component-story/component-story.js +3 -4
  47. package/src/generators/component-test/component-test.d.ts.map +1 -1
  48. package/src/generators/component-test/component-test.js +3 -4
  49. package/src/generators/consumer/consumer.d.ts +5 -0
  50. package/src/generators/consumer/consumer.d.ts.map +1 -0
  51. package/src/generators/consumer/consumer.js +135 -0
  52. package/src/generators/consumer/files/_common/src/App.tsx__tmpl__ +53 -0
  53. package/src/generators/consumer/files/_common/src/bootstrap.tsx__tmpl__ +12 -0
  54. package/src/generators/consumer/files/_common/src/index.ts__tmpl__ +4 -0
  55. package/src/generators/consumer/files/_common/src/mf.ts__tmpl__ +35 -0
  56. package/src/generators/consumer/files/_common/tsconfig.json__tmpl__ +17 -0
  57. package/src/generators/consumer/files/rsbuild/index.html__tmpl__ +12 -0
  58. package/src/generators/consumer/files/rsbuild/package.json__tmpl__ +23 -0
  59. package/src/generators/consumer/files/rsbuild/rsbuild.config.ts__tmpl__ +25 -0
  60. package/src/generators/consumer/files/rspack/index.html__tmpl__ +12 -0
  61. package/src/generators/consumer/files/rspack/package.json__tmpl__ +23 -0
  62. package/src/generators/consumer/files/rspack/rspack.config.ts__tmpl__ +59 -0
  63. package/src/generators/consumer/files/vite/index.html__tmpl__ +12 -0
  64. package/src/generators/consumer/files/vite/package.json__tmpl__ +24 -0
  65. package/src/generators/consumer/files/vite/vite.config.ts__tmpl__ +27 -0
  66. package/src/generators/consumer/schema.d.ts +8 -0
  67. package/src/generators/consumer/schema.json +43 -0
  68. package/src/generators/cypress-component-configuration/lib/add-files.d.ts +1 -1
  69. package/src/generators/cypress-component-configuration/lib/add-files.d.ts.map +1 -1
  70. package/src/generators/cypress-component-configuration/lib/add-files.js +4 -4
  71. package/src/generators/federate-module/federate-module.d.ts.map +1 -1
  72. package/src/generators/federate-module/federate-module.js +4 -2
  73. package/src/generators/federate-module/lib/utils.js +2 -2
  74. package/src/generators/hook/hook.d.ts.map +1 -1
  75. package/src/generators/hook/hook.js +5 -6
  76. package/src/generators/host/files/rspack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +1 -1
  77. package/src/generators/host/files/rspack-module-federation-ssr-ts/rspack.config.ts__tmpl__ +1 -1
  78. package/src/generators/host/files/rspack-module-federation-ts/module-federation.config.ts__tmpl__ +1 -1
  79. package/src/generators/host/files/rspack-module-federation-ts/rspack.config.prod.ts__tmpl__ +2 -2
  80. package/src/generators/host/files/rspack-module-federation-ts/rspack.config.ts__tmpl__ +1 -1
  81. package/src/generators/host/files/webpack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +1 -1
  82. package/src/generators/host/files/webpack-module-federation-ssr-ts/webpack.server.config.ts__tmpl__ +1 -1
  83. package/src/generators/host/files/webpack-module-federation-ts/module-federation.config.ts__tmpl__ +1 -1
  84. package/src/generators/host/files/webpack-module-federation-ts/webpack.config.prod.ts__tmpl__ +2 -2
  85. package/src/generators/host/files/webpack-module-federation-ts/webpack.config.ts__tmpl__ +2 -2
  86. package/src/generators/host/host.d.ts.map +1 -1
  87. package/src/generators/host/host.js +7 -5
  88. package/src/generators/host/lib/add-module-federation-files.d.ts.map +1 -1
  89. package/src/generators/host/lib/add-module-federation-files.js +3 -3
  90. package/src/generators/host/lib/normalize-host-name.js +2 -2
  91. package/src/generators/host/lib/update-module-federation-tsconfig.js +2 -2
  92. package/src/generators/init/init.d.ts.map +1 -1
  93. package/src/generators/init/init.js +2 -2
  94. package/src/generators/library/lib/add-linting.js +7 -8
  95. package/src/generators/library/lib/add-rollup-build-target.d.ts.map +1 -1
  96. package/src/generators/library/lib/add-rollup-build-target.js +6 -0
  97. package/src/generators/library/lib/install-common-dependencies.js +2 -2
  98. package/src/generators/library/lib/normalize-options.d.ts.map +1 -1
  99. package/src/generators/library/lib/normalize-options.js +7 -7
  100. package/src/generators/library/lib/update-app-routes.js +2 -2
  101. package/src/generators/library/library.d.ts.map +1 -1
  102. package/src/generators/library/library.js +14 -18
  103. package/src/generators/provider/files/_common/src/__componentName__.tsx__tmpl__ +11 -0
  104. package/src/generators/provider/files/_common/src/bootstrap.tsx__tmpl__ +12 -0
  105. package/src/generators/provider/files/_common/src/index.ts__tmpl__ +5 -0
  106. package/src/generators/provider/files/_common/tsconfig.json__tmpl__ +17 -0
  107. package/src/generators/provider/files/rsbuild/index.html__tmpl__ +12 -0
  108. package/src/generators/provider/files/rsbuild/package.json__tmpl__ +22 -0
  109. package/src/generators/provider/files/rsbuild/rsbuild.config.ts__tmpl__ +31 -0
  110. package/src/generators/provider/files/rspack/index.html__tmpl__ +12 -0
  111. package/src/generators/provider/files/rspack/package.json__tmpl__ +22 -0
  112. package/src/generators/provider/files/rspack/rspack.config.ts__tmpl__ +69 -0
  113. package/src/generators/provider/files/vite/index.html__tmpl__ +12 -0
  114. package/src/generators/provider/files/vite/package.json__tmpl__ +23 -0
  115. package/src/generators/provider/files/vite/vite.config.ts__tmpl__ +37 -0
  116. package/src/generators/provider/provider.d.ts +5 -0
  117. package/src/generators/provider/provider.d.ts.map +1 -0
  118. package/src/generators/provider/provider.js +92 -0
  119. package/src/generators/provider/schema.d.ts +9 -0
  120. package/src/generators/provider/schema.json +46 -0
  121. package/src/generators/redux/redux.d.ts.map +1 -1
  122. package/src/generators/redux/redux.js +7 -8
  123. package/src/generators/redux/schema.d.ts +1 -1
  124. package/src/generators/remote/files/rspack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +1 -1
  125. package/src/generators/remote/files/rspack-module-federation-ssr-ts/rspack.config.ts__tmpl__ +1 -1
  126. package/src/generators/remote/files/rspack-module-federation-ts/module-federation.config.ts__tmpl__ +1 -1
  127. package/src/generators/remote/files/rspack-module-federation-ts/rspack.config.ts__tmpl__ +1 -1
  128. package/src/generators/remote/files/webpack-module-federation-ssr-ts/module-federation.server.config.ts__tmpl__ +1 -1
  129. package/src/generators/remote/files/webpack-module-federation-ssr-ts/webpack.server.config.ts__tmpl__ +1 -1
  130. package/src/generators/remote/files/webpack-module-federation-ts/module-federation.config.ts__tmpl__ +1 -1
  131. package/src/generators/remote/files/webpack-module-federation-ts/webpack.config.ts__tmpl__ +1 -1
  132. package/src/generators/remote/lib/setup-package-json-exports-for-remote.js +2 -2
  133. package/src/generators/remote/lib/update-host-with-remote.js +4 -5
  134. package/src/generators/remote/remote.d.ts.map +1 -1
  135. package/src/generators/remote/remote.js +9 -7
  136. package/src/generators/setup-ssr/setup-ssr.d.ts.map +1 -1
  137. package/src/generators/setup-ssr/setup-ssr.js +5 -7
  138. package/src/generators/stories/stories.js +5 -6
  139. package/src/migrations/update-20-2-0/migrate-with-mf-import-to-new-package.d.ts.map +1 -1
  140. package/src/migrations/update-20-2-0/migrate-with-mf-import-to-new-package.js +2 -2
  141. package/src/migrations/update-20-3-0/ensure-nx-module-federation-package.d.ts.map +1 -1
  142. package/src/migrations/update-20-3-0/ensure-nx-module-federation-package.js +2 -2
  143. package/src/migrations/update-22-0-0/add-svgr-to-webpack-config.d.ts.map +1 -1
  144. package/src/migrations/update-22-0-0/add-svgr-to-webpack-config.js +2 -2
  145. package/src/migrations/update-23-0-0/remove-nx-react-webpack-plugin-import.d.ts +3 -0
  146. package/src/migrations/update-23-0-0/remove-nx-react-webpack-plugin-import.d.ts.map +1 -0
  147. package/src/migrations/update-23-0-0/remove-nx-react-webpack-plugin-import.js +128 -0
  148. package/src/module-federation/ast-utils.js +2 -2
  149. package/src/plugins/router-plugin.d.ts.map +1 -1
  150. package/src/plugins/router-plugin.js +14 -23
  151. package/src/rules/update-module-federation-project.js +3 -3
  152. package/src/utils/add-mf-env-to-inputs.d.ts.map +1 -1
  153. package/src/utils/add-mf-env-to-inputs.js +15 -8
  154. package/src/utils/ast-utils.js +15 -15
  155. package/src/utils/component-props.js +3 -3
  156. package/src/utils/create-ts-config.js +3 -3
  157. package/src/utils/ct-utils.d.ts +1 -1
  158. package/src/utils/ct-utils.d.ts.map +1 -1
  159. package/src/utils/ct-utils.js +6 -6
  160. package/src/utils/module-federation-deprecation.d.ts +13 -0
  161. package/src/utils/module-federation-deprecation.d.ts.map +1 -0
  162. package/src/utils/module-federation-deprecation.js +46 -0
  163. package/src/utils/normalize-remote.js +2 -2
  164. package/src/utils/versions.d.ts +1 -1
  165. package/src/utils/versions.js +1 -1
  166. package/tailwind.js +2 -2
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.consumerGenerator = consumerGenerator;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const versions_1 = require("@nx/js/src/utils/versions");
7
+ const versions_2 = require("../../utils/versions");
8
+ const mfVersions = tslib_1.__importStar(require("../_utils/mf-versions"));
9
+ const mf_dependencies_1 = require("../_utils/mf-dependencies");
10
+ const normalize_1 = require("../_utils/normalize");
11
+ const provider_1 = tslib_1.__importDefault(require("../provider/provider"));
12
+ // `--mode=...` is rspack's portable equivalent of `NODE_ENV=...` and works on
13
+ // Windows without a shell prefix.
14
+ const BUNDLER_DEV_COMMAND = {
15
+ vite: 'vite',
16
+ rsbuild: 'rsbuild dev',
17
+ rspack: 'rspack serve --mode=development',
18
+ };
19
+ const BUNDLER_BUILD_COMMAND = {
20
+ vite: 'vite build',
21
+ rsbuild: 'rsbuild build',
22
+ rspack: 'rspack build --mode=production',
23
+ };
24
+ async function consumerGenerator(tree, schema) {
25
+ const opts = await (0, normalize_1.normalizeScaffoldOptions)(tree, {
26
+ directory: schema.directory,
27
+ surface: 'consumer',
28
+ bundler: schema.bundler,
29
+ port: schema.port,
30
+ });
31
+ // When the user explicitly passes `--providerNames=p1,p2`, generate a
32
+ // sibling provider app per entry and wire them into the consumer's
33
+ // PROVIDERS list + App.tsx. When the flag is omitted, ship a placeholder
34
+ // `my-provider` entry pointing at the per-bundler provider-default port
35
+ // without generating an actual provider project.
36
+ const providerNames = schema.providerNames?.length
37
+ ? schema.providerNames
38
+ : ['my-provider'];
39
+ const shouldGenerateProviders = !!schema.providerNames?.length;
40
+ const providerDefaultPort = (0, normalize_1.getDefaultPort)(opts.bundler, 'provider');
41
+ const providers = providerNames.map((name, i) => ({
42
+ name,
43
+ // The federation container name the provider build emits. Must match the
44
+ // provider's federation `name`, which is derived the same way (see
45
+ // provider.ts / normalize.ts) - it strips chars that aren't valid in a JS
46
+ // identifier, so a naive `alias.replace(/-/g, '_')` in the consumer would
47
+ // diverge for names with dots/slashes/@ and loadRemote() would resolve the
48
+ // URL but look up the wrong container.
49
+ federationName: (0, normalize_1.toFederationName)((0, devkit_1.names)(name).fileName),
50
+ componentName: `Provider${(0, devkit_1.names)(name).className}`,
51
+ directory: (0, devkit_1.joinPathFragments)(opts.projectRoot, '..', name),
52
+ port: providerDefaultPort + i,
53
+ }));
54
+ (0, devkit_1.addProjectConfiguration)(tree, opts.projectName, {
55
+ root: opts.projectRoot,
56
+ sourceRoot: (0, devkit_1.joinPathFragments)(opts.projectRoot, 'src'),
57
+ projectType: 'application',
58
+ targets: {
59
+ serve: {
60
+ executor: 'nx:run-commands',
61
+ continuous: true,
62
+ options: {
63
+ command: BUNDLER_DEV_COMMAND[opts.bundler],
64
+ cwd: opts.projectRoot,
65
+ },
66
+ },
67
+ build: {
68
+ executor: 'nx:run-commands',
69
+ options: {
70
+ command: BUNDLER_BUILD_COMMAND[opts.bundler],
71
+ cwd: opts.projectRoot,
72
+ },
73
+ },
74
+ },
75
+ });
76
+ const tasks = [];
77
+ if (shouldGenerateProviders) {
78
+ for (const p of providers) {
79
+ tasks.push(await (0, provider_1.default)(tree, {
80
+ directory: p.directory,
81
+ bundler: opts.bundler,
82
+ port: p.port,
83
+ // Wire `nx serve <provider>` to also spin up this consumer.
84
+ consumer: opts.projectName,
85
+ }));
86
+ }
87
+ }
88
+ // Point at `remoteEntry.js`, which every supported bundler emits at dev
89
+ // time. `mf-manifest.json` is richer (https://module-federation.io/configure/manifest-fields)
90
+ // but `@module-federation/vite` only emits it at build time, so a consumer
91
+ // serving against a dev-mode vite provider would get the SPA-fallback HTML
92
+ // and crash on JSON.parse. Swap to mf-manifest.json manually for prod if
93
+ // you want the extra metadata.
94
+ const remotes = providers.map((p) => ({
95
+ // `alias` is the key the consumer references (loadRemote/lazyProvider);
96
+ // `name` is the provider's federation container name; `entry` is its
97
+ // remoteEntry.js URL.
98
+ alias: p.name,
99
+ name: p.federationName,
100
+ entry: `http://localhost:${p.port}/remoteEntry.js`,
101
+ }));
102
+ // Vite emits ESM `remoteEntry.js`; rspack/rsbuild emit UMD. The federation
103
+ // runtime needs `type: 'module'` for ESM (else loads as a classic <script>
104
+ // and the browser throws #RUNTIME-001) and NO type for UMD (else
105
+ // #RUNTIME-002). We only generate same-bundler providers via --providerNames,
106
+ // so a single per-consumer setting is correct.
107
+ const remoteType = opts.bundler === 'vite' ? 'module' : null;
108
+ const templateSubstitutions = {
109
+ projectName: opts.projectName,
110
+ federationName: opts.federationName,
111
+ port: opts.port,
112
+ bundler: opts.bundler,
113
+ providers,
114
+ remotes,
115
+ remoteType,
116
+ versions: {
117
+ ...mfVersions,
118
+ reactVersion: versions_2.reactVersion,
119
+ reactDomVersion: versions_2.reactDomVersion,
120
+ typesReactVersion: versions_2.typesReactVersion,
121
+ typesReactDomVersion: versions_2.typesReactDomVersion,
122
+ typescriptVersion: versions_1.typescriptVersion,
123
+ },
124
+ tmpl: '',
125
+ };
126
+ (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', '_common'), opts.projectRoot, templateSubstitutions);
127
+ (0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files', opts.bundler), opts.projectRoot, templateSubstitutions);
128
+ // Write deps into the workspace root package.json so bare bundler bins
129
+ // resolve when nx invokes the generated run-commands serve target.
130
+ const deps = (0, mf_dependencies_1.getConsumerDeps)(opts.bundler);
131
+ tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, deps.dependencies, deps.devDependencies));
132
+ await (0, devkit_1.formatFiles)(tree);
133
+ return (0, devkit_1.runTasksInSerial)(...tasks);
134
+ }
135
+ exports.default = consumerGenerator;
@@ -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,4 +1,4 @@
1
- import type { FoundTarget } from '@nx/cypress/src/utils/find-target-options';
1
+ import type { FoundTarget } from '@nx/cypress/internal';
2
2
  import { ProjectConfiguration, Tree } from '@nx/devkit';
3
3
  import type { CypressComponentConfigurationSchema } from '../schema';
4
4
  export declare function addFiles(tree: Tree, projectConfig: ProjectConfiguration, options: CypressComponentConfigurationSchema, found: FoundTarget): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"add-files.d.ts","sourceRoot":"","sources":["../../../../../../../packages/react/src/generators/cypress-component-configuration/lib/add-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAC7E,OAAO,EAIL,oBAAoB,EACpB,IAAI,EAEL,MAAM,YAAY,CAAC;AAKpB,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,WAAW,CAAC;AAErE,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,oBAAoB,EACnC,OAAO,EAAE,mCAAmC,EAC5C,KAAK,EAAE,WAAW,iBAqEnB"}
1
+ {"version":3,"file":"add-files.d.ts","sourceRoot":"","sources":["../../../../../../../packages/react/src/generators/cypress-component-configuration/lib/add-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAIL,oBAAoB,EACpB,IAAI,EAEL,MAAM,YAAY,CAAC;AAKpB,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,WAAW,CAAC;AAErE,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,oBAAoB,EACnC,OAAO,EAAE,mCAAmC,EAC5C,KAAK,EAAE,WAAW,iBAqEnB"}
@@ -35,15 +35,15 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.addFiles = addFiles;
37
37
  const devkit_1 = require("@nx/devkit");
38
- const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
38
+ const internal_1 = require("@nx/js/internal");
39
39
  const versions_1 = require("nx/src/utils/versions");
40
40
  const ct_utils_1 = require("../../../utils/ct-utils");
41
41
  const component_test_1 = require("../../component-test/component-test");
42
42
  async function addFiles(tree, projectConfig, options, found) {
43
43
  // must dynamicaly import to prevent packages not using cypress from erroring out
44
44
  // when importing react
45
- const { addMountDefinition } = await Promise.resolve().then(() => __importStar(require('@nx/cypress/src/utils/config')));
46
- const { getInstalledCypressMajorVersion } = await Promise.resolve().then(() => __importStar(require('@nx/cypress/src/utils/versions')));
45
+ const { addMountDefinition } = await Promise.resolve().then(() => __importStar(require('@nx/cypress/internal')));
46
+ const { getInstalledCypressMajorVersion } = await Promise.resolve().then(() => __importStar(require('@nx/cypress/internal')));
47
47
  const installedCypressMajorVersion = getInstalledCypressMajorVersion(tree);
48
48
  // Specifically undefined to allow Remix workaround of passing an empty string
49
49
  const actualBundler = await (0, ct_utils_1.getActualBundler)(tree, options, found);
@@ -66,7 +66,7 @@ async function addFiles(tree, projectConfig, options, found) {
66
66
  }
67
67
  if (options.generateTests) {
68
68
  const filePaths = [];
69
- const sourceRoot = (0, ts_solution_setup_1.getProjectSourceRoot)(projectConfig, tree);
69
+ const sourceRoot = (0, internal_1.getProjectSourceRoot)(projectConfig, tree);
70
70
  (0, devkit_1.visitNotIgnoredFiles)(tree, sourceRoot, (filePath) => {
71
71
  if ((0, ct_utils_1.isComponent)(tree, filePath)) {
72
72
  filePaths.push(filePath);
@@ -1 +1 @@
1
- {"version":3,"file":"federate-module.d.ts","sourceRoot":"","sources":["../../../../../../packages/react/src/generators/federate-module/federate-module.ts"],"names":[],"mappings":"AAAA,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,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"}
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.federateModuleGenerator = federateModuleGenerator;
4
+ const internal_1 = require("@nx/devkit/internal");
4
5
  const devkit_1 = require("@nx/devkit");
5
6
  const remote_1 = require("../remote/remote");
6
7
  const utils_1 = require("./lib/utils");
7
- const project_name_and_root_utils_1 = require("@nx/devkit/src/generators/project-name-and-root-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.
@@ -14,7 +16,7 @@ async function federateModuleGenerator(tree, schema) {
14
16
  Path: ${schema.path}`);
15
17
  }
16
18
  const tasks = [];
17
- const { projectName: remoteName, projectRoot: remoteRoot } = await (0, project_name_and_root_utils_1.determineProjectNameAndRootOptions)(tree, {
19
+ const { projectName: remoteName, projectRoot: remoteRoot } = await (0, internal_1.determineProjectNameAndRootOptions)(tree, {
18
20
  name: schema.remote,
19
21
  directory: schema.remoteDirectory,
20
22
  projectType: 'application',
@@ -9,10 +9,10 @@ exports.updateExposesPropertyinAST = updateExposesPropertyinAST;
9
9
  exports.writeToConfig = writeToConfig;
10
10
  exports.updateExposesProperty = updateExposesProperty;
11
11
  const devkit_1 = require("@nx/devkit");
12
- const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
12
+ const internal_1 = require("@nx/js/internal");
13
13
  let tsModule;
14
14
  if (!tsModule) {
15
- tsModule = (0, ensure_typescript_1.ensureTypescript)();
15
+ tsModule = (0, internal_1.ensureTypescript)();
16
16
  }
17
17
  /**
18
18
  * Adds a Module Federation path to the exposes property of the module federation config
@@ -1 +1 @@
1
- {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../../../../packages/react/src/generators/hook/hook.ts"],"names":[],"mappings":"AACA,OAAO,EAQL,IAAI,EACL,MAAM,YAAY,CAAC;AAQpB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAclC,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAO7D;AAmHD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../../../../packages/react/src/generators/hook/hook.ts"],"names":[],"mappings":"AAKA,OAAO,EAQL,IAAI,EACL,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAYlC,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAO7D;AAmHD,eAAe,aAAa,CAAC"}