深入理解 webpack 文件打包机制(小结)(9)
通过 npm run build:es6 对压缩的文件进行分析:
// dist/pageA.xxxx.js
webpackJsonp([0],[
function(o, t, e) {
'use strict';
Object.defineProperty(t, '__esModule', { value: !0 });
var n = e(1);
e(2), e(3);
console.log(n.a);
},function(o, t, e) {
'use strict';
t.a = 'util A';
},function(o, t, e) {
'use strict';
for (;;);
console.log('never use');
},
function(o, t, e) {
'use strict';
const n = function() {};
n.prototype.saySomething = function() {
console.log('class C');
};
}
],[0]);
引入但是没用的变量,函数都会清除,未执行的代码也会被清除。但是类方法是不会被清除的。因为 webpack 不会区分不了是定义在 classC 的 prototype 还是其它 Array 的 prototype 的,比如 classC 写成下面这样:
const classC = function() {}
var a = 'class' + 'C';
var b;
if(a === 'Array') {
b = a;
}else {
b = 'classC';
}
b.prototype.saySomething = function() {
console.log('class C');
}
export default classC;
webpack 无法保证 prototype 挂载的对象是 classC,这种代码,静态分析是分析不了的,就算能静态分析代码,想要正确完全的分析也比较困难。所以 webpack 干脆不处理类方法,不对类方法进行 tree shaking。
更多的 tree shaking 的副作用可以查阅: Tree shaking class methods
webpack3 如何做到 scope hoisting?
scope hoisting,顾名思义就是将模块的作用域提升,在 webpack 中不能将所有所有的模块直接放在同一个作用域下,有以下几个原因:
- 按需加载的模块
- 使用 commonjs 规范的模块
- 被多 entry 共享的模块
在 webpack3 中,这些情况生成的模块不会进行作用域提升,下面我就举个例子来说明:
// src/hoist/utilA.js
export const utilA = 'util A';
export function funcA() {
console.log('func A');
}
// src/hoist/utilB.js
export const utilB = 'util B';
export function funcB() {
console.log('func B');
}
// src/hoist/utilC.js
export const utilC = 'util C';
// src/hoist/pageA.js
import { utilA, funcA } from './utilA';
console.log(utilA);
funcA();
// src/hoist/pageB.js
import { utilA } from './utilA';
import { utilB, funcB } from './utilB';
funcB();
import('./utilC').then(function(utilC) {
console.log(utilC);
})
这个例子比较典型,utilA 被 pageA 和 pageB 所共享,utilB 被 pageB 单独加载,utilC 被 pageB 异步加载。
想要 webpack3 生效,则需要在 plugins 中添加 ModuleConcatenationPlugin。
webpack 配置如下:
const webpack = require('webpack');
const path = require('path')
module.exports = {
entry: {
pageA: path.resolve(__dirname, '../src/hoist/pageA.js'),
pageB: path.resolve(__dirname, '../src/hoist/pageB.js'),
},
output: {
path: path.resolve(__dirname, '../dist'),
filename: '[name].[chunkhash:8].js'
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: 2,
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity,
})
]
}
内容版权声明:除非注明,否则皆为本站原创文章。
