Skip to content

Latest commit

 

History

History
132 lines (114 loc) · 4.05 KB

webpack2新功能之tree sharking.md

File metadata and controls

132 lines (114 loc) · 4.05 KB
layout title date tags comments
post
webpack2新功能之tree-shaking
2017/02/11 16:33
webpack2
true

webpack2新功能之tree-shaking

最近webpack2正式发布,这个大版本历时一年多时间开发终于发布稳定版本。 tree-shaking是webpack2一大亮点,从字面上能猜出大概的意思:摇一摇树很多叶子就会掉下来,它能删除没有被import引用过的代码。 不过这个概念却是rollup.js首先提出来。 我们先看看它的效果怎么样?

测试tree-shaking效果

使用大家最常用react-router模块测试一下。创建main.js文件,引入react-router几个对象。代码如下:

    import { Router, Route, Link, browserHistory } from 'react-router';

我们需要使用babel来编译react。react-router默认是ES5版本,需要通过resole.mainFileds属性来调用ES6版本。webpack.config.js配置文件如下:

var path = require("path");
var webpack = require("webpack");
module.exports = {
    entry: {
        main: ['./main']
    },
    output: {
        path: path.join(__dirname) + "/dist/",
        filename: "[name].bundle.js"
    },
    module: {
        rules: [{
            test: /\.(js)$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['react']
            }
        }]
    },
    resolve: {      
        mainFields: ["jsnext:main", "main"]
    }
}

同时使用webpack2和webpack1两个版本对这段代码进行打包,对比一下最后文件大小。 使用webpack2版本进行打包结果如下:

Hash: 8ce95ccddcaf8a12428c
Version: webpack 2.2.1
Time: 2289ms
        Asset     Size  Chunks             Chunk Names
main.bundle.js  65.5 kB       0  [emitted]  main

使用webpack1版本进行打包结果如下:

Hash: 0ebab5b941295d6c81b9
Version: webpack 1.12.2
Time: 3793ms
        Asset    Size  Chunks             Chunk Names
main.bundle.js  107 kB       0  [emitted]  main

webpack2打包代码大小是65.5KB,webpack1打包代码是107KB。 tree-shaking让代码减少了大约40%。当第三方模块体积越大,tree-shaking的效果就会越明显.

tree-shaking干了什么?

tree-shaking主要做什么事情?举个官方例子具体说明一下。
maths.js模块具有square和cube两个方法

// This function isn't used anywhere
export function square(x) {
    return x * x;
}

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

main.js只有引入maths.js模块cube方法

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

执行webpack -p main.js dist.min.js命令,生成一个dist.min.js文件,打开并解压缩文件。内容如下:

function(e, t, n) {
    "use strict";

    function r(e) {
        return e * e * e
    }
    t.a = r
}
function(e, t, n) {
    "use strict";
    Object.defineProperty(t, "__esModule", {
        value: !0
    });
    var r = n(0);
    console.log(n.i(r.a)(5))
};

最终生产代码中maths.js模块只有cube方法,删除没有被引用的square方法; 这是基于ES6模块化一个优化功能,使用它前提是你的代码用ES6开发的。

为什么必须是ES6写法

ES6的export和import要求必须在代码顶层,不能嵌套在函数或者条件判断。因为import相对于其他代码会优先执行,生成一个引用。 例如下面代码是不允许:

    setTimeout(function(){
        import {cube} from './maths.js';
        console.log(cube(5));
    }, 1000)
    // => error: 'import' and 'export' may only appear at the top level

这种设计导致import无法动态加载模块,所有模块加载一开始就是固定的,从而本地构建工具才可以静态分析出模块之间引用关系,删除那些没有引用的代码。这就是为什么tree-shaking只能用在ES6的原因

使用场景

当项目代码或者引用第三方库文件是ES6开发的都可以使用webpack2的tree-shaking功能。它说不定能让你的项目来一次大瘦身!