随着Vue,react等MVVM的应用,ES6等新语言特性被引入浏览器端开发中,能高效组织组件化代码,使用ES6 import引用等特性的webpack被许多业务项目使用。
上一期的文章中,我介绍了关于利用localStorage离线化webpack编译后文件的问题,目的就是减少移动网络下的静态资源的请求。利用官方的CommonsChunkPlugin,HashedModuleIdsPlugin两个插件,拆文件,稳定moduleID可以稳定一些情况的编译结果。如果你只是把项目中共有的库文件提取到一个js中,这个方案是比较稳妥的。但是如果我们要更细粒度的拆分时,会发现随着源文件的模块数变化时,每次编译结果会出现我们不想要的"污染"情况。本文就介绍下污染的原理和处理这种污染的一种思路,各位受到困惑的开发们可以自己照着实现自己的方案。
1、“污染”情况的示例
形如上图的目录结构,项目有3个独立的入口文件放在pages目录下,共同依赖一个vue.min.js,分别不同文件依赖alib.js,blib.js,一个vue组件list.vue; 我们使用下面的配置来生成一个每个js文件一一对应的编译后文件。
LsLoader目录下运行 gulp webpack,分析依赖,webpack 开始打包,生成结果如下
看上去很美,那我们现在项目中有了需要改动的地方,list2.js中,原来引用代码是
import a from '../lib/alib.js';
现在我们需要添加个依赖,该动成为->
import a from '../lib/alib.js'
import b from '../lib/blib.js'
修改完毕,gulp webpack ,webpack打包。按道理只有list2.js会发生改变,生成新md5被用户下载到客户端。实际结果呢?
怎么改了一个文件其他也变了,我根本没动啊。我修改了个文件其他页面的缓存也跪了,不科学啊。
这种现象,我称为打包意外污染。
2、污染原理
观察我们前后打包的源码进行比对,除了page_list2文件是确实修改外,alibjs等文件没改源码的结果文件后变化点在这里
第一次编译:webpackJsonp([3],{
第二次编译:webpackJsonp([4],{
vuemin.js库文件修改则是在
第一次编译: 3:
(function(module, exports, __webpack_require__) {
module.exports = __webpack_require__("YOc6");
}),
第二次编译: 4:
(function(module, exports, __webpack_require__) {
module.exports = __webpack_require__("YOc6");
}),
数字都+1了,我们添加了个模块引用所有编译结果的数字序号都+1,这数字是什么?
这些就是webpack运行在浏览器时候配合webpackJSONP函数使用的moduleID和chunckID,
webpack各种loader加载.vue .css .js各种格式组件的背后,是编译loader文件把浏览器不识别的文件转换成一个个可执行的代码块,代码块的标示用的是两个数组,moduleIDs数组和chunkIDs数组,放在webpack源码中,运行时根据遇到的模块数量和chunk数量自增来确定唯一性。chunk可以理解为文件级别的代码块,编译出来后就是个单独的js文件可以被入口文件引用。module则是chunk内部的一个个代码段落.
其中,module又分为normalModule和contextModule两种,
normalModule很好理解,就是普通的模块代码,es6 export翻译成es5的形式后包裹使用,
contextModule比较特殊,是非入口文件暴露内部模块的一段代码,形如
(function(module, exports, __webpack_require__) {
module.exports = __webpack_require__("0YW9"); //把内部的普通模块暴露出去
})
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h63695.shtml