Skip to content

Commit e171f96

Browse files
author
nyqykk
committed
docs: add doc for rsbuild plugin
1 parent cbce384 commit e171f96

File tree

6 files changed

+161
-18
lines changed

6 files changed

+161
-18
lines changed

examples/module-federation/mf-react-component/rslib.config.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@ export default defineConfig({
3636
root: './dist/mf',
3737
},
3838
assetPrefix: 'http://localhost:3001/mf',
39-
minify: false,
40-
},
41-
source: {
42-
define: {
43-
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
44-
},
4539
},
4640
plugins: [
4741
pluginModuleFederation({
@@ -61,11 +55,5 @@ export default defineConfig({
6155
],
6256
},
6357
],
64-
plugins: [
65-
pluginReact({
66-
splitChunks: {
67-
react: false,
68-
},
69-
}),
70-
],
58+
plugins: [pluginReact()],
7159
});

packages/core/src/config.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,9 @@ export const composeAutoExternalConfig = (options: {
285285
: {};
286286
};
287287

288-
export function composeMinifyConfig(
289-
minify: NonNullable<RsbuildConfig['output']>['minify'],
290-
): RsbuildConfig {
288+
export function composeMinifyConfig(config: LibConfig): RsbuildConfig {
289+
const minify = config.output?.minify;
290+
const format = config.format;
291291
if (minify !== undefined) {
292292
// User's minify configuration will be merged afterwards.
293293
return {};
@@ -308,7 +308,8 @@ export function composeMinifyConfig(
308308
defaults: false,
309309
unused: true,
310310
dead_code: true,
311-
toplevel: true,
311+
// mf format if use toplevel, remoteEntry's global variable will be tree-shaking
312+
toplevel: format !== 'mf',
312313
},
313314
format: {
314315
comments: 'all',
@@ -1033,7 +1034,7 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
10331034
autoExternalConfig?.output?.externals,
10341035
externalsConfig?.output?.externals,
10351036
);
1036-
const minifyConfig = composeMinifyConfig(config.output?.minify);
1037+
const minifyConfig = composeMinifyConfig(config);
10371038
const bannerFooterConfig = composeBannerFooterConfig(banner, footer);
10381039
const decoratorsConfig = composeDecoratorsConfig(
10391040
compilerOptions,

website/docs/zh/guide/_meta.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,10 @@
88
"type": "dir",
99
"name": "basic",
1010
"label": "基础"
11+
},
12+
{
13+
"type": "dir",
14+
"name": "advanced",
15+
"label": "进阶"
1116
}
1217
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
["module-federation"]
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Module Federation
2+
3+
本章节将介绍如何在 Rslib 中快速构建 Module Federation 产物
4+
5+
## 名词解释
6+
7+
Module Federation 是一种 JavaScript 应用分治的架构模式(类似于服务端的微服务),它允许你在多个 JavaScript 应用程序(或微前端)之间共享代码和资源。
8+
9+
## 使用场景
10+
11+
模块联邦有一些典型的使用场景,包括:
12+
13+
允许独立应用(在微前端架构中称为"微前端")之间共享模块,无需重新编译整个应用。
14+
不同的团队在不需要重新编译整个应用的情况下处理同一应用的不同部分。
15+
应用之间在运行时进行动态代码加载和共享。
16+
模块联邦可以帮助你:
17+
18+
- 减少代码重复
19+
- 提高代码可维护性
20+
- 降低应用程序的整体大小
21+
- 提高应用程序的性能
22+
23+
## 快速接入
24+
25+
首先安装 Module Federation Rsbuild 插件(Rslib 基于 Rsbuild 构建)
26+
27+
import { PackageManagerTabs } from '@theme';
28+
29+
<PackageManagerTabs
30+
command={{
31+
npm: 'npm add @module-federation/rsbuild-plugin --save-dev',
32+
yarn: 'yarn add @module-federation/rsbuild-plugin --save-dev',
33+
pnpm: 'pnpm add @module-federation/rsbuild-plugin --save-dev',
34+
bun: 'bun add @module-federation/rsbuild-plugin --save-dev',
35+
}}
36+
/>
37+
38+
将插件添加到 `rslib.config.ts`
39+
40+
```ts title='rslib.config.ts'
41+
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
42+
import { pluginReact } from '@rsbuild/plugin-react';
43+
import { defineConfig } from '@rslib/core';
44+
45+
export default defineConfig({
46+
lib: [
47+
// ... other format
48+
{
49+
format: 'mf',
50+
output: {
51+
distPath: {
52+
root: './dist/mf',
53+
},
54+
// add your assetPrefix here
55+
// assetPrefix: 'http://localhost:3001/mf',
56+
},
57+
plugins: [
58+
pluginModuleFederation({
59+
name: 'rslib_provider',
60+
exposes: {
61+
// add expose here
62+
},
63+
// can not add 'remote' here, because you may build 'esm' or 'cjs' assets in one build.
64+
// if you want the rslib package use remote module, please see below.
65+
shared: {
66+
react: {
67+
singleton: true,
68+
},
69+
'react-dom': {
70+
singleton: true,
71+
},
72+
},
73+
}),
74+
],
75+
},
76+
],
77+
plugins: [pluginReact()],
78+
});
79+
```
80+
81+
这样我们就完成了 Rslib Module 作为生产者的接入,构建完成后可以看到产物中新增了 mf 目录,消费者可以直接消费这个包
82+
83+
在上面的例子中我们增加了一个新的 `format: 'mf'`,这会帮助你新增一份额外的 Module Federation 产物,与此同时还可以配置 `cjs``esm` 的 format,这并不冲突。
84+
85+
但是如果希望这个 Rslib Module 同时可以消费其他生产者,请不要使用构建配置 `remote` 参数,因为在其他 format 中,这可能会导致错误,请参考下方使用 Module Federation 运行时的例子
86+
87+
## 消费其他 Module Federation 模块
88+
89+
因为 Rslib 中有多种 format,如果在构建时配置 `remote` 参数来消费其他模块可能无法在所有 format 中都能正常工作,推荐通过 [Module Federation Runtime](https://module-federation.io/guide/basic/runtime.html) 进行接入
90+
91+
首先安装运行时依赖
92+
93+
<PackageManagerTabs
94+
command={{
95+
npm: 'npm add @module-federation/enhanced --save',
96+
yarn: 'yarn add @module-federation/enhanced --save',
97+
pnpm: 'pnpm add @module-federation/enhanced --save',
98+
bun: 'bun add @module-federation/enhanced --save',
99+
}}
100+
/>
101+
102+
然后在运行时消费其他 Module Federation 模块,例如
103+
104+
```ts
105+
import { init, loadRemote } from '@module-federation/rsbuild-plugin/runtime';
106+
import { Suspense, createElement, lazy } from 'react';
107+
108+
init({
109+
name: 'rslib_provider',
110+
remotes: [
111+
{
112+
name: 'mf_remote',
113+
entry: 'http://localhost:3002/mf-manifest.json',
114+
},
115+
],
116+
});
117+
118+
export const Counter: React.FC = () => {
119+
return (
120+
<div>
121+
<Suspense fallback={<div>loading</div>}>
122+
{createElement(
123+
lazy(
124+
() =>
125+
loadRemote('mf_remote') as Promise<{
126+
default: React.FC;
127+
}>,
128+
),
129+
)}
130+
</Suspense>
131+
</div>
132+
);
133+
};
134+
```
135+
136+
这样可以保证在多种 format 中都能按预期进行加载模块
137+
138+
## 参考例子
139+
140+
[Rslib Module Federation Example](https://github.com/web-infra-dev/rslib/tree/main/examples/module-federation)
141+
142+
- `mf-host`: Rsbuild App 消费者
143+
- `mf-react-component`: Rslib Module,同时是生产者和消费者,作为生产者提供模块给 `mf-host` 使用,作为消费者通过运行时消费 `mf-remote`
144+
- `mf-remote`: Rsbuild App 生产者

website/docs/zh/guide/start/index.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,8 @@ import Step from '@components/Step';
5252
title="查阅配置"
5353
description="了解如何配置 Rslib"
5454
/>
55+
<Step
56+
href="/guide/advanced/module-federation"
57+
title="构建 Module Federation 产物"
58+
/>
5559
</NextSteps>

0 commit comments

Comments
 (0)