设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

浅谈 Webpack 背后的运行机制(5)

发布时间:2019-08-15 12:49 所属栏目:21 来源:Alan
导读:接着从第二行开始, installedChunkData 从缓存中取值,显然首次加载 chunk 时此处是 undefined。接下来, installedChunkData 的 undefined 值触发了第一层 if 语句的判断条件。紧接着进行到第二层 if 语句,此时

接着从第二行开始, 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 一探究竟:

  1. (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0], { 
  2. "./src/utils/math.js": 
  3. (function (module, __webpack_exports__, __webpack_require__) { 
  4.  
  5.  
  6. "use strict"; 
  7. __webpack_require__.r(__webpack_exports__); 
  8. /* harmony export (binding) */ 
  9. __webpack_require__.d(__webpack_exports__, "plus", function () { 
  10. return plus; 
  11. }); 
  12. const plus = (a, b) => { 
  13. return a + b; 
  14. }; 
  15. }) 
  16. }]); 

我们发现了:

  1. 久违的 ./src/utils/math.js 模块
  2. window["webpackJsonp"] 数组的使用地点

这段代码开始执行,把异步加载相关的 chunk id 与模块传给 push 函数。而前面已经提到过, window["webpackJsonp"] 数组的 push 函数已被重写为 webpackJsonpCallback 函数,它的定义位置在 webpackBootstrap 中:

  1. function webpackJsonpCallback(data) { 
  2. var chunkIds = data[0]; 
  3. var moreModules = data[1]; 
  4. // then flag all "chunkIds" as loaded and fire callback 
  5. var moduleId, chunkId, i = 0, resolves = []; 
  6. // 将 chunk 标记为已加载 
  7. for(;i < chunkIds.length; i++) { 
  8. chunkId = chunkIds[i]; 
  9. if(installedChunks[chunkId]) { 
  10. resolves.push(installedChunks[chunkId][0]); 
  11. installedChunks[chunkId] = 0; 
  12. // 把 "moreModules" 加到 webpackBootstrap 中的 modules 闭包变量中。 
  13. for(moduleId in moreModules) { 
  14. if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 
  15. modules[moduleId] = moreModules[moduleId]; 
  16. // parentJsonpFunction 是 window["webpackJsonp"] 的原生 push 
  17. // 将 data 加入全局数组,缓存 chunk 内容 
  18. if(parentJsonpFunction) parentJsonpFunction(data); 
  19. // 执行 resolve 后,加载 chunk 的 promise 状态变为 resolved,then 内的函数开始执行。 
  20. while(resolves.length) { 
  21. resolves.shift()(); 
  22. }; 

走进这个函数中,意味着异步加载的 chunk 内容已经拿到,这个时候我们要完成两件事,一是让依赖这次异步加载结果的模块继续执行,二是缓存加载结果。

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读