rolllup

Rollup 概述

  • Rollup 更小巧,仅仅是一款 ESModule 打包器
  • Rollup 中并不支持类似 HMR 这种高级特性
  • 提供一个充分利用 ESM 各项特性的高效打包器

Rollup 快速上手

  • 安装 yarn add rollup --dev
  • 打包 yarn rollup ./src/index.js --format iife --file dist/bundle.js
  • 入口文件 index.js,指定输出格式:–format,格式:iife(自执行函数),–file:输出到目录
  • 没使用的不会打包,自动开启 Tree Shaking

Rollup 配置文件

  • rollup 运行在 node 环境中
  • 根目录新建 rollup.config.mjs 配置文件
  • rollup 会额外处理这个配置文件,所有可以使用 ESM,注意使用 esm 需要将后缀改为.mjs
  • 配置文件导出一个对象
  • 通过 input 属性指定打包入口
  • 通过 output 属性指定输出,该属性值是一个对象,通过 file 指定输出的文件名,format 属性指定输出格式
  • 打包 pnpm rollup --config rollup.config.mjs 通过–config 告诉 rollup 使用配置文件,可以根据开发、生产指定对应的配置文件
1
2
3
4
5
6
7
export default {
input: "src/index.js",
output: {
file: "dist/bundle.js",
format: "iife",
},
};

Rollup 使用插件

  • 插件是 rollup 唯一的扩展途径
  • 安装插件 pnpm add @rollup/plugin-json -D 一个可以在代码导入 json 文件的插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import json from "@rollup/plugin-json";

export default {
input: "src/index.js",
output: {
file: "dist/bundle.js",
format: "iife",
},
plugins: [json()],
};
// index.js
// package.json 的属性会作为成员导出
import { name, version } from "../package";
console.log(name, version);

Rollup 加载 NPM 模块

  • 安装插件 pnpm add @rollup/plugin-node-resolve -D
  • 安装 lodash 的 es 版本 pnpm add lodash-es

该插件可以让 rollup 通过模块名成导入插件.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import json from "@rollup/plugin-json";
import { nodeResolve } from "@rollup/plugin-node-resolve";

export default {
input: "src/index.js",
output: {
file: "dist/bundle.js",
format: "iife",
},
plugins: [json(), nodeResolve()],
};
// index.js
import _ from "lodash-es";
console.log(_.camelCase("hello world"));

Rollup 加载 CommonJS 模块

  • 安装插件 yarn add @rollup/plugin-commonjs --dev
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import json from "@rollup/plugin-json";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";

export default {
input: "src/index.js",
output: {
file: "dist/bundle.js",
format: "iife",
},
plugins: [json(), nodeResolve(), commonjs()],
};

// cjs-module.js
module.exports = { foo: "bar" };
// index.js
import cjs from "./cjs-module.js";
console.log(cjs);

Rollup 代码拆分

  • 可以 ESM 的动态导入方式(import())实现模块的按需加载
  • rollup 内部会自动处理代码拆分
  • 代码拆分的方式打包 formats 不可以使用 iife(自执行函数)
  • 自执行函数会把所有模块放到同一个函数中,可以使用 AMD 或者 Commonjs 标准,浏览器使用 AMD
  • 需要输出多个文件 output 中就不能使用 file 属性,而是使用 dis 属性 值是输出目录
1
2
3
4
5
6
7
8
9
10
11
export default {
input: "src/index.js",
output: {
dir: "dist",
format: "amd",
},
};
// index.js
import("./logger").then(({ log }) => {
log("code splitting~");
});

Rollup 多入口打包

  • 会把不同入口公共代码自动提取到单个文件中作为独立的 bundle
  • 把配置文件的 input 属性值修改为一个数组,或者使用对象的方式
  • rollup 内部会自动拆分 format 要使用 AMD
  • AMD 文件不能直接引入,要使用特定的库去加载
1
2
3
4
5
6
7
8
9
10
11
export default {
// input: ['src/index.js', 'src/album.js']
input: {
foo: "src/index.js",
bar: "src/album.js",
},
output: {
dir: "dist",
format: "amd",
},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<!-- AMD 标准格式的输出 bundle 不能直接引用 -->
<!-- <script src="foo.js"></script> -->
<!-- 需要 Require.js 这样的库 -->
<!--data-main:指定require入口路径-->
<script
src="https://unpkg.com/requirejs@2.3.6/require.js"
data-main="foo.js"
></script>
</body>
</html>

Rollup 选用原则

  • 优势
    • 输出结果更加扁平
    • 自动移除未引用的代码
    • 打包结果依然完全可读
  • 缺点
    • 加载非 ESM 的第三方模块比较复杂
    • 模块最终都被打包到一个函数中,无法实现 HMR
    • 浏览器环境中,代码拆分功能依赖 AMD 库
  • 应用开发建议使用 webpack
  • 库、框架开发建议使用 Rollup

Parcel 打包器

  • 零配置的前端应用打包器
  • 安装 yarn add parcel-bundler --dev
  • 官方建议使用 html 文件作为打包入口
  • 打包 yarn parcel src/index.html parcel 会根据导入的模块查找 从而完成整个项目的打包,会自动开启一个服务
  • 模块热更新
1
2
3
4
5
if (module.hot) {
module.hot.accept(() => {
console.log("hmr");
});
}
  • 会自动安装模块依赖,如文件中导入 JQ,保存文件后,会自动安装模块
  • 支持导入其他类型文件,而且是零配置的 import './style.css 保存就生效了
  • 可以动态导入模块 import()
  • 生成环境打包 yarn parcel build src/index.html
  • 内部使用多进程同时工作,构建速度快