深入理解 webpack 文件打包机制(小结)(7)

// 先将 moreModules 合并到 modules, 再去执行 callbacks, 不然之前未执行的 callback 依赖于新来的模块,你不放进 module 我岂不是得不到想要的模块
for(moduleId in moreModules) {
 if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
 modules[moduleId] = moreModules[moduleId];
 }
}
while(callbacks.length)
 callbacks.shift().call(null, __webpack_require__);

webpack1 和 webpack2 在文件打包上有什么区别?

经过我对打包文件的观察,从 webpack1 到 webpack2 在打包文件上有下面这些主要的改变:

首先,moduleId[0] 不再为入口执行函数做保留,所以说不用傻傻看到 moduleId[0] 就认为是打包文件的入口模块,取而代之的是 window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {} 传入了第三个参数 executeModules,是个数组,如果参数存在则说明它是入口模块,然后就去执行该模块。

if(executeModules) {
 for(i=0; i < executeModules.length; i++) {
 result = __webpack_require__(__webpack_require__.s = executeModules[i]);
 }
}

其次,webpack2 中会默认加载 OccurrenceOrderPlugin 这个插件,即你不用 plugins 中添加这个配置它也会默认执行,那它有什么用途呢?主要是在 webpack1 中 moduleId 的不确定性导致的,在 webpack1 中 moduleId 取决于引入文件的顺序,这就会导致这个 moduleId 可能会时常发生变化, 而 OccurrenceOrderPlugin 插件会按引入次数最多的模块进行排序,引入次数的模块的 moduleId 越小,比如说上面引用的 utilB 模块引用次数为 2(最多),所以它的 moduleId 为 0。

webpackJsonp([3],[
/* 0 */
 (function(module, exports) {
 module.exports = 'util B';
 })
]);

最后说下在异步加载模块时, webpack2 是基于 Promise 的,所以说如果你要兼容低版本浏览器,需要引入 Promise-polyfill ,另外为引入请求添加了错误处理。

__webpack_require__.e = function requireEnsure(chunkId) {
 var promise = new Promise(function(resolve, reject) {
 installedChunkData = installedChunks[chunkId] = [resolve, reject];
 });
 installedChunkData[2] = promise;
 // start chunk loading
 var head = document.getElementsByTagName('head')[0];
 var script = document.createElement('script');
 script.type = 'text/javascript';
 script.charset = 'utf-8';
 script.async = true;
 script.timeout = 120000;
 script.src = __webpack_require__.p + "" + chunkId + "." + {"0":"ae9c5f5f","1":"0ac69acb","2":"20651a9c","3":"0cdc6c84"}[chunkId] + ".js";
 var timeout = setTimeout(onScriptComplete, 120000);
 script.onerror = script.onload = onScriptComplete;
 function onScriptComplete() {
 // 防止内存泄漏
 script.onerror = script.onload = null;
 clearTimeout(timeout);
 var chunk = installedChunks[chunkId];
 if(chunk !== 0) {
  if(chunk) {
  chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
  }
  installedChunks[chunkId] = undefined;
 }
 };
 head.appendChild(script);
 return promise;
};

      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/424.html