|
| 1 | +import { Stability } from '@components/ApiMeta'; |
| 2 | + |
| 3 | +# ESM Output |
| 4 | + |
| 5 | +Rspack supports bundling ESM format output. By default, Rspack generates CommonJS-like output, but you can configure `output.module` to generate ESM format output. |
| 6 | + |
| 7 | +Below are the main configuration options related to ESM and their descriptions, which are used when building both applications and libraries. |
| 8 | + |
| 9 | +1. [output.module](/config/output#outputmodule): Set to `true` to generate ESM format output. When this option is enabled, it affects the following configurations: |
| 10 | + 1. Affects [externalsType](/config/externals#externalstype) default value: When `output.module` is `true`, `externalsType` defaults to `'module-import'` |
| 11 | + 2. Affects [output.filename](/config/output#outputfilename) default value: When `output.module` is `true`, the default filename is `'[name].mjs'` instead of `'[name].js'` |
| 12 | + 3. Affects [output.chunkFilename](/config/output#outputchunkfilename) default value: When `output.module` is `true`, chunk filename defaults to `'[id].mjs'` instead of `'[id].js'` |
| 13 | + 4. Affects [output.hotUpdateChunkFilename](/config/output#outputhotupdatechunkfilename) default value: When `output.module` is `true`, defaults to `'[id].[fullhash].hot-update.mjs'` |
| 14 | + 5. Affects [output.hotUpdateMainFilename](/config/output#outputhotupdatemainfilename) default value: When `output.module` is `true`, defaults to `'[runtime].[fullhash].hot-update.json.mjs'` |
| 15 | + 6. Affects [output.iife](/config/output#outputiife) default value: When `output.module` is `true`, `output.iife` defaults to `false` |
| 16 | + 7. Affects [output.library.type](/config/output#outputlibrarytype) default value: When `output.module` is `true`, defaults to `'module'` instead of `'var'` |
| 17 | + 8. Affects [output.scriptType](/config/output#outputscripttype) default value: When `output.module` is `true`, defaults to `'module'` |
| 18 | + 9. Affects [output.environment.dynamicImport](/config/output#outputenvironmentdynamicimport) default value: Enabled when `output.module` is `true` |
| 19 | + 10. Affects [output.environment.dynamicImportInWorker](/config/output#outputenvironmentdynamicimportinworker) default value: Enabled when `output.module` is `true` |
| 20 | + 11. Affects [output.environment.module](/config/output#outputenvironmentmodule) default value: Enabled when `output.module` is `true` |
| 21 | + 12. Affects Node.js related configuration defaults: In Node.js environment, when `output.module` is `true`, `__filename` and `__dirname` default to `'node-module'` |
| 22 | +2. [output.chunkFormat](/config/output#outputchunkformat): Set to `'module'` to use ESM format. |
| 23 | +3. [output.library.type](/config/output#outputlibrarytype): Set to `'modern-module'` for additional optimization of library ESM output format. |
| 24 | +4. [output.chunkLoading](/config/output#outputchunkloading): Set to `'import'` to use ESM `import` for loading chunks. |
| 25 | +5. [output.workerChunkLoading](/config/output#outputworkerchunkloading): Set to `'import'` to use ESM `import` for loading workers. |
| 26 | +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. |
| 27 | +7. [optimization.avoidEntryIife](/config/optimization#optimizationavoidentryiife): In some cases, Rspack wraps ESM output in an IIFE, which breaks ESM's modular characteristics. |
| 28 | +8. [experiments.outputModule](/config/experiments#experimentsoutputmodule): Enable the experimental feature required for output.module. |
| 29 | +9. [HtmlWebpackPlugin.scriptLoading](/guide/tech/html#htmlwebpackplugin): Set to `'module'` to use ESM `<script type="module">` for loading `.mjs` modules. |
| 30 | + |
| 31 | +## Building application ESM output |
| 32 | + |
| 33 | +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: |
| 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 | +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. |
| 51 | + |
| 52 | +## Building library ESM output |
| 53 | + |
| 54 | +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. |
| 55 | + |
| 56 | +If you need to use Rspack directly to build ESM format output for libraries (npm library), you need to configure the following: |
| 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 | +You can check out this [rspack-examples](https://github.com/rspack-contrib/rstack-examples/tree/main/rspack/library-esm) ESM library example. |
| 83 | + |
| 84 | +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. |
| 85 | + |
| 86 | +## Future plans for ESM output |
| 87 | + |
| 88 | +Currently, Rspack's support for ESM is still relatively basic, and ESM output cannot fully replace the current CommonJS output. In many scenarios, ESM output cannot work properly. The main limitations include: |
| 89 | + |
| 90 | +1. Lack of static analysis friendly code splitting support |
| 91 | +2. Limited custom chunk splitting support in ESM format |
| 92 | +3. Lack of module-level side effect information preservation, affecting tree-shaking accuracy |
| 93 | +4. Re-exports of external modules (`export * from '...'`) cannot be properly preserved in ESM format |
| 94 | + |
| 95 | +Rspack will continue to improve ESM support in the future, with the goal of treating ESM output as a first-class citizen, making ESM usage and configuration simpler and more intuitive, and better embracing modern JavaScript module systems. |
0 commit comments