打包工具 Rollup

Rollup

概述

Rollup 与 Webpack 作用类似,Rollup更小巧,仅仅是一款 ESM 打包器。

Rollup 中并不支持类型 HMR 这种高级特性

Rollup 并不是与 Webpack 全面竞争,其初衷是提供一个充分利用 ESM 各种特性的高效打包器

快速上手

安装rollup:

yarn add rollup --dev

运行rollup:

yarn rollup

在不传递任何参数的时候,rollup 会打印出它的帮助信息。

Usage: rollup [options]

指定一个打包入口文件

yarn rollup ./src/index.js

指定输出格式 --format iife (自调用函数)

yarn rollup ./src/index.js --format iife

指定输出文件路径 --file

yarn rollup ./src/index.js --format iife --file dist/bundle.js

结论

rollup的打包结果惊人的简洁,基本上跟我们手写的代码一样的。相比于 Webpack 中大量的引导代码还有模块函数,这里的输出结果几乎没有任何的多余代码。rollup 默认会开启 tree-shaking 去优化代码,tree-shaking最早就是在rollup中提出的。

配置文件

// rollup.config.js
export default {
    input: 'src/index.js',
    output: {
        file: 'dist/bundle.js',
        format: 'iife' // 输出格式 (iife:自调用函数)
    }
}

运行打包:

yarn rollup --config

也可以运行指定的配置文件,如:dev.config.js、prod.config.js

yarn rollup --config rollup.config.js
yarn rollup --config dev.config.js
yarn rollup --config prod.config.js

使用插件

额外的需求:

  • 加载其它类型资源文件

  • 导入CommonJS 模块

  • 编译 ECMAScript 新特性

Rollup 支持使用插件的方式扩展

插件是 Rollup 唯一的扩展途径

接下来我们用导入json的插件来演示rollup怎么使用插件

安装rollup-plugin-json

yarn add rollup-plugin-json --dev

打开配置文件 配置:

import json from 'rollup-plugin-json'; // rollup 支持ESM,我们可以直接使用import导入

export default {
    input: 'src/index.js',
    output: {
        file: 'dist/bundle.js',
        format: 'iife' // 输出格式 (iife:自调用函数)
    },
    plugins: [
        json(),// 把调用的结果放到数组当中,而不是将函数放进去
    ]
}

在index.js 中使用

// src/index.js
import { log } from './logger'
import message from './message'
import { name, version } from "../package.json"
const msg = message.hi;

log(msg);
log(name);
log(version);

运行打包:

yarn rollup --confing

查看结果:

// dist/bundle.js
(function () {
    'use strict';

    const log = msg => {
        console.log('--------------INFO--------------');
        console.log(msg);
        console.log('--------------------------------');
    };

    var message = {
        hi: "Hey Guys, I am kk ~"
    };

    var name = "01-getting-start";
    var version = "1.0.0";

    const msg = message.hi;

    log(msg);
    log(name);
    log(version);

}());

加载 npm 模块

Rollup 默认只能按照文件路径去加载本地的文件模块,对于 npm 中的第三方模块并不能像 Webpack 一样直接通过模块名称导入对应模块。

为了抹平这个差异,Rollup官方给出了 rollup-plugin-node-resolve 插件,通过使用这个插件我们就可以直接使用模块名称导入相应的模块。

安装插件:

yarn add rollup-plugin-node-resolve --dev

配置:

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' // 输出格式 (iife:自调用函数)
    },
    plugins: [
        json(),// 把调用的结果放到数组当中,而不是将函数放进去
        resolve(),
    ]
}

使用:

提前到导入了 lodash-es (使用loads-es 而不是使用 lodash 的原因是rollup默认只能处理 ESM 模块)

// src/index.js
import _ from 'lodash-es';
import { log } from './logger'
import message from './message'
import { name, version } from "../package.json"
const msg = message.hi;

log(msg);
log(name);
log(version);
log(_.camelCase('hello world'))

