定义

官方对rollup的定义:

Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex,such as a library or application.

Rollup是一个JavaScript的模块化打包工具,可以帮助我们编译小的代码到一个大的、复杂的代码中,比如一个库或者一个应用程序;

从定义上看,Rollup与之前我们所学的webpack在定位上是很相似的。实际上Rollup就是对标Webpack的。

  • rollup也是一个模块化的打包工具,但是Rollup主要是针对ES Module进行打包的;(webpack支持esm、cjs、amd等模块化)
  • rollup更多时候是专注于处理JavaScript代码的(当然也可以处理css、font、vue等文件);

另外rollup的配置和理念相对于webpack来说,更加的简洁和容易理解;

webpack和rollup各自的应用场景

通常在实际项目开发过程中,我们都会使用webpack(比如vue、react、angular脚手架创建的项目都是基于webpack的);
在对js库进行打包时,我们通常会使用rollup(比如vue、react、dayjs源码本身都是基于rollup的);

看到这里,我们不得不产生了一个疑惑。它们两者既然是对标的,那为什么rollup会更适用于库的开发呢?
查阅了网上很多文章,都对于这个问题没有说清楚。网上文章的说法大多只是rollpu是更适合处理js库的,而且打包出来的文件体积会比webpack 小。

那接下来我们带着这个问题去更深入地学下rollup。看能不能分析出答案来。

基本使用

安装:

  1. npm install rollup -D

在根目录下创建rollup.config.js配置文件

//rollup.config.js
export default {
  input: "./src/main.js",
  //output能接收一个数组,rollup支持创建不同应用场景的打包文件
  output: [
    {
      format: "umd",
      name: "umdbundle",
      file: "dist/bundle.umd.js"
    },
    {
      format: "cjs",
      file: "dist/bundle.commonjs.js"
    },
    {
      format: "amd",
      file: "dist/bundle.amd.js"
    },
    {
      format: "es",
      file: "dist/bundle.es.js"
    },
    {
      format: "iife",
      name: "iifebundle",
      file: "dist/bundle.browser.js"
    }
  ]
}
//package.json
"scripts": {
  "build": "rollup -c"
},

命令行输入npm run build后就可以看到打包出来的文件了:
image-20220607105856981.png
我们可以看到根据我们对不同场景的配置,分别创建了不同场景的bundle文件。假如这是个第三方js库,那么用户在使用时,就可以根据自己当前的场景环境,拿对应的bundle文件即可。(比如在node环境下,就只能commonjs的bundle文件)
而webpack不是这样去处理模块化的。webpack会帮我们写很多支持模块化的代码,保证代码可以在各个场景环境下运行。(webpack模块化方面可以回顾之前的 06、webpack实现模块化原理)

至此,我们就知道 为什么rollup会更适用于库的开发 这个问题的答案了。

  • rollup可以针对各个应用场景都生成对应的bundle文件;
  • 用户真正拿到的库文件体积更小。

rollup处理引入的第三方库

我们最开始看rollup定义时,发现Rollup主要是针对ES Module进行打包。
也就是说我们的代码中模块化方面只支持写ES Module。如果写了其他的模块化语法,比如commonJS,就会报错。

当我们的项目引入了第三方库,会产生如下几个问题:
如果第三方库使用的是commonJs模块化,那我们需要怎么处理?
rollup默认不会去node_modules里找第三方库,我们需要怎么处理?

安装解决commonjs的库:

npm install @rollup/plugin-commonjs -D

安装解决node_modules的库:

npm install @rollup/plugin-node-resolve -D

使用:

//rollup.config.js
import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";

export default {
  input: "./src/main.js",
  output: {
    format: "umd",
    name: "unmbundle",
    file: "dist/why.umd.js",
    //如果使用了external,还需要配置globals全局对象
    globals: {
      lodash: "_",
    },
  },
  //建议使用第三方库时,采用全局引入+external(全局引入可以在html文件里引入)。这样就可以让第三方库与我们项目代码不被打包到同一bundle文件里
  external: ["lodash"],
  plugins: [
    //支持导出可以为commonjs模块化  
    commonjs(),
    //支持rollup会去node_modules下找第三方库  
    resolve()
  ],
};

通过上述配置,我们就可以正常使用导入的第三方库。

rollup自动化构建案例

  • 解决commonjs和第三方库问题
  • Babel转换代码
  • Teser代码压缩
  • 处理css文件
  • 处理vue文件
  • 搭建本地服务器
  • 区分开发环境 ```javascript //rollup.config.js import commonjs from “@rollup/plugin-commonjs”; import resolve from “@rollup/plugin-node-resolve”; import babel from “@rollup/plugin-babel”; import { terser } from “rollup-plugin-terser”; import postcss from ‘rollup-plugin-postcss’; import vue from ‘rollup-plugin-vue’; import replace from ‘rollup-plugin-replace’; import serve from ‘rollup-plugin-serve’; import livereload from ‘rollup-plugin-livereload’;

const isProduction = process.env.NODE_ENV === ‘production’; const plugins = [ commonjs(), resolve(), //使用replace注入环境变量 replace({ ‘process.env.NODE_ENV’: JSON.stringify(process.env.NODE_ENV) }), //使用babel进行一些转化 babel({ babelHelpers: “bundled”, }), //处理css文件 postcss(), //处理vue文件 vue(), ]

if (isProduction) { //production模式下,使用terser丑化压缩代码 plugins.push(terser()) } else { const devPlugins = [ //开发模式下,开启本地服务 serve({ // open: true, // 是否打开浏览器 port: 8080, // 监听哪一个端口 contentBase: “.” // 服务哪一个文件夹 }), //文件发生变化自动刷新浏览器 livereload() ] plugins.push(…devPlugins); }

export default { input: “./src/main.js”, output: { format: “umd”, name: “whyUtils”, file: “dist/why.umd.js”, globals: { lodash: “_”, }, }, external: [“lodash”], plugins, };

```json
//package.json
"scripts": {
  "build": "rollup -c --environment NODE_ENV:production",
  //-w:(--watch)开启文件监听
  "serve": "rollup -c --environment NODE_ENV:development -w"
},