diff --git a/examples/module-federation/host/module-federation.config.js b/examples/module-federation/host/module-federation.config.js new file mode 100644 index 0000000000..6cb601958c --- /dev/null +++ b/examples/module-federation/host/module-federation.config.js @@ -0,0 +1,19 @@ +const { dependencies } = require('./package.json'); + +module.exports = { + name: 'host', + remotes: { + remote: 'remote@http://localhost:3002/remoteEntry.js', + }, + shared: { + ...dependencies, + react: { + singleton: true, + requiredVersion: dependencies.react, + }, + 'react-dom': { + singleton: true, + requiredVersion: dependencies['react-dom'], + }, + }, +}; diff --git a/examples/module-federation/host/package.json b/examples/module-federation/host/package.json new file mode 100644 index 0000000000..16b4b2b181 --- /dev/null +++ b/examples/module-federation/host/package.json @@ -0,0 +1,16 @@ +{ + "name": "@examples/module-federation-host", + "private": true, + "scripts": { + "dev": "rsbuild dev", + "build": "rsbuild build" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@rsbuild/core": "workspace:*", + "@rsbuild/plugin-react": "workspace:*" + } +} diff --git a/examples/module-federation/host/rsbuild.config.ts b/examples/module-federation/host/rsbuild.config.ts new file mode 100644 index 0000000000..1d8362dbca --- /dev/null +++ b/examples/module-federation/host/rsbuild.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import mfConfig from './module-federation.config'; + +export default defineConfig({ + plugins: [pluginReact()], + server: { + port: 3000, + }, + performance: { + chunkSplit: { + strategy: 'split-by-experience', + override: { + chunks: 'async', + minSize: 30000, + }, + }, + }, + tools: { + rspack(config, { rspack, mergeConfig }) { + return mergeConfig(config, { + output: { + publicPath: 'auto', + }, + plugins: [new rspack.container.ModuleFederationPlugin(mfConfig)], + }); + }, + }, +}); diff --git a/examples/module-federation/host/src/App.js b/examples/module-federation/host/src/App.js new file mode 100644 index 0000000000..102178abfc --- /dev/null +++ b/examples/module-federation/host/src/App.js @@ -0,0 +1,15 @@ +import React from 'react'; + +const RemoteButton = React.lazy(() => import('remote/Button')); + +const App = () => ( +
+

Basic Host-Remote

+

Host

+ + + +
+); + +export default App; diff --git a/examples/module-federation/host/src/bootstrap.js b/examples/module-federation/host/src/bootstrap.js new file mode 100644 index 0000000000..c9ebadbf85 --- /dev/null +++ b/examples/module-federation/host/src/bootstrap.js @@ -0,0 +1,11 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; + +import App from './App'; + +ReactDOM.render( + + + , + document.getElementById('root'), +); diff --git a/examples/module-federation/host/src/index.js b/examples/module-federation/host/src/index.js new file mode 100644 index 0000000000..b93c7a0268 --- /dev/null +++ b/examples/module-federation/host/src/index.js @@ -0,0 +1 @@ +import('./bootstrap'); diff --git a/examples/module-federation/remote/module-federation.config.js b/examples/module-federation/remote/module-federation.config.js new file mode 100644 index 0000000000..75f8275fb3 --- /dev/null +++ b/examples/module-federation/remote/module-federation.config.js @@ -0,0 +1,20 @@ +const { dependencies } = require('./package.json'); + +module.exports = { + name: 'remote', + exposes: { + './Button': './src/Button', + }, + filename: 'remoteEntry.js', + shared: { + ...dependencies, + react: { + singleton: true, + requiredVersion: dependencies.react, + }, + 'react-dom': { + singleton: true, + requiredVersion: dependencies['react-dom'], + }, + }, +}; diff --git a/examples/module-federation/remote/package.json b/examples/module-federation/remote/package.json new file mode 100644 index 0000000000..4c3b575637 --- /dev/null +++ b/examples/module-federation/remote/package.json @@ -0,0 +1,16 @@ +{ + "name": "@examples/module-federation-remote", + "private": true, + "scripts": { + "dev": "rsbuild dev", + "build": "rsbuild build" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@rsbuild/core": "workspace:*", + "@rsbuild/plugin-react": "workspace:*" + } +} diff --git a/examples/module-federation/remote/rsbuild.config.ts b/examples/module-federation/remote/rsbuild.config.ts new file mode 100644 index 0000000000..b8a7bd8914 --- /dev/null +++ b/examples/module-federation/remote/rsbuild.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import mfConfig from './module-federation.config'; + +export default defineConfig({ + plugins: [pluginReact()], + server: { + port: 3002, + }, + performance: { + chunkSplit: { + strategy: 'split-by-experience', + override: { + chunks: 'async', + minSize: 30000, + }, + }, + }, + tools: { + rspack(config, { rspack, mergeConfig }) { + return mergeConfig(config, { + output: { + publicPath: 'auto', + }, + plugins: [new rspack.container.ModuleFederationPlugin(mfConfig)], + }); + }, + }, +}); diff --git a/examples/module-federation/remote/src/App.js b/examples/module-federation/remote/src/App.js new file mode 100644 index 0000000000..c2689dc3ba --- /dev/null +++ b/examples/module-federation/remote/src/App.js @@ -0,0 +1,11 @@ +import LocalButton from './Button'; + +const App = () => ( +
+

Basic Host-Remote

+

Remote

+ +
+); + +export default App; diff --git a/examples/module-federation/remote/src/Button.js b/examples/module-federation/remote/src/Button.js new file mode 100644 index 0000000000..c67c7c3bd9 --- /dev/null +++ b/examples/module-federation/remote/src/Button.js @@ -0,0 +1,2 @@ +const Button = () => ; +export default Button; diff --git a/examples/module-federation/remote/src/bootstrap.js b/examples/module-federation/remote/src/bootstrap.js new file mode 100644 index 0000000000..c9ebadbf85 --- /dev/null +++ b/examples/module-federation/remote/src/bootstrap.js @@ -0,0 +1,11 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; + +import App from './App'; + +ReactDOM.render( + + + , + document.getElementById('root'), +); diff --git a/examples/module-federation/remote/src/index.js b/examples/module-federation/remote/src/index.js new file mode 100644 index 0000000000..b93c7a0268 --- /dev/null +++ b/examples/module-federation/remote/src/index.js @@ -0,0 +1 @@ +import('./bootstrap'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6066afddc1..556aa8ee18 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -316,6 +316,38 @@ importers: specifier: ^5.3.0 version: 5.3.2 + examples/module-federation/host: + dependencies: + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + devDependencies: + '@rsbuild/core': + specifier: link:../../../packages/core + version: link:../../../packages/core + '@rsbuild/plugin-react': + specifier: link:../../../packages/plugin-react + version: link:../../../packages/plugin-react + + examples/module-federation/remote: + dependencies: + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + devDependencies: + '@rsbuild/core': + specifier: link:../../../packages/core + version: link:../../../packages/core + '@rsbuild/plugin-react': + specifier: link:../../../packages/plugin-react + version: link:../../../packages/plugin-react + examples/node: devDependencies: '@rsbuild/core':