接着从第二行开始, installedChunkData 从缓存中取值,显然首次加载 chunk 时此处是 undefined。接下来, installedChunkData 的 undefined 值触发了第一层 if 语句的判断条件。紧接着进行到第二层 if 语句,此时根据判断条件走入 else 块,这里 if 块里的内容我们先战略跳过,else 里主要有两块内容,一是 chunk 脚本加载过程,这个过程创建了一个 script 标签,使其请求 chunk所在地址并执行 chunk 内容;二是初始化 promise ,并用 promise 控制 chunk 文件加载过程。
不过,我们只在这段 else 代码块中找到了 reject 的使用处,也就是在 chunk 加载异常时 chunk[1](error) 的地方,但并没发现更重要的 resolve 的使用地点,仅仅是把 resolve 挂在了缓存上 (installedChunks[chunkId] = [resolve, reject])。
这里的 chunk 文件加载下来会发生什么呢?让我们打开 dist/0.js 一探究竟:
- (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0], {
- "./src/utils/math.js":
- (function (module, __webpack_exports__, __webpack_require__) {
-
-
- "use strict";
- __webpack_require__.r(__webpack_exports__);
- /* harmony export (binding) */
- __webpack_require__.d(__webpack_exports__, "plus", function () {
- return plus;
- });
- const plus = (a, b) => {
- return a + b;
- };
- })
- }]);
我们发现了:
- 久违的 ./src/utils/math.js 模块
- window["webpackJsonp"] 数组的使用地点
这段代码开始执行,把异步加载相关的 chunk id 与模块传给 push 函数。而前面已经提到过, window["webpackJsonp"] 数组的 push 函数已被重写为 webpackJsonpCallback 函数,它的定义位置在 webpackBootstrap 中:
- function webpackJsonpCallback(data) {
- var chunkIds = data[0];
- var moreModules = data[1];
- // then flag all "chunkIds" as loaded and fire callback
- var moduleId, chunkId, i = 0, resolves = [];
- // 将 chunk 标记为已加载
- for(;i < chunkIds.length; i++) {
- chunkId = chunkIds[i];
- if(installedChunks[chunkId]) {
- resolves.push(installedChunks[chunkId][0]);
- }
- installedChunks[chunkId] = 0;
- }
- // 把 "moreModules" 加到 webpackBootstrap 中的 modules 闭包变量中。
- for(moduleId in moreModules) {
- if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
- modules[moduleId] = moreModules[moduleId];
- }
- }
- // parentJsonpFunction 是 window["webpackJsonp"] 的原生 push
- // 将 data 加入全局数组,缓存 chunk 内容
- if(parentJsonpFunction) parentJsonpFunction(data);
- // 执行 resolve 后,加载 chunk 的 promise 状态变为 resolved,then 内的函数开始执行。
- while(resolves.length) {
- resolves.shift()();
- }
- };
走进这个函数中,意味着异步加载的 chunk 内容已经拿到,这个时候我们要完成两件事,一是让依赖这次异步加载结果的模块继续执行,二是缓存加载结果。
(编辑:ASP站长网)
|