Rollup学习笔记

1,133 阅读6分钟

rollup\color{#1E90FF}{rollup} 也是一款 ESmodules\color{#1E90FF}{ESmodules} 打包器,它可以将我们项目中的细小的模块打包为整块的额代码,rollup\color{#1E90FF}{rollup}webpack\color{#1E90FF}{webpack} 类似,但是相比于 webpack,rollup更为小巧,因为 webpack 在配合插件的使用下 可以完成前端过程中绝大多数的开发工作,而 rollup 仅仅是一个 ESmodules 的打包器,并没有其他 额外的功能,比如 webpack 中有的 html 热替换,在rollup中就没有这个功能,rollup 的诞生并不是与 webpack 进行竞争,它只是为了提供一个高效的 Esmodules 打包器,充分利用 ESmodules 的各项特性的高效打包器,

基本使用

  1. 新建一个目录 yarn init 初始化 package.json ,新建 src 目录,包含 index.js, message.js ,logger.js 三个文件
// message.js
export default{
    hi:"hello my name is xuke"
}
// logger.js
export const log =(msg)=> {
    console.log('log')
    console.log(msg)
}
export const error =(error)=> {
    console.log('error')
    console.log(error)
}
//index.js
import {log} from './logger'
import message from './message'
console.log(message.hi)
log('haha')
  1. 安装 rollup,yarn add rollup --dev
  2. 通过 yarn rollup ./src/index.js --format iife --file dist/bundle.js 对入口文件进行打包 ./src/index.js 代表入口文件,dist/bundle.js 代表输出文件
  3. 执行完命令后 我们多出了 dist目录和bundle.js 文件,
// bundle.js
(function () {
    'use strict';
    const log =(msg)=> {
        console.log('log');
        console.log(msg);
    };
    var message = {
        hi:"hello my name is xuke"
    };
    console.log(message.hi);
    log('haha');
}());

通过打包对比我们可以看出 rollup 的打包结果比较简洁,没有任何多余的代码,它是将我们代码中的依赖顺序先后拼接到一起,它打包的结果中只会保留用到的部分,对于未引用的部分都没有输出,这是因为 rollup 会自动开启 treeshaking\color{#1E90FF}{tree shaking} 来优化我们的代码。而 tree shaking 的概念最早也是在 rollup 中提出的

配置文件

rollup 的配置文件是在 rollup.config.js 中配置的,由于rollup 本身会处理 这个配置文件,所以我们可以使用 ESmodules 语法来写

// rollup.config.js
// rollup 配置文件
export default{
    input:'src/index.js',//输入路径
    output:{
        file:'dist/bundle.js',//输出路径名
        format:'iife',//代表输出格式,五种输出格式:amd /  es6 / iife / umd / cjs
    },//输出路径
}

我们执行 yarn rollup --config 就可以生成打包后的文件了,我们只有带了 --config ,rollup 才会执行我们的配置文件,默认是不会执行我们的配置文件的 ,

rollup 使用插件

插件是 rollup 的唯一的扩展途径,他没有 loder,举例使用 rollup-plugin-json 可以导入 json 的插件

  1. 安装插件 yarn add rollup-plugin-json --dev
  2. 配置插件
// rollup 配置文件
+ import json from 'rollup-plugin-json'
  export default{
      input:'src/index.js',//输入路径
      output:{
          file:'dist/bundle.js',//输出路径名
          format:'iife',//代表输出格式,五种输出格式:amd /  es6 / iife / umd / cjs
      },//输出路径
      plugins:[
 +        json(),//我们放的是json函数的结果,而不是函数本身
      ]
  }
  1. 插件的使用,这里我们举例取出 package.json 中的字段
 import {log} from './logger'
  import message from './message'
+ import {name,version} from '../package.json'
+ console.log(name,version)
  console.log(message.hi)
  log('haha')
  1. 重新打包
// bundle.js
(function () {
    'use strict';
    const log =(msg)=> {
        console.log('log');
        console.log(msg);
    };
    var message = {
        hi:"hello my name is xuke"
    };
+    var name = "rollup";
+    var version = "1.0.0";
    console.log(name,version);
    console.log(message.hi);
    log('haha');
}());

我们观察到 bundle.js 中我们引入的package.json 中的字段已经被打包进来了,而没有被打包进来的 被我们的 tree shaking 移除掉了

rollup npm模块加载

rollup 默认只能按照文件路径的方式加载本地的模块,而对于 node_modules 中的第三方的模块,它并不能像 webpack 一样通过 模块的名称导入相对应的模块,需要安装插件yarn add --dev rollup-plugin-node-resolve,然后在plugins中使用:

// rollup 配置文件
   import json from 'rollup-plugin-json'
+  import resolve from 'rollup-plugin-node-resolve'
export default{
    input:'src/index.js',//输入路径
    output:{
        file:'dist/bundle.js',//输出路径名
        format:'iife',//代表输出格式,五种输出格式:amd /  es6 / iife / umd / cjs
    },//输出路径
    plugins:[
        json(),//我们放的是json函数的结果,而不是函数本身
 +      resolve()
    ]
}

我们安装一个第三方模块测试,安装 yarn add lodash-es --save,在index中引入

    import {log} from './logger'
    import message from './message'
    import {name,version} from '../package.json'
+   import _ from 'lodash-es'
+   console.log(_.concat([1],[2,3],[4]))
    console.log(name,version)
    console.log(message.hi)
    log('haha')

重新打包 执行 yarn rollup --config,在bundle.js中就会生成我们引入的 lodash

rollup 加载 commonjs 模块

rollup 默认只加载 ESmodules 模块,我们要想加载 commonjs 模块就要

  1. 安装 rollup-plugin-commonjs
  2. 配置
// rollup 配置文件
      import json from 'rollup-plugin-json'
      import resolve from 'rollup-plugin-node-resolve'
+     import commonjs from 'rollup-plugin-commonjs'
      export default{
          input:'src/index.js',//输入路径
          output:{
              file:'dist/bundle.js',//输出路径名
              format:'iife',//代表输出格式,五种输出格式:amd /  es6 / iife / umd / cjs
          },//输出路径
          plugins:[
              json(),//我们放的是json函数的结果,而不是函数本身
              resolve(),
+             commonjs()
          ]
      }
  1. 使用 在src目录下新建一个 common.js 文件
// common.js
module.exports={
    name:'xuke'
}

在 index.js 中引入

 import {log} from './logger'
    import message from './message'
    import {name,version} from '../package.json'
    import _ from 'lodash-es'
+   import common from './common'
+   console.log(common)
    console.log(_.concat([1],[2,3],[4]))
    console.log(name,version)
    console.log(message.hi)
    log('haha')

bundle.js 代码拆分 rollup 的代码拆分 是按需导入的方式 index.js

import('./logger').then(()=>{
    console.log("xuke")
})

我们这样按需导入的话,我们的配置文件输出目录不能用 file 表示,要用 dir ,format 格式不能定义为 iife(自执行函数,自执行函数会把所有的模块放到一个文件当中,没有办法实现代码拆分),要用 **amd **或者 commonjs中的其他标准 修改配置文件:webpack.config.js

// rollup 配置文件
export default{
    input:'src/index.js',//输入路径
    output:{
        // file:'dist/bundle.js',//输出路径名
        // format:'iife',//代表输出格式,五种输出格式:amd /  es6 / iife / umd / cjs
        dir:'dist',//输出路径名
        format:'amd',//代表输出格式,五种输出格式:amd /  es6 / iife / umd / cjs
    },//输出路径
}

rollup 的优势和缺点

优点:

  1. 输出结果更加扁平,执行效率更高,
  2. 会自动移除未引用的代码(内置了 tree shaking)
  3. 打包结果的可读性比较好

缺点:

  1. 加载第三方模块比较复杂
  2. 模块被打包到一个函数中,不能实现 HMR (html-modules-replace)模块热替换
  3. 浏览器环境中,代码拆分功能必须依赖 amd 库,

打包器选择

当我们使用第三方插件比较多时,我们选用webpack,当我们写一些自定义插件,库,或者框架的时候(vue、react...),我们使用rollup 作为模块打包器,webpack大而全,rollup小而美\color{#FF69B4}{webpack 大而全,rollup 小而美}

rollup 一些问题

为什么ES模块比CommonJS更好?

ES模块是官方标准,也是JavaScript语言明确的发展方向,而CommonJS模块是一种特殊的传统格式,在ES模块被提出之前做为暂时的解决方案。 ES模块允许进行静态分析,从而实现像 tree-shaking 的优化,并提供诸如循环引用和动态绑定等高级功能。

什么是 ‘tree-shaking’?

Tree-shaking, 也被称为 "live code inclusion," 它是清除实际上并没有在给定项目中使用的代码的过程,但是它可以更加高效。

我如何在 CommonJS 模块中使用 Rollup ?

Rollup 力图实现 ES 模块的规范,而不一定是 Node.js, npm, require(), 和 CommonJS 的特性。 因此,加载 CommonJS 模块和使用 Node 模块位置解析逻辑都被实现为可选插件,默认情况下不在 Rollup 内核中。 你只需要执行 npm install 安装 CommonJS 和 node-resolve 插件然后使用 rollup.config.js 配置文件启用他们,那你就完成了所有设置。

Rollup 是用来构建库还是应用程序?

Rollup 已被许多主流的 JavaScript 库使用,也可用于构建绝大多数应用程序。但是 Rollup 还不支持一些特定的高级功能,尤其是用在构建一些应用程序的时候,特别是代码拆分和运行时态的动态导入 dynamic imports at runtime. 如果你的项目中更需要这些功能,那使用 Webpack可能更符合你的需求。