-
-
Notifications
You must be signed in to change notification settings - Fork 775
docs(ESM): add ESM guide #11344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
docs(ESM): add ESM guide #11344
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
8171750
docs(ESM): add ESM guide
fi3ework e8517a0
Update website/docs/zh/guide/features/esm.mdx
fi3ework 2fa180c
fix
fi3ework 8af0d5b
Update website/docs/zh/guide/features/esm.mdx
fi3ework 34d7c27
Update website/docs/en/guide/features/esm.mdx
fi3ework 2e950da
Update website/docs/zh/guide/features/esm.mdx
fi3ework cdb2ef3
Update website/docs/en/guide/features/esm.mdx
fi3ework f18f94b
Update website/docs/en/guide/features/esm.mdx
fi3ework 18c447d
refactor
fi3ework 87bba51
up
fi3ework File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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', | ||
} | ||
fi3ework marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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. | ||
fi3ework marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 格式产物 | ||
fi3ework marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
在构建应用时,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) 的示例。 | ||
fi3ework marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## 构建库的 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', | ||
} | ||
fi3ework marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 库的例子。 | ||
fi3ework marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
进行 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` 模块。 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.