webpack提供的一个非常强大的功能就是code spliting(代码切割)。
在webpack 1.x中提供了
require.ensure([], () => {
let module = require('./page1/module');
// do something
}, 'module1')
利用require.ensure这个API使得webpack单独将这个文件打包成一个可以异步加载的chunk.
具体的套路见我写的另一篇blog: webpack分包及异步加载套路
一句话总结就是:
在输出的runtime代码中,包含了异步chunk的id及chunk name的映射关系。需要异步加载相应的chunk时,通过生成script标签,然后插入到DOM中完成chunk的加载。通过JSONP,runtime中定义好函数,chunk加载完成后即会立即执行这个函数。
从编译生成后的代码来看,webpack 1.x从chunk的加载到执行的过程处理的比较粗糙,仅仅是通过添加script标签,异步加载chunk后,完成函数的执行。
这个过程当中,如果出现了chunk加载不成功时,这种情况下应该如何去容错呢?
在webpack2中相比于webpack1.x在这个点的处理上是将chunk的加载包裹在了promise当中,那么这个过程变的可控起来。具体的webpack2实现套路也是本文想要去说明的地方。
webpack提供的异步加载函数是
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
// runtime代码里面只包含了入口的chunk
// 这个函数的主要作用:
// 1. 异步加载chunk
// 2. 提供对于chunk加载失败或者处于加载中的处理
// 其中chunk加载状态的判断是根据installedChunks对象chunkId是数字0还是数组来进行判断的
/******/ __webpack_require__.e = function requireEnsure(chunkId) {
// 数字0代表chunk加载成功
/******/ if(installedChunks[chunkId] === 0)
/******/ return Promise.resolve();
/******/ // an Promise means "currently loading".
// 如果installedChunks[chunkId]为一个数组
/******/ if(installedChunks[chunkId]) {
// 返回一个promise对象
/******/ return installedChunks[chunkId][2];
/******/ }
/******/ // start chunk loading
// 通过生成script标签来异步加载chunk.文件名是根据接受的chunkId来确认的
/******/ var head = document.getElementsByTagName('head')[0];
/******/ var script = document.createElement('script');
/******/ script.type = 'text/javascript';
/******/ script.charset = 'utf-8';
/******/ script.async = true;
// 超时时间为120s
/******/ script.timeout = 120000;
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
// 需要加载的文件名
/******/ script.src = __webpack_require__.p + "js/register/" + ({"2":"index"}[chunkId]||chunkId) + ".js";
// 120s的定时器,超时后触发onScriptComplete回调
/******/ var timeout = setTimeout(onScriptComplete, 120000);
// chunk加载完毕后的回调
/******/ script.onerror = script.onload = onScriptComplete;
/******/ function onScriptComplete() {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
// 清空定时器
/******/ clearTimeout(timeout);
// 获取这个chunk的加载状态
// 若为数字0,表示加载成功
// 若为一个数组, 调用数组的第2个元素(第二个元素为promise内传入的reject函数),使得promise捕获抛出的错误。reject(new Error('xxx'))
/******/ var chunk = installedChunks[chunkId];
/******/ if(chunk !== 0) {
/******/ if(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
/******/ installedChunks[chunkId] = undefined;
/******/ }
/******/ };
// 每次需要进行异步加载chunk时,会将这个chunk的加载状态进行初始化为一个数组,并以key/value的形式保存在installedChunks里
// 这个数组为[resolve, reject, promise];
/******/ var promise = new Promise(function(resolve, reject) {
/******/ installedChunks[chunkId] = [resolve, reject];
/******/ });
/******/ installedChunks[chunkId][2] = promise;
/******/ head.appendChild(script);
//返回promise
/******/ return promise;
/******/ };
我们再来看看路由配置文件编译后生成的代码index.js, 特别注意下__webpack_require__.e这个异步加载函数:
Router
.home('path1')
.addRoute({
path: 'path1',
animate: 'zoomIn',
viewBox: '.public-path1-container',
template: __webpack_require__(5),
// 挂载controller
pageInit: function pageInit() {
var _this = this;
console.time('route async path1');
// 异步加载0.js(这个文件是webpack通过code spliting自己生成的文件名)
// 具体异步加载代码的封装见"color: #ff0000">总结一下就是:
webpack2相比于webpack1.x将异步加载chunk的过程封装在了promise当中,如果chunk加载超时或者失败会抛出错误,这时我们可以针对抛出的错误做相应的错误处理。
此外还应该注意下,webpack2异步加载chunk是基于原生的promise。如果部分环境暂时还不支持原生promise时需要提供polyfill。另外就是require.ensure可以接受第三个参数用以给chunk命名,但是import这个API没有提供这个方法
更多的细节大家可以运行demo看下编译后的代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
webpack2异步加载
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]