Rollup打包从0到1

1,025 阅读3分钟

一、开始

Rollup 是一个JavaScript模块打包器,其使用ES6规则进行打包,天然具有tree-shaking特性,且体积轻巧,打包后文件可读性高。VueVue RouterVuex等库均使用Rollup打包。

下面从一个简单的例子开始,代码地址在这里

新建一个项目,在src/index.js中随便写点内容:

console.log('How are you?')

安装rollup,然后执行:

rollup src/index.js -f umd -o dist/bundle.js

dist/bundle.js中即可查看到打包后的文件。

二、命令行参数

下面是rollup常用的命令行的参数:

  • -f--format的缩写,它表示生成代码的格式,取值有amdcjssystemesmiifeumd。关于打包方式的差异可以参考这里
  • -o-o指定了输出的路径,比如上面的dist/bundle.js
  • -c。指定rollup的配置文件。默认为rollup.config.js
  • -w。监听源文件是否有改动,如果有改动,重新打包。
  • -n--name的缩写,是打包后的模块名称,同一页面的其他脚本可以访问它。也可以在配置文件的output.name中定义

三、配置文件

新建文件rollup.config.js

export default {
  input: ["./src/index.js"],
  output: {
    file: "./dist/bundle.js",
    format: "umd",
    name: "myBundle",
  },
  external: ["vue"],
};
  • input表示入口文件的路径(老版本为entry,已经废弃)
  • output表示输出文件的内容,它允许传入一个对象或一个数组,当为数组时,依次输出多个文件,它包含以下内容:
    • output.file:输出文件的路径(老版本为dest,已经废弃)
    • output.format:输出文件的格式
    • output.banner:文件头部添加的内容
    • output.footer:文件末尾添加的内容
  • external打包时要排除掉的模块

四、插件

Rollup只提供了最核心的打包功能,很多其他功能需要插件实现。

1. @rollup/plugin-node-resolve

Rollup不识别node_modules的模块引入,比如import answer from "the-answer",所以需要resove插件解决。

2. @rollup/plugin-commonjs

rollup打包时只支持ES6的模块导入导出方式,即export/import,对于CommonJS方式导出的包,需要使用@rollup/plugin-commonjs解决。

3. @rollup/plugin-babel

目前很多浏览器不完全支持ES6,所以需要将项目中的ES6语法转为ES5,这就用到了babel插件。

注意要同时配置.babelrc文件,并且安装@babel/core@babel/preset-env插件。

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
      }
    ]
  ]
}

4. @rollup/plugin-json

使用json插件可以在代码中直接引用json文件,比如

import json from '../package.json'

console.log(json.name)

5. rollup-plugin-terser

该插件可以压缩打包文件。

6. rollup-plugin-replace

该插件用来替换变量:

import replace from '@rollup/plugin-replace'
// ...

plugins: [
  replace({
    preventAssignment: true,
    values: {
      __VERSION__: JSON.stringify(pkg.version),
    },
  }),
]

// ...

为了防止替换过程中,将something=false替换成false=false,引发错误的问题,可以将preventAssignment设置为true

五、Demo地址

这里有个简单的例子,你可以clone下来,然后执行npm installnpm run build查看打包结果。

项目中还包含了一些自定义插件

六、Rollup原理

Rollup分为build(构建)阶段和output generate(输出生成)阶段。主要过程如下:

  • 获取入口文件的内容,包装成module,生成抽象语法树
  • 对入口文件抽象语法树进行依赖解析
  • 生成最终代码
  • 写入目标文件

七、Rollup与Webpack

Rollup优势:

  • 基于ES6,支持tree shaking
  • 冗余代码少,执行快
  • 打包结果依然完全可读

Rollup缺陷:

  • 不支持热更新
  • 对于commonjs模块,需要用插件读成ES6代码后再处理
  • umdiife格式无法对公共代码进行拆分,因为自执行函数会把所有的模块都放到一个函数中,并没有像webpack一样有一些引导代码,所以没有办法做到代码拆分

八、相关资料

  1. Rollup文档
  2. 文章中的例子
  3. 一文带你快速上手Rollup
  4. Rollup使用
  5. 从0到1解读rollup Plugin
  6. rollup实践系列之从0到1手写rollup
  7. 从rollup初版源码学习打包原理
  8. estree
  9. 原来rollup这么简单之rollup.rollup篇
  10. 使用 Acorn 来解析 JavaScript