Skip to content

Commit 1955ec0

Browse files
committed
docs(ESM): add ESM guide
1 parent d406a66 commit 1955ec0

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

website/docs/zh/guide/features/_meta.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
"web-workers",
1010
"lazy-compilation",
1111
"builtin-swc-loader",
12-
"builtin-lightningcss-loader"
12+
"builtin-lightningcss-loader",
13+
"esm"
1314
]
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { Stability } from '@components/ApiMeta';
2+
3+
# ESM 格式产物
4+
5+
Rspack 支持打包 ESM 格式的产物。默认情况下,Rspack 会生成 CommonJS 格式的产物,但你可以通过配置 `output.module` 来生成 ESM 格式的产物。
6+
7+
这里先列出与 ESM 相关的配置并解释,这在构建应用和库时都需要用到。
8+
9+
1. [output.module](/config/output#outputmodule): 设置为 `true`,表示生成 ESM 格式的产物,开启时,会
10+
1. 影响 [externalsType](/config/externals#externalstype) 默认值:当 `output.module``true` 时,`externalsType` 默认为 `'module-import'`
11+
2. 影响 [output.filename](/config/output#outputfilename) 默认值:当 `output.module``true` 时,默认文件名为 `'[name].mjs'` 而不是 `'[name].js'`
12+
3. 影响 [output.chunkFilename](/config/output#outputchunkfilename) 默认值:当 `output.module``true` 时,chunk 文件名默认为 `'[id].mjs'` 而不是 `'[id].js'`
13+
4. 影响 [output.hotUpdateChunkFilename](/config/output#outputhotupdatechunkfilename) 默认值:当 `output.module``true` 时,默认为 `'[id].[fullhash].hot-update.mjs'`
14+
5. 影响 [output.hotUpdateMainFilename](/config/output#outputhotupdatemainfilename) 默认值:当 `output.module``true` 时,默认为 `'[runtime].[fullhash].hot-update.json.mjs'`
15+
6. 影响 [output.iife](/config/output#outputiife) 默认值:当 `output.module``true` 时,`output.iife` 默认为 `false`
16+
7. 影响 [output.library.type](/config/output#outputlibrarytype) 默认值:当 `output.module``true` 时,默认为 `'module'` 而不是 `'var'`
17+
8. 影响 [output.scriptType](/config/output#outputscripttype) 默认值:当 `output.module``true` 时,默认为 `'module'`
18+
9. 影响 [output.environment.dynamicImport](/config/output#outputenvironmentdynamicimport) 默认值:当 `output.module``true` 时会被启用
19+
10. 影响 [output.environment.dynamicImportInWorker](/config/output#outputenvironmentdynamicimportinworker) 默认值:当 `output.module``true` 时会被启用
20+
11. 影响 [output.environment.module](/config/output#outputenvironmentmodule) 默认值:当 `output.module``true` 时会被启用
21+
12. 影响 Node.js 相关配置的默认值:在 Node.js 环境下,当 `output.module``true` 时,`__filename``__dirname` 默认为 `'node-module'`
22+
2. [output.chunkFormat](/config/output#outputchunkformat): 设置为 `'module'`,表示使用 ESM 格式。
23+
3. [output.library.type](/config/output#outputlibrarytype): 设置为 `'modern-module'`,表示对库的 ESM 产物格式进行了额外的优化。
24+
4. [output.chunkLoading](/config/output#outputchunkloading): 设置为 `'import'`,表示使用 ESM 的 `import` 来加载 chunk。
25+
5. [output.workerChunkLoading](/config/output#outputworkerchunkloading): 设置为 `'import'`,表示使用 ESM 的 `import` 来加载 worker
26+
6. [optimization.concatenateModules](/config/optimization#optimizationconcatenatemodules): modern-module 依赖 concatenateModules 的开启来保证输出的产物支持良好的 tree-shaking 及库最终的正确导出
27+
7. [optimization.avoidEntryIife](/config/optimization#optimizationavoidentryiife): 在某些情况下,Rspack 会将 ESM 产物的输出包裹在一个 IIFE 中,这将破坏 ESM 的模块化特性
28+
8. [experiments.outputModule](/config/experiments#experimentsoutputmodule): 开启 output.module 需要手动开启的前置实验特性
29+
9. [HtmlWebpackPlugin.scriptLoading](/guide/tech/html#htmlwebpackplugin): 设置为 `'module'`,表示使用 ESM 的 `<script type="module">` 来加载 `.mjs` 模块。
30+
31+
## 构建应用的 ESM 格式产物
32+
33+
在构建应用时,Rspack 会默认生成 CommonJS 格式的产物。如果你需要生成 ESM 格式的产物,可以在 `rspack.config.mjs` 中进行如下配置:
34+
35+
```js title="rspack.config.mjs"
36+
export default {
37+
//...
38+
output: {
39+
module: true,
40+
chunkFormat: 'module',
41+
chunkLoading: 'import',
42+
workerChunkLoading: 'import',
43+
},
44+
experiments: {
45+
outputModule: true,
46+
},
47+
};
48+
```
49+
50+
你可以查看 [rspack-examples](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/react-refresh-esm) 中这个使用 React 应用构建到 ESM 产物的例子。
51+
52+
## 构建库的 ESM 格式产物
53+
54+
推荐使用 [Rslib](https://rslib.rs) 来构建库产物,Rslib 底层的实现基于 Rspack,能够构建 ES Module、CommonJS 和 UMD 等多种格式的产物。Rslib 提供了更高层次的 API,简化了库的构建过程。使用 Rslib 进行库的构建会比直接使用 Rspack 更加方便和高效。
55+
56+
当直接使用 Rspack 支持构建库(npm library)的 ESM 格式产物时,需要同时进行以下配置:
57+
58+
```js title="rspack.config.mjs"
59+
export default {
60+
//...
61+
output: {
62+
module: true,
63+
chunkFormat: 'module',
64+
externalsType: "module-import",
65+
library: {
66+
type: 'modern-module',
67+
}
68+
chunkLoading: 'import',
69+
workerChunkLoading: 'import',
70+
},
71+
optimization: {
72+
concatenateModules: true,
73+
avoidEntryIife: true,
74+
minimize: false, // 在构建库时禁用代码压缩
75+
},
76+
experiments: {
77+
outputModule: true,
78+
},
79+
};
80+
```
81+
82+
你可以查看 [rspack-examples](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/library-esm) 中这个使用 ESM 库的例子。
83+
84+
要进行 ESM 产物的打包还需要处理各种细节问题,这里不再一一列举,可以参考 [Rslib 中对 ESM 格式的相关配置](https://github.com/web-infra-dev/rslib/blob/f727b18805767b99fb85ae67ebff959aa644536e/packages/core/src/config.ts),或者直接使用 Rslib 开箱即用进行库的构建。
85+
86+
## ESM 产物未来规划
87+
88+
现在 Rspack 对 ESM 的支持还很基本,ESM 的产物还没有达到能够完全替代当前的 CommonJS 产物的程度,在很多场景下 ESM 产物也无法正常工作。包括:
89+
90+
1. 没有对静态分析友好的代码分割支持
91+
2. 缺少模块级别的副作用信息保留,影响 tree-shaking 的精确性
92+
3. 缺少对 ESM 产物的 Live Bindings 支持,无法正确处理导出绑定的动态更新
93+
4. 循环依赖处理在 ESM 产物中存在问题
94+
5. 外部模块的重新导出(`export * from '...'`)在 ESM 格式下无法正确保留
95+
96+
Rspack 未来会继续完善对 ESM 的支持,目标是将 ESM 产物视为一等公民,使 ESM 的使用及配置更加简单和直观,更好地拥抱现代 JavaScript 模块系统。

0 commit comments

Comments
 (0)