小巧而专注的打包工具rollup

507 阅读4分钟

由于以前主要是做web页面开发,所以用的都是webpack来打包。而现在从web页面转到sdk开发,打包工具也从webpack转到了rollup。在此记录一下rollup的特点和使用。

rollup

简介:

Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序

  • 优点: 小巧而专注

应用场景:

使用Rollup的开源项目:
  • vue
  • vuex
  • vue-router

rollup和webpack的对比

名称简介开源项目
rollup是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序vue, vuex, vue-router
webpack是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。element-ui, mint-ui, vue-cli
从上面使用场景可以大概分析出,Rollup偏向应用于js库,webpack偏向应用于前端工程,UI库;如果你的应用场景中只是js代码,希望做ES转换,模块解析,可以使用Rollup。如果你的场景中涉及到css、html,涉及到复杂的代码拆分合并,建议使用webpack。

使用

安装Rollup并创建配置文件,通过如下命令安装
 yarn add --save-dev rollup
在项目的根目录下新建一个新文件 rollup.config.js, 之后再在文件中添加如下代码:
export default {
  input: './src/index.js',
  output: {
    file: './dist/sdk.min.js',
    format: 'umd'
  }
}

接下来了解下各个配置的含义:

input:
rollup先执行的入口文件
output:
rollup 输出的文件。
output.format:
rollup支持的多种输出格式(有amd,cjs, es, iife 和 umd)

我们在package.json代码下 添加如下脚本:

"scripts": {
  "build": "rollup -c"
}

现在我们只要在命令行中 输入命令:yarn run build即可完成打包

接下来看看各个文件代码: src/utils/utils.js:

export function a(name) {
  const str = `我是${name}!`;
  return str;
}
export function b(name) {
  const str = `他是${name}!`;
  return str;
}

src/utils/addArray.js

/**
 * @param  {Array} arr
 * @return {Number}
 */
const addArray = arr => {
  const result = arr.reduce((a, b) => a + b, 0);
  return result;
};
export default addArray;

src/index.js

import { a } from './utils/utils';
import addArray from './utils/addArray';

const res1 = a('老王');
const res2 = addArray([1, 2, 3, 4]);

console.log(res1);
console.log(res2);

最终会在项目的根目录下生成文件 dist/sdk.min.js, 代码如下:

(function (factory) {
    typeof define === 'function' && define.amd ? define(factory) :
    factory();
}((function () { 'use strict';

    function a(name) {
        const str = `我是${name}!`;
        return str;
    }

    /**
     * @param  {Array} arr
     * @return {Number}
     */
    const addArray = arr => {
        const result = arr.reduce((a, b) => a + b, 0);
        return result;
    };

    const res1 = a('老王');
    const res2 = addArray([1, 2, 3, 4]);

    console.log(res1);
    console.log(res2);

})));

如上可以看到 在 src/utils/a.js 下的 b函数没有被使用到,所以打包的时候没有被打包进来。

注意:在上面代码打包后,只有现代浏览器会正常工作,如果要让不支持ES2015的旧版本浏览器下也正常工作的话,我们需要添加一些插件。

使用插件Babel来转换ES6的代码使其支持旧版浏览器

如上打包后的代码,我们可以在现代浏览器下运行了,但是如果我们使用老版本的浏览器的话,就会产生错误。这时我们需要使用Babel来进行转换

首先需要安装一些依赖项:

yarn add @babel/core @babel/preset-env @babel/plugin-external-helpers rollup-plugin-babel --save-dev
注意:Babel preset 是一个有关Babel插件的集合,它会告诉Babel我们需要转译什么。
创建 .babelrc文件

在项目的根目录下创建 .babelrc的新文件,并添加如下JSON代码:

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

然后在 rollup.config.js中引入babel插件:

// Rollup plugins
import babel from 'rollup-plugin-babel';

export default {
  input: './src/index.js',
  output: {
    file: './dist/sdk.min.js',
    format: 'umd'
  },
  plugins: [
    babel({
      exclude: 'node_modules/**'  // 排除node_module下的所有文件
    })
  ]
}

为了避免转译第三方脚本,我们需要设置一个 exclude 的配置选项来忽略掉 node_modules 目录下的所有文件。安装完成后,我们重新运行命令;然后打包后代码变成如下:

(function (factory) {
    typeof define === 'function' && define.amd ? define(factory) :
    factory();
}((function () { 'use strict';

    function a(name) {
      var str = "\u6211\u662F".concat(name, "!");
      return str;
    }

    /**
     * @param  {Array} arr
     * @return {Number}
     */
    var addArray = function addArray(arr) {
      var result = arr.reduce(function (a, b) {
        return a + b;
      }, 0);
      return result;
    };

    var res1 = a('老王');
    var res2 = addArray([1, 2, 3, 4]);
    console.log(res1);
    console.log(res2);

})));

我们对比下代码,可以看到 addArray 的箭头函数解析成真正的函数。 在转译运行完成后,代码也差不多一样的,只是代码已经支持 了旧版本浏览器。

注意: Babel也提供了 babel-polyfill, 也可以让IE8之前的浏览器能够顺利执行。

添加 Uglify插件压缩代码

安装命令如下:
yarn add rollup-plugin-uglify

再在 rollup.config.js 配置代码,为了在开发中使代码更具可读性,我们只在生产环境压缩代码: rollup.config.js配置代码如下:

// Rollup plugins
import babel from 'rollup-plugin-babel';
import uglify from 'rollup-plugin-uglify';

export default {
  input: './src/index.js',
  output: {
    file: './dist/sdk.min.js',
    format: 'umd'
  },
  plugins: [
    babel({
      exclude: 'node_modules/**'  // 排除node_module下的所有文件
    })
    // js 压缩插件,需要在最后引入
    uglify(),
  ]
}