快速上手
在阅读本指南前,请先阅读 设置环境。本指南将引导你逐步学习使用 Module Federation。我们将构建两个独立的单页面应用程序 (SPA),它们会使用 Module Federation 共享组件,下文中遇到不熟的名词请查看名词解释。
新项目创建
Module Federation 提供了 create-module-federation
工具来创建项目,不需要全局安装,直接使用 npx 按需运行即可。
你可以使用 create-module-federation
来创建一个 Module Federation 项目,调用以下命令:
npm create module-federation@latest
按照提示一步步操作即可。在创建过程中,你可以选择项目类型、角色类型等。
模板
在创建项目时,你可以选择 create-module-federation
提供的下列模板:
模板 |
描述 |
provider-modern |
使用 Modern.js 的生产者 |
provider-rsbuild |
使用 Rsbuild 的生产者 |
provider-rslib |
使用 Rslib 的生产者 |
provider-rslib-storybook |
使用 Rslib 的生产者,并且开启了 storybook 功能 |
consumer-modern |
使用 Modern.js 的消费者 |
consumer-rsbuild |
使用 Rsbuild 的消费者 |
快速创建
create-module-federation 提供了一些 CLI 选项。通过设置这些 CLI 选项,你可以跳过交互式的选择步骤,一键创建项目。
比如,一键创建名称为 provider 的 Modern.js 生产者项目到 my-project
目录:
npx create-module-federation --dir my-project --template provider-modern --name provider
# 使用缩写
npx create-module-federation -d my-project -t provider-modern -n provider
create-module-federation
完整的 CLI 选项如下:
Usage: create-module-federation [options]
Options:
-h, --help display help for command
-d, --dir create project in specified directory
-t, --template specify the template to use
-n, --name specify the mf name
-r, --role specify the mf role type: provider or consumer
--override override files in target directory
Templates:
provider-modern, provider-rsbuild, provider-rslib, provider-rslib-storybook, consumer-modern, consumer-rsbuild
创建一个生产者
执行 create-module-federation
命令,按照需求选择需要的框架和类型,并选择角色类型为生产者即可创建项目。
此处以创建一个 rsbuild 生产者项目为例:
➜ ~ ✗ npm create module-federation@latest
> npx
> create-module-federation
◆ Create Module Federation Project
│
◇ Please input Module Federation name:
│ mf_provider
│
◇ Please select the type of project you want to create:
│ Application
│
◇ Select template
│ Rsbuild
│
◇ Please select the role of project you want to create:
│ Provider
│
◇ Next steps ─────╮
│ │
│ cd mf_provider │
│ npm install │
│ npm run dev │
│ │
├──────────────────╯
│
└ Done.
创建一个消费者
执行 create-module-federation
命令,按照需求选择需要的框架和类型,并选择角色类型为消费者即可创建项目。
此处以创建一个 rsbuild 消费者项目为例:
➜ ~ ✗ npm create module-federation@latest
> npx
> create-module-federation
◆ Create Module Federation Project
│
◇ Please input Module Federation name:
│ mf_consumer
│
◇ Please select the type of project you want to create:
│ Application
│
◇ Select template
│ Rsbuild
│
◇ Please select the role of project you want to create:
│ Consumer
│
◇ Next steps ─────╮
│ │
│ cd mf_provider │
│ npm install │
│ npm run dev │
│ │
├──────────────────╯
│
└ Done.
替换生产者
默认创建的消费者项目会消费一个已发布的生产者,如果你想替换生产者,需要在 module-federation.config.ts
中修改 remotes
配置。
module-federation.config.ts
import { createModuleFederationConfig } from '@module-federation/rsbuild-plugin';
export default createModuleFederationConfig({
name: 'mf_consumer',
remotes: {
- 'provider': 'rslib_provider@https://unpkg.com/module-federation-rslib-provider@latest/dist/mf/mf-manifest.json',
+ 'provider': 'rslib_provider@http://localhost:3000/mf-manifest.json',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
});
已有项目创建
创建一个生产者
1. 初始化项目
使用 Rsbuild 来创建一个生产者,调用以下命令:
npm create rsbuild@latest
根据提示完成项目创建
? Input target folder -> federation_provider
? Select framework -> React
? Select language -> TypeScript
2. 安装 Module Federation 构建插件
根据上面初始化项目的步骤,我们创建了名为 federation_provider
的 React
项目,依次执行以下命令
cd federation_provider
npm add @module-federation/enhanced
npm add @module-federation/rsbuild-plugin --save-dev
3. 生产者导出模块
将入口改为异步
// 移动 src/index.tsx 到新建的 src/bootstrap.tsx 文件中
// src/index.tsx
import('./bootstrap');
// src/bootstrap.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
增加 Button 组件
// src/button.tsx
export default function Button() {
return <div>Provider button</div>;
}
通过 Module Federation 导出 Button 组件
rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
export default defineConfig({
plugins: [
pluginReact(),
pluginModuleFederation({
name: 'federation_provider',
exposes: {
'./button': './src/button.tsx',
},
shared: ['react', 'react-dom'],
}),
],
server: {
port: 3000,
},
});
4. 启动生产者
➜ federation_provider npm run dev
> federation_provider@1.0.0 dev
> rsbuild dev --open
Rsbuild v0.5.1
> Local: http://localhost:3000/
> Network: http://10.94.55.204:3000/
> Network: http://10.4.255.21:3000/
start Compiling...
[ Module Federation Manifest Plugin ] Manifest Link: http://localhost:3000/mf-manifest.json
项目启动后出现 Manifest Link: http://localhost:3000/mf-manifest.json
信息,这是 Module federation 的 manifest 信息链接
创建一个消费者
1. 初始化项目
使用 Rsbuild 来创建一个消费者,调用以下命令:
npm create rsbuild@latest
根据提示完成项目创建
? Input target folder -> federation_consumer
? Select framework -> React
? Select language -> TypeScript
2. 安装 Module Federation 构建插件
根据上面初始化项目的步骤,我们创建了名为 federation_consumer
的 React
项目,依次执行以下命令
cd federation_consumer
npm add @module-federation/enhanced
npm add @module-federation/rsbuild-plugin --save-dev
3. 消费生产者
增加 Module Federation 插件消费远程模块
rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
export default defineConfig({
plugins: [
pluginReact(),
pluginModuleFederation({
name: 'federation_consumer',
remotes: {
federation_provider:
'federation_provider@http://localhost:3000/mf-manifest.json',
},
shared: ['react', 'react-dom'],
}),
],
server: {
port: 2000,
},
});
将入口改为异步
// 移动 src/index.tsx 到新建的 src/bootstrap.tsx 文件中
// src/index.tsx
import('./bootstrap');
// src/bootstrap.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
在 tsconfig.json
中声明 Module Federation
类型路径
{
"compilerOptions": {
"paths": {
"*": ["./@mf-types/*"]
}
}
}
引用远程模块
import './App.css';
// federation_provider 提供的远程组件
import ProviderButton from 'federation_provider/button';
const App = () => {
return (
<div className="content">
<h1>Rsbuild with React</h1>
<p>Start building amazing things with Rsbuild.</p>
<div>
<ProviderButton />
</div>
</div>
);
};
export default App;
总结
通过上面的流程你已经基于 Module Federation 完成了一个「生产者」导出一个组件给到「消费者」使用,并在过程中初步使用和了解了:Module Fderation 插件中的 remotes、exposes、shared 的配置。
如果你希望了解如何直接在 Webpack、Rspack 构建工具上导出和消费远程模块可以参考:Rspack Plugin、Webpack Plugin
下一步
你可能想要: