Appearance
rollup.js
介绍
Rollup 是JavaScript
模块打包工具,与 webpack 常用于打包页面应用不同,Rollup 更专注于类库的打包,支持打包为IIFE
、ESM
、CJS
、AMD
、UMD
等模块;Rollup 使用的是 ES6 版本 Javascript 中的模块标准,更好的tree shaking
支持;
安装
npm i -g rollup
配置文件
Rollup 支持配置文件来扩展更强的能力,命令行运行rollup --config 配置文件
(--config 可简写为-c,配置文件路径可省略,默认查找顺序为:rollup.config.mjs => rollup.config.cjs => rollup.config.js)来执行配置文件;
默认配置文件rollup.config.js
为ESM
默认模块,最基础的配置文件:
export default {
// 入口文件
input: ["./src/index.js"],
output: {
// 输出指定格式模块
format: "umd",
},
};
运行命令支持传递自定义参数用作配置文件内执行相关的操作;
配置项完整列表:
// rollup.config.js
export default {
// 可以是一个数组(用于多个输入的情况)
// 核心的输入选项
external,
input, // 必要项
plugins,
// 高级输入选项
cache,
onwarn,
preserveEntrySignatures,
strictDeprecations,
// 危险区
acorn,
acornInjectPlugins,
context,
moduleContext,
preserveSymlinks,
shimMissingExports,
treeshake,
// 实验性
experimentalCacheExpiry,
perf,
output: {
// 必要项 (可以是一个数组,用于多输出的情况)
// 核心的输出选项
dir,
file,
format, // 必要项
globals,
name,
plugins,
// 高级输出选项
assetFileNames,
banner,
chunkFileNames,
compact,
entryFileNames,
extend,
footer,
hoistTransitiveImports,
inlineDynamicImports,
interop,
intro,
manualChunks,
minifyInternalExports,
outro,
paths,
preserveModules,
sourcemap,
sourcemapExcludeSources,
sourcemapFile,
sourcemapPathTransform,
// 危险区
amd,
esModule,
exports,
externalLiveBindings,
freeze,
indent,
namespaceToStringTag,
noConflict,
preferConst,
strict,
systemNullSetters,
},
watch:
{
buildDelay,
chokidar,
clearScreen,
skipWrite,
exclude,
include,
} | false,
};
命令行参数集
注意:命令行参数会覆盖配置文件相应的配置;
-c, --config <filename> 使用配置文件(如果使用参数但是值没有
指定, 默认就是 rollup.config.js)
-d, --dir <dirname> 构建块的目录(如果不存在,就打印到标准输出)
-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 生成 sourcemap (`-m inline` 生成行内 map)
-n, --name <name> UMD 导出的名字
-o, --file <output> 单个的输出文件(如果不存在,就打印到标准输出)
-p, --plugin <plugin> 使用指定的插件(可能重复)
-v, --version 显示版本号
-w, --watch 监听 bundle 中的文件并在文件改变时重新构建
--amd.id <id> AMD 模块 ID(默认是匿名的)
--amd.define <name> 代替 `define` 使用的功能
--assetFileNames <pattern> 构建的资源命名模式
--banner <text> 插入 bundle 顶部(包装器之外)的代码
--chunkFileNames <pattern> 次要构建块的命名模式
--compact 压缩包装器代码
--context <variable> 指定顶层的 `this` 值
--entryFileNames <pattern> 入口构建块的命名模式
--environment <values> 设置传递到配置文件 (看示例)
--no-esModule 不增加 __esModule 属性
--exports <mode> 指定导出的模式 (auto, default, named, none)
--extend 通过 --name 定义,拓展全局变量
--no-externalLiveBindings 不生成实施绑定的代码
--footer <text> 插入到 bundle 末尾的代码(包装器外部)
--no-freeze 不冻结命名空间对象
--no-hoistTransitiveImports 不提升传递性的导入到入口构建块
--no-indent 结果中不进行缩进
--no-interop 不包含互操作块
--inlineDynamicImports 使用动态导入时创建单个 bundle
--intro <text> 在 bundle 顶部插入代码(包装器内部)
--minifyInternalExports 强制或者禁用内部导出的压缩
--namespaceToStringTag 为命名空间创建正确的 `.toString` 方法
--noConflict 为 UMD 全局变量生成 noConflict 方法
--outro <text> 在 bundle 的末尾插入代码(包装器内部)
--preferConst 使用 `const` 代替 `var` 进行导出
--no-preserveEntrySignatures 避免表面的构建块作为入口
--preserveModules 保留模块结构
--preserveSymlinks 解析文件时不要遵循符号链接
--shimMissingExports 给丢失的导出创建填充变量
--silent 不打印警告
--sourcemapExcludeSources source map 中不包含源码
--sourcemapFile <file> source map 中指定 bundle 的路径
--no-stdin 不从标准输入中读取 "-"
--no-strict 在生成的模块中不使用 `"use strict";`
--strictDeprecations 不推荐使用的特性抛出错误
--systemNullSetters 用 `null` 替换空的 SystemJS setter
--no-treeshake 禁用 tree-shaking 优化
--no-treeshake.annotations 忽略纯的调用注释
--no-treeshake.moduleSideEffects 假设模块没有副作用
--no-treeshake.propertyReadSideEffects 忽略属性访问的副作用
--no-treeshake.tryCatchDeoptimization 不关闭 try-catch-tree-shaking
--no-treeshake.unknownGlobalSideEffects 假设未知的全局变量不抛出
--waitForBundleInput 等待 bundle 的输入文件
--watch.buildDelay <number> 监听重新构建的延时
--no-watch.clearScreen 重新构建时不进行清屏
--watch.skipWrite 监听时不写入文件到磁盘
--watch.exclude <files> 监听时排除的文件
--watch.include <files> 限制监听指定的文件
插件
JSON
# 解决json文件
npm install --save-dev @rollup/plugin-json
应用:
// rollup.config.js
import json from "@rollup/plugin-json";
export default {
input: "src/main.js",
output: {
file: "bundle.js",
format: "cjs",
},
plugins: [json()],
};
resolve
# 解决引入的npm包未被打包的问题
npm install --save-dev @rollup/plugin-node-resolve
应用:同上
示例:
import deepmerge from "deepmerge";
// 默认情况下,rollup不会打包node_modules中的包,需要使用resolve插件,
// 否则会报错(报错使用路径简写,如./utils/index.js简写为./utils,是会报错的)
// 所以大部分情况下都需要使用resolve插件
babel
# 引入babel解决es6语法兼容
npm install --save-dev @rollup/plugin-babel @babel/preset-env @babel/core
应用:
// rollup.config.js
import babel from "@rollup/plugin-babel";
export default {
input: "src/main.js",
output: {
file: "bundle.js",
format: "cjs",
},
plugins: [babel({ exclude: "node_modules/**" })],
};
.babelrc:
{
"presets": [
[
"@babel/preset-env",
{
"modules": false
}
]
]
}
注意先将 modules
设置为 false
,否则 Babel 将在 Rollup 有机会执行其操作之前将模块转换为 CommonJS ,从而导致其失败;
commonjs
# 将commonjs模块的包转成es2015,而被rollup识别并处理,
# 需要注意的是,搭配babel使用时,需要将babel的modules设置为false
# 并且需要将commonjs放在babel之前
npm install --save-dev @rollup/plugin-commonjs
应用:同上
terser
# 代码压缩
npm install --save-dev rollup-plugin-terser
应用:同上
ts
# 识别ts
npm install --save-dev @rollup/plugin-typescript
应用:同上
注意项:需要安装 tslib、typescript
删除旧目录
# 删除旧的打包目录,避免打包后的文件夹中存在旧的文件
npm install --save-dev rollup-plugin-delete
应用:
// rollup.config.js
import deletePlugin from "rollup-plugin-delete";
export default {
input: "src/main.js",
output: {
file: "bundle.js",
format: "cjs",
},
plugins: [
deletePlugin({
targets: "dist/*",
}),
],
};
css
# 识别css
npm install rollup-plugin-postcss --save-dev
应用:同上
开发服务器
# 可以启动一个开发服务器,注意rollup运行指令需指明--watch参数来实现监听
npm install rollup-plugin-serve --save-dev
应用:
// rollup.config.js
import json from "@rollup/plugin-json";
import serve from "rollup-plugin-serve";
export default {
input: "src/main.js",
output: {
file: "bundle.js",
format: "cjs",
},
plugins: [json(), serve({ open: true, port: 8080 })],
};
注意:需要在根目录下新建 index.html 并引入入口 js 文件,rollup-plugin-dev
也可以实现开发服务器(提供更多的功能)
热更新
# 启动开发服务器后,实现hmr功能
npm install rollup-plugin-livereload --save-dev
应用:同上
代码分割
UMD
和IIFE
模块不支持代码分割,动态引入其它模块(import 回调),需指定打包输出目录,实现代码分割,如
// src/foo.js
export default { a: 1 }
// src/main.js
export default function () {
import('./foo.js').then(({ default: foo }) => console.log(foo));
}
配置文件:
// rollup.config.js
import json from "@rollup/plugin-json";
export default {
input: "src/main.js",
output: {
dir: "dist",
format: "cjs",
},
plugins: [json()],
};
多入口文件打包也可实现代码分割;
外部引入
假设你正在构建一个类似 React 和 Lodash 这样具有前置依赖的库,如果你按照上述的方式设置外部引入(external),rollup 将会打包 所有 的引入项:
import answer from 'the-answer';
import _ from 'lodash';
你可以微调哪些引入需要被打包,哪些引入需要设置为外部引入。在这个例子中,我们可以将 lodash
视为外部引入,而不是 the-answer
;
下面是配置文件:
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
export default {
input: 'src/main.js',
output: {
file: 'bundle.js',
format: 'cjs'
},
plugins: [resolve({
// 将自定义选项传递给解析插件
customResolveOptions: {
moduleDirectory: 'node_modules'
}
})],
// 指出哪些模块需要被视为外部引入
external: ['lodash']
};
lodash
现在会被视为外部引入,而不会和你的库打包在一起;