Skip to content

Bundle 格式

rollup 可以打包以下格式的 bundle:

  • amd – 异步模块加载,适用于 RequireJS 等模块加载器
  • cjs – CommonJS,适用于 Node 环境和其他打包工具(别名:commonjs)
  • es – 将 bundle 保留为 ES 模块文件,适用于其他打包工具,以及支持 <script type=module> 标签的浏览器。(别名:esm,module)
  • iife – 自执行函数,适用于 <script> 标签(如果你想为你的应用程序创建 bundle,那么你可能会使用它)。iife 表示“自执行 函数表达式”
  • umd – 通用模块定义规范,同时支持 amd,cjs 和 iife
  • system – SystemJS 模块加载器的原生格式(别名:systemjs)

根据使用场景的不同而输出不同格式的产物。目前比较常用输出 esmcjsumd 格式

esm 格式

esm 支持命名导出、更好的静态分析、tree shaking、浏览器原生支持,最重要的是,作为一种标准,它基本上是 JavaScript 的未来。或许在将来的某一天,你的库只需要输出 esm

package.json 中的module 字段指向一个兼容 ESM 格式的产出

json
{
  "module": "es/index.mjs"
}

如果项目是使用 webpack 构建的,那么你使用的资源就是module 指向的的 ESM 文件给 rollup.js 或 webpack 等打包工具使用。

js
import { ref } from 'vue'

现在主流浏览器对原生 ESM 的支持都不错,所以用户还可以直接引入 ESM 格式的资源

html
<body>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.41/vue.esm-browser.js"></script>
  <script>
    const { createApp } = Vue;
    //  ...
  </script>
</body>

module 是一个当打包工具或运行时不支持 package.json#exports 时的兜底方案;如果打包工具或运行时支持 package exports,则不会使用 module

cjs 格式

esm 被认为是“未来”,但 cjs 仍然在社区和生态系统中占有重要地位。 用户除了可以直接使用 <script> 标签引入资源外,我们还希望用户可以在 Node.js 中通过 require 语句引用资源,例如

js
const _ = require('lodash')

main 定义 CommonJS 入口

json
{
  "main": "lib/index.cjs.js"
}

main 是一个当打包工具或运行时不支持 package.json#exports 时的兜底方案;如果打包工具或运行时支持 package exports,则不会使用 main

main 应该指向一个兼容 CommonJS 格式的产出;它应该与 package exports 中的 require 保持一致。

iife 格式

首先我们希望用户可以直接在 HTML 页面中使用 <script> 标签引入框架并使用

umd 格式

umd 是“Universal Module Definition”的缩写,它可以在 <script> 标签中执行、被 CommonJS 模块加载器加载、被 AMD 模块加载器加载。

你可能已经注意到,umd 已经与 CommonJS 模块加载器兼容 —— 所以为什么还要同时具备 cjsumd 输出呢?一个原因是,与 umd 文件相比,CommonJS 文件在对依赖进行条件导入时通常表现更好;例如:

js
if (process.env.NODE_ENV === 'production')
  module.exports = require('my-lib.production.js')
else
  module.exports = require('my-lib.development.js')

上面的例子,当使用 CommonJS 模块时,只会引入 productiondevelopment 包中的一个。但是,对于 UMD 模块,最终可能会将两个包全部引入。有关更多信息,请参阅此讨论