加载 CommonJS 模块

由于目前有大量的 npm 模块使用 CommonJS 的方式去导出成员,所以为了兼容这些模块官方又给出了一个插件:rollup-plugin-commonjs

安装插件 rollup-plugin-commonjs:

yarn add rollup-plugin-commonjs --dev

配置:

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' // 输出格式 (iife:自调用函数)
    },
    plugins: [
        json(),// 把调用的结果放到数组当中,而不是将函数放进去
        resolve(),
        commonjs(),
    ]
}

使用:

先准备 CommonJS 模块

// /src/cjs-module.js
module.exports = {
    foo: 'bar',
}

再到index.js中使用

import _ from 'lodash-es';
import { log } from './logger'
import message from './message'
import { name, version } from "../package.json"
import cjs from './cjs-module'

const msg = message.hi;

log(msg);
log(name);
log(version);
log(_.camelCase('hello world'))
log(cjs);

运行打包:

yarn rollup --config

此时 CommonJS 模块就可以打包进我们的 bundle.js 中了

代码拆分 code spliting

在新版本的Rollup 中也支持了 Dynamic imports (动态导入),Rollup 内部也会自动的去处理代码拆分(分包)

尝试动态导入:

// src/index.js
import('./logger').then(({ log }) => {
    console.log('code splitting~');
})

由于动态导入的打包输出格式不能是iife(因为iife会把所有的模块放到同一个函数当中,所以无法实现代码拆分),要使用代码拆分的话就必须要使用amd或者cjs这些其它的标准。我们配置一下config.js

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' // 输出格式 (iife:自调用函数)
        dir: 'dist',
        format: 'amd'
    },
    plugins: [
        json(),// 把调用的结果放到数组当中,而不是将函数放进去
        resolve(),
        commonjs(),
    ]
}

运行打包:

yarn rollup --config

查看打包结果:dist中生成了入口bundle及动态导入对应的bundle,它们都以amd标准输出的。

这就是在Rollup中以动态导入的形式实现代码拆分。

多入口打包

Rollup 也支持多入口打包,而且对于多入口当中的公共部分也会单独提取出来作为独立的bundle。

配置非常简单,只需要把配置文件中的input属性改为数组就可以了,也可以使用对象。输出格式修改为amd

export default {
  // input: ['src/index.js', 'src/album.js'],
  input: {
    foo: 'src/index.js',
    bar: 'src/album.js'
  },
  output: {
    dir: 'dist',
    format: 'amd'
  }
}

运行打包:

yarn rollup --config

查看结果:有三个文件bar.js、foo.js、及公共模块。

需要注意:对于amd这种输出格式的js文件我们不能直接引用到页面上,而是需要去通过实现amd标准的库加载。

在dist下创建index.html文件,使用require.js加载




    
    
    
    
    Document


  
  
  
  


运行打包结果:

yarn serve dist

打开浏览器可以查看我们的打包结果正常的工作了。

选用原则

Rollup/Webpack

Rollup的优势

  • 输出结果更加扁平
  • 自动移除未引用代码
  • 打包结果依然完全可读

Rollup的缺点

  • 加载非 ESM 的第三方模块比较复杂
  • 模块最终都被打包到一个函数中,无法实现HMR
  • 浏览器环境中,代码拆分功能依赖AMD库

综合以上的特点:

如果我们正在开发应用程序,建议选择 Webpack

如果我们正在开发一个框架或者类库,建议选择 Rollup

所以,大多数知名框架/库都在使用 Rollup

(这不是绝对的标准,只是经验法则,因为Rollup也可以去构建绝大多数的应用程序,而Webpack也可以去构建类库和框架,只不过相对来说术业有专攻些。另外,随着近几年 Webpack的发展,Rollup 的优势基本上也已经被抹平了)

社区中希望二者并存

总结:Webpack 大而全,Rollup 小而美

demo代码查看

你可能感兴趣的:(打包工具 Rollup)