知识 分享 互助 懒人建站

    懒人建站专注于网页素材下载,提供网站模板、网页设计、ps素材、图片素材等,服务于【个人站长】【网页设计师】和【web开发从业者】的代码素材与设计素材网站。

    懒人建站提供网页素材下载、网站模板
    知识 分享 互助!

    rollup.js打包

    作者:佳明妈 来源:未知 2016-10-02 人气:
    在rollup.js编译模块的过程中,通过 Tree-shacking 的方式来剔除各模块中最终未被引用到的方法,通过rollup.js打包的js体积大大减小

    开始使用rollup.js

    跟 webpack rollup可以以命令行和 javascript 调用两种方式,这里只介绍用javascript的调用的这种方式。首先我们安装一些 rollup 使用到的module, 在 package.json 中加上这些

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    {
        // ...
        "devDependencies": {
            "babel-core": "^6.13.0",
            "babel-preset-es2015-rollup": "^1.1.1",
            "rollup": "^0.34.3",
            "rollup-plugin-babel": "^2.6.1",
            "rollup-plugin-commonjs": "^3.3.1",
            "rollup-plugin-node-resolve": "^2.0.0",
            "rollup-plugin-uglify": "^1.0.1"
        }
    }
    

    编写打包的代码

    建一个 build.js 文件,内部代码可以像这样

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    var rollup = require('rollup');
    var babel = require('rollup-plugin-babel');
    var uglify = require('rollup-plugin-uglify');
    var npm = require('rollup-plugin-node-resolve');
    var commonjs = require('rollup-plugin-commonjs');
    rollup.rollup({
        entry: 'src/index.js',
        plugins: [
            npm({ jsnext: true, main: true }),
            commonjs(),
            babel({
                exclude: 'node_modules/**',
                presets: [ "es2015-rollup" ]
            })
        ]
    }).then(function(bundle) {
        bundle.write({
            format: 'cjs',
            banner: banner,
            dest: 'dist/si_log_common.js'
        });
    });
    

    如果需要同时 输出 commonJS 规范和 UMD 规范的代码只要这样既可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    rollup.rollup({
        entry: 'src/index.js',
        plugins: [
            npm({ jsnext: true, main: true }),
            commonjs(),
            babel({
                exclude: 'node_modules/**',
                presets: [ "es2015-rollup" ]
            })
        ]
    }).then(function(bundle) {
        bundle.write({
            format: 'cjs',
            banner: banner,
            dest: 'dist/si_log_common.js'
        });
        rollup.rollup({
            entry: 'src/index.js',
            plugins: [
                npm({ jsnext: true, main: true }),
                uglify(),   // 加入压缩代码
                commonjs(),
                babel({
                    exclude: 'node_modules/**',
                    presets: [ "es2015-rollup" ]
                })
            ]
        }).then(function(bundle) {
            bundle.write({
                // output format - 'amd', 'cjs', 'es6', 'iife', 'umd'
                format: 'umd',
                moduleName: 'siLog',
                sourceMap: true,
                dest: 'si_log.js'
            });
        })
    }).catch(function(err){
        console.log(err);
    });

    ===========================================================================================
    今天则向大家介绍一个—Rollup.js,通过它可以让你的 bundle 最小化,有效减少文件请求大小——以至于连 vue 都迅速地转投它来打包模块。

     

    Tree-shaking

    在 Rollup 编译模块的过程中,通过 Tree-shacking 的方式来剔除各模块中最终未被引用到的方法,通过仅保留被调用到的代码块来缩减 bundle 的大小。

    我们来看下官网的例子。

    页面入口文件 main.js:

    import { cube } from './maths.js';
    console.log( cube( 5 ) ); // 125,即5的立方值

    被引如的 math.js 模块如下:

    // 注意这个方法在入口文件里没有被调用过
    //最终会被 Rollup 剔除
    export function square ( x ) {
        return x * x;
    }
    
    //入口文件需要调用到的求立方值的方法
    export function cube ( x ) {
        return x * x * x;
    }

    通过 Rollup 打包之后如下:

    'use strict';
    
    function cube ( x ) {
        // rewrite this as `square( x ) * x`
        // and see what happens!
        return x * x * x;
    }
    
    console.log( cube( 5 ) ); // 125

    可以很明显地体会到 Tree-shaking 的作用 —— Math 模块里有个从未用到的 square 方法,咱们在 bundle 文件里把它消灭掉了。

    另外 TS 会抽取引用到的模块内容,将它们置于同一个作用域下,进而直接用变量名就可以访问各个模块的接口;而不像 webpack 这样每个模块外还要包一层函数定义,再通过合并进去的 define/require 相互调用。

    当然这种方法需要 ES2015 的解构赋值语法来配合,多亏了它,Rollup 才能有效地对模块内容进行可靠的静态分析。
    web前端开发

     

    Rollup.js使用方式

    安装自然不用说,走 npm 的老套路:

    npm i rollup

    执行打包的方式也是简单到爆:

    rollup src/main.js -o rel/bundle.js

    这意味着将入口文件 src/main.js 打包为 rel/bundle.js 文件。

    很多时候我们开发走的 ES2015 模块语法,但最终编译出来的模块希望它能走 commonjs 语法,只需要加上 -f cjs运行时参数(f for format)即可:

    rollup src/main.js -o rel/bundle.js -f cjs

    当然,如果你想编译为其它格式,可以把 cjs 更换为:

    amd /  es6 / iife / umd

    我们分别来个参考~ 假设入口文件 src/main.js 如下:

    var name = 'VaJoy';
    
    function main () {
        console.log(name);
    }
    
    export default main;

    编译为各种模式后的bundle:

    //////////////////////////////commonjs(-f cjs)
    'use strict';
    
    var name = 'VaJoy';
    
    function main () {
        console.log(name);
    }
    
    module.exports = main;
    
    
    //////////////////////////////AMD(-f amd)
    define(function () { 'use strict';
    
        var name = 'VaJoy';
    
        function main () {
            console.log(name);
        }
    
        return main;
    
    });
    
    //ES2015/ES6(-f es6)
    var name = 'VaJoy';
    
    function main () {
        console.log(name);
    }
    
    export default main;
    
    
    //////////////////////////////Global(-f iife)
    //注意该方法需要通过配置文件形式来执行(见下一节)
    var main = (function () {
        'use strict';
    
        var name = 'VaJoy';
    
        function main () {
            console.log(name);
        }
    
        return main;
    
    }());
    
    //////////////////////////////UMD(-f umd)
    //注意该方法需要通过配置文件形式来执行(见下一节)
    (function (global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
        (global.main = factory());
    }(this, function () { 'use strict';
    
        var name = 'VaJoy';
    
        function main () {
            console.log(name);
        }
    
        return main;
    
    }));

     

    配置文件

    和 webpack 一样,rollup 也支持通过配置文件来实现更灵活的功能。

    我们在项目根目录新建一个 rollup.config.js :

    export default {
      entry: 'src/main.js',
      format: 'cjs',
      dest: 'rel/bundle.js' // 输出文件
    };

    然后执行

    rollup -c

    即可通过默认配置文件(rollup.config.js)所设置的信息来进行打包。

    如果你的配置文件另有其名(例如“rollup.config.dev.js”),在后面加上配置文件名即可:

    rollup -c rollup.config.dev.js

     

    Rollup 也支持使用插件,写到配置对象的 plugin 里即可,这里我们以 rollup-plugin-babel 为例:

    import babel from 'rollup-plugin-babel';
    
    export default {
      entry: 'src/main.js',
      format: 'cjs',
      plugins: [ babel() ],
      dest: 'rel/bundle.js'
    };

    比较不爽的是,babel 的预设不像 webpack 可以直接写在配置文件里,而还是得独立写个“src/.babelrc”(注意我们可以写在 src 下,而不是非得放在项目根目录下):

    {
      "presets": ["es2015-rollup"]
    }

    注意咱得确保安装了 rollup-plugin-babel 和 babel 预设 babel-preset-es2015-rollup:

    npm i rollup-plugin-babel babel-preset-es2015-rollup

    这时候就能配合 babel 一起把 ES6 的模块编译为 ES5 的 bundle 了。

    更多有趣的插件可以在 rollup 项目组织里找,貌似没有 webpack 那样专门有个插件列表页汇总,这点找起来不太方便。

     

    Rollup 也支持直接在模块中来被调用执行,这样很方便跟 grunt/gulp 等工具进行协作。

    如我们修改 rollup.config.dev.js 内容为:

    var rollup = require( 'rollup' );
    var babel = require('rollup-plugin-babel');
    
    rollup.rollup({
        entry: 'src/main.js',
        plugins: [ babel() ]
    }).then( function ( bundle ) {
        bundle.write({
            format: 'umd',
            moduleName: 'main', //umd或iife模式下,若入口文件含 export,必须加上该属性
            dest: 'rel/bundle.js'
        });
    });

    然后用 node 直接执行

    node rollup.config.dev.js

    可以得到一样的执行结果。

    注意 “rollup.rollup()”返回一个带着 bundle 作为 resolve 回调参数的 Promise 对象,我们常规直接使用语法糖 bundle.write 来打包输出文件:

        bundle.write({
            format: 'umd',
            moduleName: 'main',
            dest: 'rel/bundle.js'
        });

    其等价于

      var result = bundle.generate({ //生成一个 bundle + sourcemap
        format: 'umd',
        moduleName: 'main',
        dest: 'rel/bundle.js',
      });
    
      fs.writeFileSync( 'rel/bundle.js', result.code );

     

    SourceMap

    为了方便调试编译后的文件,rollup 肯定不会忘记添加 source map 功能,而且其配置也非常简单:

        {
            format: 'umd',
            moduleName: 'main',
            dest: 'rel/bundle.js',
            sourceMap: true   //加上这里即可
        }

    这样编译后,rollup 会自动生成一个 rel/bundle.js.map 关联到 rel/bundle.js 中。

    也可以将其直接内联在 bundle 里而不是独立生成一个 map 文件:

        {
            format: 'umd',
            moduleName: 'main',
            dest: 'rel/bundle.js',
            sourceMap: 'inline'
        }

    若希望 map 文件可以自定义位置和名称,就得使用上面稍微提到的 bundle.generate 方法了:

      var result = bundle.generate({ //生成一个 bundle + sourcemap
        //...
      });
    
      fs.writeFileSync( 'rel/bundle.js', result.code );
      fs.writeFileSync( 'map/bundle.js.map', result.map.toString() );

     

    issue

    Rollup 虽然利用 ES6 的特性帮咱节省了不少文件大小,但它并没有类似 webpack 的 -p 参数帮你压缩混淆文件。

    因此即使是官方文档也推荐配合使用 UglifyJS 来进一步缩小 bundle 体积。

    另外 webpack2 已经出来好几款 beta 版本了,同样也加上了对 Tree-shaking 的支持,相信 webpack2 出来后,Rollup 的热度会大大消减。
    在rollup.js编译模块的过程中,通过 Tree-shacking 的方式来剔除各模块中最终未被引用到的方法,通过rollup.js打包的js体积大大减小

    ↓ 查看全文

    rollup.js打包由懒人建站收集整理,您可以自由传播,请主动带上本文链接

    懒人建站就是免费分享,觉得有用就多来支持一下,没有能帮到您,懒人也只能表示遗憾,希望有一天能帮到您。

    rollup.js打包-最新评论