你尚未登录,仅允许查看本站部分内容。请登录使用邀请码注册
whilefor

rollup.js 简介 1个回复 专栏 @ 框架与库

whilefor 发布于 5 月前

rollup.js 简介

1-rtjclmz8sq3clft9aq8xyg

  • Webpack vs Rollup
  • Rollup语法
  • Tree-shaking
  • Webpack and Rollup: the same but different
  • Google Closure Compiler

Webpack vs Rollup

在Webpack已经是霸主地位的构建打包天下,杀出一个Rollup。Vue, Ember, Preact, D3, Three.js, Moment, etc. 一些很有名的js库,甚至最近React,都使用纷纷使用Rollup来作为打包工具。所以Rollup想必有它的优势。

Rollup语法

Rollup的语法比Webpack更加简单,文档教程比Webpack更加循序渐进,按顺序全部看一遍,虽然没有中文,但英文读下来基本没有障碍。有JavaScript-API的使用方法,也有指定配置文件形式的CLI的方法,这里就只介绍配置文件的用法。

// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import buble from 'rollup-plugin-buble';

export default {
  // 入口文件
  entry: 'src/main.js',

  // 指定打包后js的代码格式 - 'amd', 'cjs', 'es', 'iife', 'umd'
  format: 'cjs',  

  // 使用的插件
  plugins: [
    buble(),
    resolve(),
    babel({
      exclude: 'node_modules/**' // only transpile our source code
    })
  ],

  // 可以同时打包输出多个格式的js文件
  targets: [
    { dest: 'dist/bundle.cjs.js', format: 'cjs' },
    { dest: 'dist/bundle.umd.js', format: 'umd' },
    { dest: 'dist/bundle.es.js', format: 'es' },
  ],

  //也可以是一个
  dest: 'bundle.js'
};

如果使用balel插件,就需要在src目录下新建.babelrc文件

// src/.babelrc
{
  "presets": [
    ["latest", {
      "es2015": {
        // 指定babel不要把es2015的模块转换为commonjs的
        "modules": false
      }
    }]
  ],
  "plugins": ["external-helpers"]
}

Tree-shaking

这个概念是Rollup提出来的。

Rollup推荐使用ES2015 Modules来编写模块代码,这样就可以使用Tree-shaking来对代码做静态分析消除无用的代码,可以查看Rollup网站上的REPL示例,代码打包前后之前的差异,就会清晰的明白Tree-shaking的作用。

  • 没有使用额外的模块系统,直接定位import来替换export的模块
  • 去掉了未被使用的代码

打包前的js代码

```js
// main.js (entry module)
import { cube } from './maths.js';
console.log( cube( 5 ) ); // 125

```js
// ./maths.js
// This function isn't used anywhere, so
// Rollup excludes it from the bundle...
export function square ( x ) {
return x * x;
}

// This function gets included
export function cube ( x ) {
return x * x * x;
}

打包后的js代码

'use strict';

// This function isn't used anywhere, so
// Rollup excludes it from the bundle...


// This function gets included
function cube ( x ) {
return x * x * x;
}

console.log( cube( 5 ) ); // 125

更多Tree-shaking代码示例

Rollup之所以能可以用Tree-shaking来消除无用的代码

主要为以下四个原因(摘自尤雨溪在知乎的回答):

  1. import只能作为模块顶层的语句出现,不能出现在 function 里面或是 if 里面。
  2. import 的模块名只能是字符串常量。
  3. 不管 import 的语句出现的位置在哪里,在模块初始化的时候所有的 import 都必须已经导入完成。
  4. import binding 是 immutable 的,类似 const。比如说你不能 import { a } from './a' 然后给 a 赋值个其他什么东西。

Webpack and Rollup: the same but different

Rollup作者最近的一片文章里分析了Webpack和Rollup的不同之处。总结是说Webpack适合在单页应用Web App上使用,Rollup适合使用在独立的js库上。

Use Webpack for apps, and Rollup for libraries

Webpack核心功能包括Code-splitting(按需加载js)和Static assets(处理各种格式的资源)。

Rollup到目前为止不支持Code-splitting和hot module replacement (热更新),它更趋向专注于构建分发类的js库,也就是说大多只会生成一个js文件来被其他项目依赖,更好的利用ES2015 modules的优势来缩小和优化代码。

Rollup在15年时候就已经发布,支持Tree-shaking,当时Webpack还是1.*的版本,没有使用Tree-shaking,而且每个模块外还要包一层函数定义,再通过合并进去的 define/require 相互调用,模块越多,这些包在外层的模块系统的函数就越多,造成打包后代码量的增大。

然而Webpack2.* 今年1月份才上线正式的版本,Rollup经过二年左右的发展也取向成熟,所以许多js库从纷纷使用了Rollup。

Webpack and Rollup: the same but different

Google Closure Compiler

Google开发的一个优化js代码的工具,能对源码做更深层次静态分析,更全面的优化达到高度压缩源码的效果,直接看一下的示例,在这不多做介绍。

Google Closure Compiler

参考文章

微信号:feworld
前端这么大我想去看看

  • 297951292

    rollup有很多问题的:

    • 插件不够多,这个要看是不是有足够多的人用,不然没有各种插件支持,基本就废了。比如我想svg生成个iconfont什么的
    • 他的流式处理也有问题,我无法把一个流id(rollup里叫importer)重写,比如a.vue重写成a.ts,以便传到下一个plugin时能被识别成ts并且编译。但是id改写,在load流程之前,改写了id之后,load hook会去load这个不存在的文件,然后就炸了。
    • 还有一个问题,没法做code split。因为,我没找到如何从一个流中,分离出另一个流。举个栗子,还是.vue,假设,我想要从.vue文件中分离出来.html、.scss、.ts三个流,这三个流再通过不同的plugin,识别完之后进入postcss和ts编译。或者另一种情况,System.import在js里做分离点,这个把一个js异步掉。这个时候,又傻了。

    but,rollup的核心还是很强悍的,他不像webpack做太多事情,没有loader之说。编译出来的文件就是一堆全局的Function和Object,用命名做隔离。这个比起webpack的loader加载,快了很多。我用一个简单的js,import了几个简单的lodash模块,都能看出区别。当有几千个模块打包的时候,这个时候就更明显了。

    总之,rollup很像加强版的gulp,解决了代码依赖和冗余的问题。如果没有很多工程化的需求,还是可以的。工程化的话,还要看后面他的社区支持了~~

    #1
登录后回复,如无账号,请使用邀请码注册