深入理解 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, }) ] }
内容版权声明:除非注明,否则皆为本站原创文章。