在 .babelrc 文件添加 { "modules": false },另见 Babel Config
presets: [
["es2015", { "modules": false } ]
// webpack 能对 ES6 Module 做静态依赖解析,但 babel 转译时需要排除 babel-plugin-transform-es2015-modules-commonjs 插件,才能实现 tree shaking 功能
]
webpack 2 与 rollup 的 tree-shaking 的实现都是因为 ES6 module 的静态特性才得以实现。
webpack 2 默认是支持 tree-shaking,但由于现有的 production 环境,不得不使用 babel 语法转换器,在配置 .babelrc 时,跟 webpack 1 还是有所差别。
此项目只是对 webpack tree-shaking 技术的验证实验。
介于webpack2正式发布,官方也给出 Tree-shaking 的解释
Because ES6 import and export are statically analyzed, webpack can “mark” unused imports and allow minifiers such as UglifyJs, and Closure Compiler to remove the unused code. This may result in much smaller bundles! (Known as dead code elimination) – Click here for more info!
npm install
npm run build
helpers.js
export function foo() {
return 'foo';
}
export function bar() {
return 'bar';
}
entry.js
import {foo} from './helpers';
let elem = document.getElementById('output');
elem.innerHTML = `Output: ${foo()}`;
-
结论:
webpack 2默认是支持tree-shaking验证:
webpack编译后,输出bundle.harmony.js中,可以从 helper 模块代码看出 exports 中没有了 bar 这个方法。
function(module, exports, __webpack_require__) {
"use strict";
/* harmony export (immutable) */ exports["a"] = foo;
/* unused harmony export bar */
function foo() {
return 'foo';
}
function bar() {
return 'bar';
}
}
-
结论:
babel配置没做特殊处理,是无法实现tree shaking验证:
webpack+babel:presets: ['es2015']编译后,输出bundle.normal.js中, helper 模块代码还是包含 bar 方法
function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.foo = foo;
exports.bar = bar;
function foo() {
return 'foo';
}
function bar() {
return 'bar';
}
}
-
结论:
transform-es2015-modules-commonjs插件影响tree shaking的实现验证:
webpack+babel:presets: ['es2015', {'modules': false}]编译后,输出bundle.without-optimize.js中, helper 模块代码已经不包含 bar 方法了
function(module, exports, __webpack_require__) {
"use strict";
/* harmony export (immutable) */ exports["a"] = foo;
/* unused harmony export bar */
function foo() {
return 'foo';
}
function bar() {
return 'bar';
}
}
-
结论:通过UglifyJs简单的代码压缩,过滤掉无用 DCE(无用代码消除)
验证:
webpack+babel:presets: ['es2015', {'modules': false}]编译后,经过UglifyJs压缩,输出bundle.with-optimize.js中,可以看到压缩代码 helper 模块代码已经不包含 bar 方法了
function(t,e,n){"use strict";function r(){return"foo"}e.a=r}
-
结论:只有es6模块才能使用webpack2做静态依赖解析
验证:
webpack入口文件修改为entry.common.js,编译后输出bundle.common.js,里面还是包含 bar 方法,说明除了 ES6 Module 外,无法实现 tree-shaking
function(module, exports) {
module.exports.foo = function foo () {
return 'foo';
}
module.exports.bar = function bar () {
return 'bar';
}
}