Webpack2 tree shaking 之旅

来源:互联网 发布:系统优化软件 编辑:程序博客网 时间:2024/04/29 12:14

背景:最近webpack升级了2.0的版本,支持代码静态依赖解析打包了。吓得我赶紧弄个小demo出来试试水。本文默认读者都有一定的webpack使用经验,没使用过webpack的同学最好先看下相关文档。

静态依赖打包可以去掉很多无用的代码,减少文件体积。下面两张图片是楼主打包的两个文件,一个是使用tree shaking,一个是没使用的,都是为了引用一个方法encodeHTML。对比下生成文件的差异。

普通require模式引入

 

es6 tree shaking

 

可以看到tree shaking 只打包了我们需要的那个方法。楼主的demo支持打包多页面,地址在最下面,各位小伙伴可以自己clone下来看看。

看完了tree shaking的效果,下面我们来讨论以下几点

1. 如何开启webpack2tree shaking功能

2. Webpack2配置注意事项

3. ES6模块编写注意事项

4.  一些配置优化点

如何开启webpack2tree shaking功能

首先,只有es6模块才能使用webpack2做静态依赖解析。因为现在大部分浏览器还不支持es6模块语法,所以我们得下载babel,利用babel对代码进行编译。正常使用Babel 6来转换,一般设置presets: ['es2015']。但是这种方式使用的 transform-es2015-modules-commonjs插件意味着Babel会将es6模块通过commonJs模块转换输出,然后webpack 2就不能进行tree-shaking分析了。我的办法是修改babel的设置

//关键代码,只有去掉babel的cjs模块,才能做tree shaking打包test: /\.js$/,loader:'babel',query: {    cacheDirectory: true,    plugins: [        'transform-es2015-template-literals',        'transform-es2015-literals',        'transform-es2015-function-name',        'transform-es2015-arrow-functions',        'transform-es2015-block-scoped-functions',        'transform-es2015-classes',        'transform-es2015-object-super',        'transform-es2015-shorthand-properties',        'transform-es2015-computed-properties',        'transform-es2015-for-of',        'transform-es2015-sticky-regex',        'transform-es2015-unicode-regex',        'check-es2015-constants',        'transform-es2015-spread',        'transform-es2015-parameters',        'transform-es2015-destructuring',        'transform-es2015-block-scoping',        'transform-es2015-typeof-symbol',        ['transform-regenerator', {async: false, asyncGenerators: false}]]}exclude: /node_modules/

Webpack2配置注意事项

Webpack2相对webpack1做了一些配置的更改,更改的配置比较多,这里只是简单的介绍下几个影响构建的部分

Resolve option

webpack1中,文件路径查找的resolve.root属性被删除了,取代的是resolve.module属性。

Plugins

//webpack.optimize.OccurenceOrderPlugin插件不再需要配置//ExtractTextPlugin配置方式变更, ExtractTextPlugin需要更新到2.0版本。新老配置方式对比:Webpack1 : ExtractTextPlugin.extract('css!postcss!sass')Webpack2: ExtractTextPlugin.extract({                    fallbackLoader: "style-loader",                    loader: "css-loader?minimize"                })//CommonsChunkPlugin配置方式变更Webpack1:CommonsChunkPlugin('common/common','js/[name].js')Webpack2:CommonsChunkPlugin({name:'commonFile',filename:'js/[name].[hash:8].js' })

HMR communication

Webpack 1 中,更新信号用的是Web Messaging APIpostMessage)。而Webpack 2将使用一个标准的事件触发器来传递事件信号。这表示WebSocket必须内联到打包文件中。webpack-dev-server必须使用新版本

更多配置可以看楼主的demo和下文参考资料中的链接

ES6模块编写注意事项

Webpack2支持新的异步加载模块方法System.import。使用这个方法可以返回一个promise对象,模块加载失败可以被捕获,支持动态模块名,每个动态模块都会产生新的chunk文件。异步加载的文件,没必要分别导出模块的方法。

示例代码

function route(path, query) {   return System.import("./routes/" + path + "/route")        .then(route => new route.Route(query));}

这会为每种可能的路径组合都创建一个对应的chunk

非异步的模块,使用export关键字,导出函数和变量,在构建时,才可以分析依赖进行构建。

示例代码

export function encodeHTML(str) {    if (typeof str == 'string') {        var ar = ['&', '&', '<', '<', '>', '>', '"', '"'];        for (var i = 0; i < ar.length; i += 2) {            str = str.replace(new RegExp(ar[i], 'g'), ar[1 + i]);        }        return str;    }    return str;} export var a = ['hello world']; //引用import {encodeHTML} from 'util/string_es6'

一些配置优化点

UglifyJsPlugin配置output.max_line_len属性,指定压缩文件的单行最大长度,方便在线上代码出现js问题的时候可以快速定位到出错的代码位于哪一行。

webpack.DllPlugin打包不怎么改动的文件,提高构建速度。

babel打包默认会加上use strict,如果使用了argument.calleejs代码。会导致一些语法错误。可以使用插件babel-plugin-transform-remove-strict-mode或者用gulp全局替换下。

demo地址:https://github.com/xyc-cn/webpack2-demo/tree/master

参考资料

Babel use strict https://github.com/shanggqm/blog/issues/1

Webpack1 to webpack2 https://github.com/cssmagic/blog/issues/58

Webpack2 tree shaking http://www.2ality.com/2015/12/webpack-tree-shaking.html

Webpack2 demo https://github.com/phiphou/webpack-es6-demo

 

0 0