Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion website/docs/en/guide/features/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"web-workers",
"lazy-compilation",
"builtin-swc-loader",
"builtin-lightningcss-loader"
"builtin-lightningcss-loader",
"esm"
]
97 changes: 97 additions & 0 deletions website/docs/en/guide/features/esm.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Stability } from '@components/ApiMeta';

# ESM output

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.

## Building application ESM output

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:

```js title="rspack.config.mjs"
export default {
//...
output: {
module: true,
chunkFormat: 'module',
chunkLoading: 'import',
workerChunkLoading: 'import',
},
experiments: {
outputModule: true,
},
};
```

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.

## Building library ESM output

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.

If you need to use Rspack directly to build ESM format output for libraries (npm library), you need to configure the following:

```js title="rspack.config.mjs"
export default {
//...
output: {
module: true,
chunkFormat: 'module',
externalsType: "module-import",
library: {
type: 'modern-module',
}
chunkLoading: 'import',
workerChunkLoading: 'import',
},
optimization: {
concatenateModules: true,
avoidEntryIife: true,
minimize: false,
},
experiments: {
outputModule: true,
},
};
```

You can check out this [rspack-examples](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/library-esm) ESM library example.

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.

## Future plans for ESM output

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:

1. Lack of static analysis friendly code splitting support
2. Limited custom chunk splitting support in ESM format
3. Lack of module-level side effect information preservation, affecting tree-shaking accuracy
4. Re-exports of external modules (`export * from '...'`) cannot be properly preserved in ESM format

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.

## Configuration checklist

Below are the main configuration options related to ESM and their descriptions, which are used when building both applications and libraries.

