Rollup是什么?
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。这在未来将在所有场景原生支持,但 Rollup 让你今天就可以开始这样做。
起步
前置要求:
Rollup 3:
- Node版本要求:请确保你的 Node 版本至少为
14.18.0
,并更新所有 Rollup 插件到最新版本。
全局安装
全局安装将使 Rollup 可以作为全局命令工具使用。使用命令行工具运行
npm install --global rollup
简写:npm i -g rollup
快速体验
由于Rollup 可以静态分析你导入的代码,并将排除任何实际上没有使用的内容(Tree-Shaking),
在快速体验的时候,我们都会去调用或者输出下,目的是让rollup去编译,以便我们去感受。
对于浏览器:
(作为<script src="xxx.js">
引入使用)
bash
# 编译为包含自执行函数('iife')的 <script>。
rollup main.js --file bundle.js --format iife
将目标文件 main.js 编译为 自执行函数(iife)格式 生成 bundle.js
将编译的文件 bundle.js 引入 index.html 中使用:
对于Node.js
bash
# 编译为一个 CommonJS 模块 ('cjs')
rollup main.js --file bundle.js --format cjs
对于浏览器 和 Node.js
UMD格式(兼容格式)
bash
# UMD 格式需要一个包名
rollup main.js --file bundle.js --format umd --name "myBundle"
如果在使用 rollup 遇到 Error: Cannot find module 'node:process'
, 可能是node版本太低导致(Node版本至少为14.18.0
),报错如下:
本地安装
在团队或分布式环境中工作时,将 Rollup 添加为 本地 依赖可能是明智的选择。本地安装 Rollup 可以避免多个贡献者单独安装Rollup的额外步骤,并确保所有贡献者使用相同版本的Rollup。
用 npm 安装: npm install rollup --save-dev
Yarn 安装: yarn -D add rollup
安装完成后,通常为了避免频繁的输入打包命令,会把命令配置到 package.json
中,作为构建脚本。
json
{
"type": "module", // 如果配置文件是 .js 后缀名,这个要配置,后面章节会说明
"scripts": {
"build": "rollup --config" // 配置脚本,可以简写成 rollup -c 后面 命令行标志章节有说明
},
"devDependencies": {
"rollup": "^4.2.0"
}
}
运行 npm run build
或 yarn build
就可以执行脚本,脚本就可以执行 rollup的命令行 打包。 这样一旦本地依赖安装完成后,当运行脚本命令时,不管是 NPM 还是 Yarn 都可以找到 Rollup 的可执行文件并执行。
使用教程
使用命令行方式打包
- 全局安装了rollup:
bash
# 全局安装
npm install rollup --global
运行 rollup
后, 会打印出使用说明。这与运行 rollup --help
或者 rollup -h
相同。 让我们创建一个简单的项目:
bash
mkdir -p my-rollup-project/src
cd my-rollup-project
首先,我们创建一个名为 foo.js
的模块,它在入口文件中被导入:
javascript
// src/foo.js
export default "hello world"
创建入口文件 src/main.js
, 文件内容:
javascript
// src/main.js
import foo from './foo'
export default function() {
console.log(foo)
}
打开项目所在的终端
输入命令行命令: rollup src/main.js -f cjs
;
-f
选项 (是 --format
的缩写) 指定了产物的类型 --- 在本例中是 CommonJS (可以在 Node.js 中运行)。因为我们没有指定输出文件,所以它将直接打印到 stdout
: 你也可以像这样将产物保存为文件:rollup src/main.js -o bundle.js -f cjs
;
使用配置文件方式打包
到目前为止,使用命令行方式来打包都挺好的,只是输入命令有点麻烦。为了避免重复输入,我们可以创建一个包含所有必选项的配置文件。配置文件是使用
javascript
编写的,比原始的 cli 更加灵活。
在项目根目录中创建
一个名为 rollup.config.mjs
的文件,.mjs
后缀名的配置文件,我们要使用 ES模块规范
来编写代码;
添加以下代码:
javascript
// rollup.config.mjs
// ES 模块方式编写的,最后打包成CommonJS模块规范的输出产物。
export default {
input: "src/main.js",
output: {
file: "bundle.js",
format: 'cjs'
}
}
也可以在项目根目录中创建
一个名为 rollup.config.cjs
的文件,.cjs
后缀名的配置文件,我们使用 CommonJS模块规范
来编写代码;例如 module.exports = {/* config */}
)
添加以下代码:
javascript
// rollup.config.cjs
// CommonJS 模块规范
module.exports = {
input: "src/main.js",
output: {
file: "bundle.js",
format: "cjs"
}
}
使用配置文件,我们使用 rollup --config
或 rollup -c
; 命令行标志说明见下方章节 命令行标志以及使用;
你可以使用等效的命令行选项 覆盖配置文件中的任何选项,也就是说虽然配置文件中定义了命令行选项,但是我们可以通过打包时输入的命令行命令,来覆盖配置文件中等价的选项。
例如:我们在配置文件中定义了输出的产物文件名叫 bundle.js
, 但是我们通过终端使用等效的命令行选项,让它输出产物的文件叫 bundle-2.js
;
bash
rollup -c -o bundle-2.js # `-o` 等价于 `--file`(曾用名为 "output")
注意: Rollup本身会处理配置文件,这就是为什么我们可以使用 export default
语法的原因 - 代码没有被 Babel 或任何类似的工具转换,因此你只能使用在你当前使用的 Node 版本中支持的 ES2015 功能。
你可以选择指定不同默认的 rollup.config.mjs
的配置文件
bash
rollup --config rollup.config.dev.mjs
rollup --config rollup.config.prod.mjs
然后可以在脚本中package.json
配置不同的脚本, 可以配合下面的 命令行参数 --environment <values>
, 根据不同的环境,注入不同的值; [命令行参数用法 -- 请查看!](#命令行参数用法 -- 请查看! "#environment")
配置文件说明
rollup 配置文件
是可选的
,但它们非常强大和方便,因此推荐使用
;配置文件
是
一个ES模块
, 它导出一个默认对象
;(也可以使用require
和module.exports
编写CommonJS 模块的配置文件
,但是应该将文件扩展名更改为 .cjs
。)配置文件
通常为:rollup.config.js
或rollup.config.mjs
;并位于项目的根目录中
;
配置文件,其中包含所需的选项:
javascript
// rollup.config.js
export default {
input: "./src/main.js", // 入口
output: { // 必需的 出口
file: './dist/bundle.js', // 打包后生成的文件路径及文件名
format: 'cjs' // 模块格式
},
}
如果配置文件为:rollup.config.js
采用 ES模块方式编写
, 打包编译
命令使用 rollup --config
或 rollup -c
,则会 报错
;
原因: Node会尝试将配置文件使用CommonJS模块方式进行加载
,即使它可能是一个ES模块
(export default{} 方式),除非在命令行中使用
--bundleConfigAsCjs
或 --configPlugin
选项,否则 Rollup 将直接使用 Node 导入该文件。
解决方式:
方式一: 将配置文件由 rollup.config.js
改为 rollup.config.mjs
;
方式二: package.json
方式的,在 package.json
中,添加 type: "module"
;
方式三: 根据实际情况,增加命令行参数 --bundleConfigAsCjs 或 --configPlugin
;
--bundleConfigAsCjs
: 此选项将强制将你的配置转译为 CommonJS 。
rollup的配置文件也可以采用CommonJS模块方式编写
,但是应该把文件扩展名更改为
: .cjs
;
要注意,如果使用 ES模块方式编写配置文件
请注意,使用原生 Node ES模块 时存在一些注意事项,因为 Rollup 将遵循 Node ESM 语义。
原生 Node ES 模块时的注意事项:
-
获取当前目录:
__dirname
在原生ES模块中不支持。建议使用 fileURLToPath
javascript// rollup.config.js import {fileURLToPath} from "node:url" export default { ..., external: [ // 当前所在目录下得绝对路径 fileURLToPath(new URL('src/some-file.js', import.meta.url)) ] }
-
导入 package.json。
- 对于 Node 17.5+ 可以使用导入断言
- 对于node旧版本,可以使用
createRequire
rollup 配置选项说明
配置文件的配置选项主要分为: 核心功能
,进阶功能
, 慎用选项
,实验选项
,观察选项
,废弃选项
; 具体的配置文件的配置选项说明可以查看中文官网: 配置选项
rollup 配置文件基本结构: rollup配置文件,支持 单文件(单个)配置
或 多文件(多个)配置
;
javascript
// rollup.config.js
// 可以是数组(即多个输入源)
export default {
// 核心输入选项
external,
input, // 有条件地需要
plugins,
// 进阶输入选项
cache,
logLevel,
makeAbsoluteExternalsRelative,
maxParallelFileOps,
onLog,
onwarn,
preserveEntrySignatures,
strictDeprecations,
// 危险区域
acorn,
acornInjectPlugins,
context,
moduleContext,
preserveSymlinks,
shimMissingExports,
treeshake,
// 实验性
experimentalCacheExpiry,
experimentalLogSideEffects,
experimentalMinChunkSize,
perf,
// 必需(可以是数组,用于描述多个输出)
output: {
// 核心输出选项
dir,
file,
format,
globals,
name,
plugins,
// 进阶输出选项
assetFileNames,
banner,
chunkFileNames,
compact,
dynamicImportInCjs,
entryFileNames,
extend,
externalImportAssertions,
footer,
generatedCode,
hoistTransitiveImports,
inlineDynamicImports,
interop,
intro,
manualChunks,
minifyInternalExports,
outro,
paths,
preserveModules,
preserveModulesRoot,
sourcemap,
sourcemapBaseUrl,
sourcemapExcludeSources,
sourcemapFile,
sourcemapFileNames,
sourcemapIgnoreList,
sourcemapPathTransform,
validate,
// 危险区域
amd,
esModule,
exports,
externalLiveBindings,
freeze,
indent,
noConflict,
sanitizeFileName,
strict,
systemNullSetters,
// 实验性
experimentalMinChunkSize
},
watch: {
buildDelay,
chokidar,
clearScreen,
exclude,
include,
skipWrite
}
};
- 创建 Rollup配置文件:项目
根目录创建
rollup.config.js
文件, 根据需要并定义如上相关配置; - 完成相关操作后,Rollup 可以在项目的根目录中运行;
安装完成后,Rollup 可以在项目的根目录中运行: npx rollup --config
或使用 Yarn: yarn rollup --config
,这是用配置文件方式执行(需要定义配置文件);
命令行标志以及使用
命令行标志
终端命令行使用标志的含义,上述我们经常使用:rollup --config --bundleConfigAsCjs
, rollup -c --bundleConfigAsCjs
,
许多选项都有等效的命令行标志。这些情况下,如果你正在使用配置文件(rollup.config.js
),则此处传递的任何参数都将覆盖配置文件。即 命令行传递的参数优先级更高,能覆盖配置文件中的定义。
lua
-c, --config <filename> 使用此配置文件
(如果使用参数但未指定值,则默认为 rollup.config.js)
-d, --dir <dirname> 用于块的目录(如果不存在,则打印到 stdout)
-e, --external <ids> 排除模块 ID 的逗号分隔列表
-f, --format <format> 输出类型(amd、cjs、es、iife、umd、system)
-g, --globals <pairs> `moduleID:Global` 对的逗号分隔列表
-h, --help 显示此帮助消息
-i, --input <filename> 输入(替代 <entry file>)
-m, --sourcemap 生成源映射(`-m inline` 为内联映射)
-n, --name <name> UMD 导出的名称
-o, --file <output> 单个输出文件(如果不存在,则打印到 stdout)
-p, --plugin <plugin> 使用指定的插件(可重复)
-v, --version 显示版本号
-w, --watch 监视产物文件并在更改时重新构建
--amd.autoId 基于块名称生成 AMD ID
--amd.basePath <prefix> 要预先添加到自动生成的 AMD ID 的路径
--amd.define <name> 在 `define` 位置使用的函数
--amd.forceJsExtensionForImports 在 AMD 导入中使用 `.js` 扩展名
--amd.id <id> AMD 模块的 ID(默认为匿名)
--assetFileNames <pattern> 发布资源的名称模式
--banner <text> 在产物顶部插入的代码(位于包装器之外)
--chunkFileNames <pattern> 发布次要块的名称模式
--compact 缩小包装器代码
--context <variable> 指定顶级 `this` 值
--no-dynamicImportInCjs 将外部动态 CommonJS 导入编写为 require
--entryFileNames <pattern> 发布入口块的名称模式
--environment <values> 传递给配置文件的设置(请参阅示例)
--no-esModule 不添加 __esModule 属性
--exports <mode> 指定导出模式(auto、default、named、none)
--extend 扩展由 --name 定义的全局变量
--no-externalImportAssertions 在 "es" 输出中省略导入断言
--no-externalLiveBindings 不生成支持实时绑定的代码
--failAfterWarnings 如果生成的构建产生警告,则退出并显示错误
--filterLogs <filter> 过滤日志信息
--footer <text> 在产物底部插入的代码(位于包装器之外)
--no-freeze 不冻结命名空间对象
--generatedCode <preset> 使用哪些代码特性(es5/es2015)
--generatedCode.arrowFunctions 在生成的代码中使用箭头函数
--generatedCode.constBindings 在生成的代码中使用 "const"
--generatedCode.objectShorthand 在生成的代码中使用简写属性
--no-generatedCode.reservedNamesAsProps 始终引用保留名称作为 props
--generatedCode.symbols 在生成的代码中使用符号
--no-hoistTransitiveImports 不将中转导入提升到入口块中
--no-indent 不缩进结果
--inlineDynamicImports 使用动态导入时创建单次打包
--no-interop 不包括交互操作块
--intro <text> 在产物顶部插入的代码(位于包装器内部)
--logLevel <level> 要显示哪种类型的日志
--no-makeAbsoluteExternalsRelative 不规范化外部导入
--maxParallelFileOps <value> 并行读取的文件数
--minifyInternalExports 强制或禁用内部导出的缩小
--noConflict 为 UMD 全局生成 noConflict 方法
--outro <text> 在产物底部插入的代码(位于包装器内部)
--perf 显示性能计时
--no-preserveEntrySignatures 避免入口点的门面块
--preserveModules 保留模块结构
--preserveModulesRoot 将保留的模块放置在根路径下的此路径下
--preserveSymlinks 解析文件时不要跟随符号链接
--no-sanitizeFileName 不要替换文件名中的无效字符
--shimMissingExports 为丢失的导出创建卡扣变量
--silent 不打印警告
--sourcemapBaseUrl <url> 使用给定的基本 URL 发出绝对源映射 URL
--sourcemapExcludeSources 在源映射中不包括源代码
--sourcemapFile <file> 指定源映射的包位置
--sourcemapFileNames <pattern> 编译后 sourcemap 的命名模式
--stdin=ext 指定用于标准输入的文件扩展名
--no-stdin 不要从 stdin 读取 "-"
--no-strict 不在生成的模块中发出 `"use strict";`
--strictDeprecations 抛出有关不推荐使用的功能的错误
--no-systemNullSetters 不要将空的 SystemJS setter 替换为 `null`
--no-treeshake 禁用除屑优化
--no-treeshake.annotations 忽略纯调用注释
--treeshake.correctVarValueBeforeDeclaration 在声明之前将变量取消优化
--treeshake.manualPureFunctions <names> 手动将函数声明为纯函数
--no-treeshake.moduleSideEffects 假设模块没有副作用
--no-treeshake.propertyReadSideEffects 忽略属性访问副作用
--no-treeshake.tryCatchDeoptimization 不要关闭 try-catch-tree-shaking
--no-treeshake.unknownGlobalSideEffects 假设未知的全局变量不会抛出异常
--validate 验证输出
--waitForBundleInput 等待打包输入文件
--watch.buildDelay <number> 节流观察重建
--no-watch.clearScreen 重建时不要清除屏幕
--watch.exclude <files> 排除要观察的文件
--watch.include <files> 限制观察到指定文件
--watch.onBundleEnd <cmd> 在 "BUNDLE_END" 事件上运行的 Shell 命令
--watch.onBundleStart <cmd> 在 "BUNDLE_START" 事件上运行的 Shell 命令
--watch.onEnd <cmd> 在 "END" 事件上运行的 Shell 命令
--watch.onError <cmd> 在 "ERROR" 事件上运行的 Shell 命令
--watch.onStart <cmd> 在 "START" 事件上运行的 Shell 命令
--watch.skipWrite 在监视时不要将文件写入磁盘
命令行参数使用说明
以下命令行标志仅通过命令行界面可用。所有其他标志都对应并覆盖其配置文件等效项。
--bundleConfigAsCjs
: 此选项将强制将你的配置转译为CommonJS。 这允许你在配置中使用CommonJS常用的变量/方法,例如__dirname
或require.resolve
,即使配置本身是作为ES模块编写的。
--environment <values>
:通过 process.ENV
传递其他设置到配置文件。
通过命令行参数传递参数,在项目文件中可以获取到传递过来的变量。
bash
rollup -c --environment INCLUDE_DEPS,BUILD:production
其他命令行标识,请查看文档!!
click here
Rollup兼容性
- Rollup 可以通过插件
导入现有的CommonJS模块
。 - 发布 ES 模块。 为了确保你的 ES 模块可以立即被处理 CommonJS 的工具,例如 Node.js 和 webpack 使用,你可以使用 Rollup 编译成 UMD 或 CommonJS 格式,然后在
package.json
文件中使用main
属性指向编译后的版本。如果你的package.json
文件还有一个module
字段,那么像 Rollup 和 webpack 2+ 这样的可感知 ES 模块的工具将直接 导入 ES 模块版本。
遇到的问题
(1). Node版本太低:确保你的 Node 版本至少为 18.0.0,并更新所有 Rollup 插件到最新版本 (2). 以配置文件方式执行:npx rollup --config
或使用 Yarn: yarn rollup --config
,这是用配置文件方式执行,需要定义配置文件(注意需要rollup配置,配置文件并定义配置文件,否则运行命令会报错。 )。如果是命令行执行,则需要输入相关命令行参数, 配置文件方式执行,未定义配置文件,报错情况如下: