详解从零搭建 vue2 vue-router2 webpack3 工程(9)
如果你查看未压缩版的vendor.js,会发现不仅包含vue的代码,还包含了webpackBootstrap(webpack模块加载器)的代码,按理说放在vendor里面也没啥问题,毕竟后面的模块都需要依赖于此,但是如果你的chunk使用了hash,一旦app代码发生了改变,相应的hash值会发生变化,webpackBootstrap的代码也会发生变化(如图),而我们提取vendor的初心就是这部分代码改变频率不大,显然这不符合我们的目标,那么应当将webpackBootstrap再提取到一个文件中,代码如下:
new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor'] })
用 import 还是 require
vue 2.2.0 后不能直接使用 require 来加载 vue,那么到底改是该使用 ES6 Module 还是 CommonJS 呢?,先看一个对比图:
全部使用 ES6 Module,即import、export default,最终打包的app.js为1.20KB。
全部使用 CommonJS(除了vue),即require、module.exports,最终打包的app.js为1.12KB。
虽然两者大小相差不大,但是这不禁让人觉得用 CommonJS 似乎是一条优化措施,那么代码层面到底是怎么回事呢?
为了一探究竟,注释了压缩插件,以about.vue最终构建的代码来看,使用 CommonJS 的代码如下:
(function (module, exports, __webpack_require__) { "use strict"; module.exports = { data: function data() { return { page: 'about' }; } }; }),
这基本上和 about.vue 中的代码相差无几,而使用 ES6 Module 构建的代码如下:
(function (module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = { data: function data() { return { page: 'about' }; } }; }),
对比两种规范下构建后的代码,使用 ES6 Module 主要是多了 Object.defineProperty 那一部分,从而导致了最终打包的文件大一点儿。那是不是为了最终文件体积能小些就全部使用 CommonJS 呢?这个需要你充分理解 CommonJS 和 ES6 Module 的区别,引用《ECMAScript 6入门》这本书的解释如下:
ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。
为了更清楚的理解这段话,我们稍微做一下测试,在 src 下增加一个test.js,内容如下(分别将两种写法列出):