1. [output.module](/config/output#outputmodule): Set to `true` to generate ESM format output. When this option is enabled, it affects the following configurations:
1. Affects [externalsType](/config/externals#externalstype) default value: When `output.module` is `true`, `externalsType` defaults to `'module-import'`
2. Affects [output.filename](/config/output#outputfilename) default value: When `output.module` is `true`, the default filename is `'[name].mjs'` instead of `'[name].js'`
3. Affects [output.chunkFilename](/config/output#outputchunkfilename) default value: When `output.module` is `true`, chunk filename defaults to `'[id].mjs'` instead of `'[id].js'`
4. Affects [output.hotUpdateChunkFilename](/config/output#outputhotupdatechunkfilename) default value: When `output.module` is `true`, defaults to `'[id].[fullhash].hot-update.mjs'`
5. Affects [output.hotUpdateMainFilename](/config/output#outputhotupdatemainfilename) default value: When `output.module` is `true`, defaults to `'[runtime].[fullhash].hot-update.json.mjs'`
6. Affects [output.iife](/config/output#outputiife) default value: When `output.module` is `true`, `output.iife` defaults to `false`
7. Affects [output.library.type](/config/output#outputlibrarytype) default value: When `output.module` is `true`, defaults to `'module'` instead of `'var'`
8. Affects [output.scriptType](/config/output#outputscripttype) default value: When `output.module` is `true`, defaults to `'module'`
9. Affects [output.environment.dynamicImport](/config/output#outputenvironmentdynamicimport) default value: Enabled when `output.module` is `true`
10. Affects [output.environment.dynamicImportInWorker](/config/output#outputenvironmentdynamicimportinworker) default value: Enabled when `output.module` is `true`
11. Affects [output.environment.module](/config/output#outputenvironmentmodule) default value: Enabled when `output.module` is `true`
12. Affects Node.js related configuration defaults: In Node.js environment, when `output.module` is `true`, `__filename` and `__dirname` default to `'node-module'`
2. [output.chunkFormat](/config/output#outputchunkformat): Set to `'module'` to use ESM format.
3. [output.library.type](/config/output#outputlibrarytype): Set to `'modern-module'` for additional optimization of library ESM output format.
4. [output.chunkLoading](/config/output#outputchunkloading): Set to `'import'` to use ESM `import` for loading chunks.
5. [output.workerChunkLoading](/config/output#outputworkerchunkloading): Set to `'import'` to use ESM `import` for loading workers.
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.
7. [optimization.avoidEntryIife](/config/optimization#optimizationavoidentryiife): In some cases, Rspack wraps ESM output in an IIFE, which breaks ESM's modular characteristics.
8. [experiments.outputModule](/config/experiments#experimentsoutputmodule): Enable the experimental feature required for output.module.
9. [HtmlWebpackPlugin.scriptLoading](/guide/tech/html#htmlwebpackplugin): Set to `'module'` to use ESM `<script type="module">` for loading `.mjs` modules.
3 changes: 2 additions & 1 deletion website/docs/zh/guide/features/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"web-workers",
"lazy-compilation",
"builtin-swc-loader",
"builtin-lightningcss-loader"
"builtin-lightningcss-loader",
"esm"
]
97 changes: 97 additions & 0 deletions website/docs/zh/guide/features/esm.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Stability } from '@components/ApiMeta';

# ESM 格式产物

Rspack 支持使用 ESM 格式输出进行打包。构建应用时,Rspack 默认会生成基于 IIFE 格式代码的打包输出,而不是标准的 CommonJS 或 ESM 格式,你可以通过配置 [output.module](/config/output#outputmodule) 来生成 ESM 格式的产物。下面的章节介绍了如何 [构建应用的 ESM 格式产物](#构建应用的-esm-格式产物) 及 [构建库的 ESM 格式产物](#构建库的-esm-格式产物) 并在最后列出了与 ESM 产物相关的 [配置清单](#配置清单)。

## 构建应用的 ESM 格式产物

在构建应用时,Rspack 默认依赖 Rspack runtime 的。如果你需要生成 ESM 格式的产物,可以在 `rspack.config.mjs` 中进行如下配置:

```js title="rspack.config.mjs"
export default {
//...
output: {
module: true,
chunkFormat: 'module',
chunkLoading: 'import',
workerChunkLoading: 'import',
},
experiments: {
outputModule: true,
},
};
```

你可以在 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) 的示例。

## 构建库的 ESM 格式产物

推荐使用 [Rslib](https://rslib.rs) 来构建库产物,Rslib 底层基于 Rspack 实现,能够构建 ES Module、CommonJS 和 UMD 等多种格式的产物。Rslib 提供了更高层次的 API,简化了库的构建过程。相比直接使用 Rspack,使用 Rslib 进行库的构建会更加方便和高效。

如果你需要直接使用 Rspack 构建库(npm library)的 ESM 格式产物,需要同时进行以下配置:

```js title="rspack.config.mjs"
export default {
//...
output: {
module: true,
chunkFormat: 'module',
externalsType: "module-import",
library: {
type: 'modern-module',
}
chunkLoading: 'import',
workerChunkLoading: 'import',
},
optimization: {
concatenateModules: true,
avoidEntryIife: true,
minimize: false,
},
experiments: {
outputModule: true,
},
};
```

你可以查看 [rspack-examples](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/library-esm) 中这个使用 ESM 库的例子。

进行 ESM 产物的打包还需要处理各种细节问题,这里不逐一列举。你可以参考 [Rslib 中对 ESM 格式的相关配置](https://github.com/web-infra-dev/rslib/blob/f727b18805767b99fb85ae67ebff959aa644536e/packages/core/src/config.ts),或者直接使用 Rslib 开箱即用地进行库的构建。

## ESM 产物未来规划

当前 Rspack 的 ESM 支持仍有待完善,在某些使用场景中,你可能会遇到 ESM 与其他功能的集成问题。主要限制包括:

1. 缺少对静态分析友好的代码分割支持
2. ESM 格式下的自定义 chunk splitting 支持有限
3. 缺少模块级别的副作用信息保留,影响 tree-shaking 的精确性
4. 外部模块的重新导出(`export * from '...'`)在 ESM 格式下无法正确保留

我们正在持续改进 Rspack 的 ESM 支持,致力于提供完善的 ESM 方案,解决现有问题,使 ESM 的使用和配置更加简单直观,更好地拥抱现代 JavaScript 模块系统。

## 配置清单

下面列出了与 ESM 相关的主要配置选项及其说明,这些配置在构建应用和库时都会用到。

1. [output.module](/config/output#outputmodule): 设置为 `true`,表示生成 ESM 格式的产物。开启此选项后,会对以下配置产生影响:
1. 影响 [externalsType](/config/externals#externalstype) 默认值:当 `output.module` 为 `true` 时,`externalsType` 默认为 `'module-import'`
2. 影响 [output.filename](/config/output#outputfilename) 默认值:当 `output.module` 为 `true` 时,默认文件名为 `'[name].mjs'` 而不是 `'[name].js'`
3. 影响 [output.chunkFilename](/config/output#outputchunkfilename) 默认值:当 `output.module` 为 `true` 时,chunk 文件名默认为 `'[id].mjs'` 而不是 `'[id].js'`
4. 影响 [output.hotUpdateChunkFilename](/config/output#outputhotupdatechunkfilename) 默认值:当 `output.module` 为 `true` 时,默认为 `'[id].[fullhash].hot-update.mjs'`
5. 影响 [output.hotUpdateMainFilename](/config/output#outputhotupdatemainfilename) 默认值:当 `output.module` 为 `true` 时,默认为 `'[runtime].[fullhash].hot-update.json.mjs'`
6. 影响 [output.iife](/config/output#outputiife) 默认值:当 `output.module` 为 `true` 时,`output.iife` 默认为 `false`
7. 影响 [output.library.type](/config/output#outputlibrarytype) 默认值:当 `output.module` 为 `true` 时,默认为 `'module'` 而不是 `'var'`
8. 影响 [output.scriptType](/config/output#outputscripttype) 默认值:当 `output.module` 为 `true` 时,默认为 `'module'`
9. 影响 [output.environment.dynamicImport](/config/output#outputenvironmentdynamicimport) 默认值:当 `output.module` 为 `true` 时会被启用
10. 影响 [output.environment.dynamicImportInWorker](/config/output#outputenvironmentdynamicimportinworker) 默认值:当 `output.module` 为 `true` 时会被启用
11. 影响 [output.environment.module](/config/output#outputenvironmentmodule) 默认值:当 `output.module` 为 `true` 时会被启用
12. 影响 Node.js 相关配置的默认值:在 Node.js 环境下,当 `output.module` 为 `true` 时,`__filename` 和 `__dirname` 默认为 `'node-module'`
2. [output.chunkFormat](/config/output#outputchunkformat): 设置为 `'module'`,表示使用 ESM 格式。
3. [output.library.type](/config/output#outputlibrarytype): 设置为 `'modern-module'`,表示对库的 ESM 产物格式进行额外的优化。
4. [output.chunkLoading](/config/output#outputchunkloading): 设置为 `'import'`,表示使用 ESM 的 `import` 来加载 chunk。
5. [output.workerChunkLoading](/config/output#outputworkerchunkloading): 设置为 `'import'`,表示使用 ESM 的 `import` 来加载 worker
6. [optimization.concatenateModules](/config/optimization#optimizationconcatenatemodules): modern-module 依赖此选项的开启来保证输出的产物支持良好的 tree-shaking 和库的正确导出
7. [optimization.avoidEntryIife](/config/optimization#optimizationavoidentryiife): 在某些情况下,Rspack 会将 ESM 产物的输出包裹在一个 IIFE 中,这会破坏 ESM 的模块化特性
8. [experiments.outputModule](/config/experiments#experimentsoutputmodule): 开启 output.module 所需的前置实验特性
9. [HtmlWebpackPlugin.scriptLoading](/guide/tech/html#htmlwebpackplugin): 设置为 `'module'`,表示使用 ESM 的 `<script type="module">` 来加载 `.mjs` 模块。
Loading