Skip to content

Commit 99bb1e4

Browse files
fi3eworkJSerFengchenjiahan
authored
docs(ESM): add ESM guide (#11344)
* docs(ESM): add ESM guide * Update website/docs/zh/guide/features/esm.mdx Co-authored-by: Fy <[email protected]> * fix * Update website/docs/zh/guide/features/esm.mdx Co-authored-by: neverland <[email protected]> * Update website/docs/en/guide/features/esm.mdx Co-authored-by: neverland <[email protected]> * Update website/docs/zh/guide/features/esm.mdx Co-authored-by: neverland <[email protected]> * Update website/docs/en/guide/features/esm.mdx Co-authored-by: neverland <[email protected]> * Update website/docs/en/guide/features/esm.mdx Co-authored-by: neverland <[email protected]> * refactor * up --------- Co-authored-by: Fy <[email protected]> Co-authored-by: neverland <[email protected]>
1 parent b36069e commit 99bb1e4

File tree

4 files changed

+198
-2
lines changed

4 files changed

+198
-2
lines changed

website/docs/en/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: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { Stability } from '@components/ApiMeta';
2+
3+
# ESM output
4+
5+
Rspack supports building with ESM format output. When building applications, Rspack generates IIFE-based bundled output by default instead of standard CommonJS or ESM format. You can configure [output.module](/config/output#outputmodule) to generate ESM format output. The following sections introduce how to [build application ESM output](#building-application-esm-output) and [build library ESM output](#building-library-esm-output), and finally list the [configuration checklist](#configuration-checklist) related to ESM output.
6+
7+
## Building application ESM output
8+
9+
When building applications, Rspack generates CommonJS-like format output by default. If you need to generate ESM format output, you can configure it in `rspack.config.mjs` as follows:
10+
11+
```js title="rspack.config.mjs"
12+
export default {
13+
//...
14+
output: {
15+
module: true,
16+
chunkFormat: 'module',
17+
chunkLoading: 'import',
18+
workerChunkLoading: 'import',
19+
},
20+
experiments: {
21+
outputModule: true,
22+
},
23+
};
24+
```
25+
26+
You can check out examples of [building React applications to ESM output](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/react-refresh-esm) and [React ESM SSR](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/react-ssr-esm) in rspack-examples.
27+
28+
## Building library ESM output
29+
30+
We recommend using [Rslib](https://rslib.rs) to build library output. Rslib is built on top of Rspack and can build multiple formats including ES Module, CommonJS, and UMD. Rslib provides higher-level APIs that simplify the library building process. Compared to using Rspack directly, using Rslib for library building is more convenient and efficient.
31+
32+
If you need to use Rspack directly to build ESM format output for libraries (npm library), you need to configure the following:
33+
34+
```js title="rspack.config.mjs"
35+
export default {
36+
//...
37+
output: {
38+
module: true,
39+
chunkFormat: 'module',
40+
externalsType: "module-import",
41+
library: {
42+
type: 'modern-module',
43+
}
44+
chunkLoading: 'import',
45+
workerChunkLoading: 'import',
46+
},
47+
optimization: {
48+
concatenateModules: true,
49+
avoidEntryIife: true,
50+
minimize: false,
51+
},
52+
experiments: {
53+
outputModule: true,
54+
},
55+
};
56+
```
57+
58+
You can check out this [rspack-examples](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/library-esm) ESM library example.
59+
60+
Building ESM output also requires handling various detailed issues, which are not listed exhaustively here. You can refer to the [ESM format related configurations in Rslib](https://github.com/web-infra-dev/rslib/blob/f727b18805767b99fb85ae67ebff959aa644536e/packages/core/src/config.ts), or use Rslib directly for out-of-the-box library building.
61+
62+
## Future plans for ESM output
63+
64+
Currently, Rspack's ESM support is still being improved. In certain use cases, you may encounter integration issues between ESM and other features. The main limitations include:
65+
66+
1. Lack of static analysis friendly code splitting support
67+
2. Limited custom chunk splitting support in ESM format
68+
3. Lack of module-level side effect information preservation, affecting tree-shaking accuracy
69+
4. Re-exports of external modules (`export * from '...'`) cannot be properly preserved in ESM format
70+
71+
We are continuously improving Rspack's ESM support to provide a comprehensive solution that addresses existing issues and makes ESM usage more simple and intuitive, better embracing the modern JavaScript module system.
72+
73+
## Configuration checklist
74+
75+
Below are the main configuration options related to ESM and their descriptions, which are used when building both applications and libraries.
76+
77+
1. [output.module](/config/output#outputmodule): Set to `true` to generate ESM format output. When this option is enabled, it affects the following configurations:
78+
1. Affects [externalsType](/config/externals#externalstype) default value: When `output.module` is `true`, `externalsType` defaults to `'module-import'`
79+
2. Affects [output.filename](/config/output#outputfilename) default value: When `output.module` is `true`, the default filename is `'[name].mjs'` instead of `'[name].js'`
80+
3. Affects [output.chunkFilename](/config/output#outputchunkfilename) default value: When `output.module` is `true`, chunk filename defaults to `'[id].mjs'` instead of `'[id].js'`
81+
4. Affects [output.hotUpdateChunkFilename](/config/output#outputhotupdatechunkfilename) default value: When `output.module` is `true`, defaults to `'[id].[fullhash].hot-update.mjs'`
82+
5. Affects [output.hotUpdateMainFilename](/config/output#outputhotupdatemainfilename) default value: When `output.module` is `true`, defaults to `'[runtime].[fullhash].hot-update.json.mjs'`
83+
6. Affects [output.iife](/config/output#outputiife) default value: When `output.module` is `true`, `output.iife` defaults to `false`
84+
7. Affects [output.library.type](/config/output#outputlibrarytype) default value: When `output.module` is `true`, defaults to `'module'` instead of `'var'`
85+
8. Affects [output.scriptType](/config/output#outputscripttype) default value: When `output.module` is `true`, defaults to `'module'`
86+
9. Affects [output.environment.dynamicImport](/config/output#outputenvironmentdynamicimport) default value: Enabled when `output.module` is `true`
87+
10. Affects [output.environment.dynamicImportInWorker](/config/output#outputenvironmentdynamicimportinworker) default value: Enabled when `output.module` is `true`
88+
11. Affects [output.environment.module](/config/output#outputenvironmentmodule) default value: Enabled when `output.module` is `true`
89+
12. Affects Node.js related configuration defaults: In Node.js environment, when `output.module` is `true`, `__filename` and `__dirname` default to `'node-module'`
90+
2. [output.chunkFormat](/config/output#outputchunkformat): Set to `'module'` to use ESM format.
91+
3. [output.library.type](/config/output#outputlibrarytype): Set to `'modern-module'` for additional optimization of library ESM output format.
92+
4. [output.chunkLoading](/config/output#outputchunkloading): Set to `'import'` to use ESM `import` for loading chunks.
93+
5. [output.workerChunkLoading](/config/output#outputworkerchunkloading): Set to `'import'` to use ESM `import` for loading workers.
94+
6. [optimization.concatenateModules](/config/optimization#optimizationconcatenatemodules): modern-module depends on this option being enabled to ensure the output supports good tree-shaking and correct library exports.
95+
7. [optimization.avoidEntryIife](/config/optimization#optimizationavoidentryiife): In some cases, Rspack wraps ESM output in an IIFE, which breaks ESM's modular characteristics.
96+
8. [experiments.outputModule](/config/experiments#experimentsoutputmodule): Enable the experimental feature required for output.module.
97+
9. [HtmlWebpackPlugin.scriptLoading](/guide/tech/html#htmlwebpackplugin): Set to `'module'` to use ESM `<script type="module">` for loading `.mjs` modules.

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

0 commit comments

Comments
 (0)