## webpack异步加载原理
***不管任何语言,使用一个模块的步骤分为以下三步***
第一步:找到该模块源码
第二步:加载该模块源码
第三步:使用该模块
对于在网页上的js而言,需要多一步,就是先加载js文件。就是在html中添加 script标签
webpack异步加载js文件是四步。
第一步:异步加载js文件 对应的函数为requireEnsure 该函数的作用就是html body 中追加一个script标签,标签的src就是要加载的js。 并且加载的时候,返回一个文件加载promise。该promise代表着该文件是否被加载完成。
第二步:找到该模块 对应的函数就是webpackJsonpCallback 。该函数的作用就是找到该模块源码,并改变上面的promise的状态,把状态改为已找到该模块源码。具体的流程为:在上面第一步的时候我们请求了这个js,请求这个js以后,下载下来的js源码就是一个 webpackJsonpCallback 执行函数。一下下来就开始执行该函数,函数执行完成后,就改变promise状态。
第三步:就是加载该模块,对应的源码就是__webpack_require__。 该函数的作用就是加载该模块,执行模块内的代码,并把结果导出。对应上面第二步,就是在promise的then 之后 _webpack_require__(模块c)
第四步:就是使用该模块了,对应的上面的步骤就是后面再添加then,在用导出的结果做事情。
具体的使用可以用以下一个函数表达
requireEnsure(xxx.js 下载模块c源码,下载完之后就执行,把模块c源码添加进来).then(webpack_require_(c模块源码 )).then(res=>{res.default 就是模块c源码执行结果。在这里我们可以使用该模块了})
下面举个例子来说明一下
有a.js 和 c.js
a.js 源码为
```
import b from './b.js';
const c = ()=> import('./c.js');
c().then((res)=>{
console.log(res);
})
b();
console.log("我是a.js,我开始加载了");
export default function say(){
console.log("我是a.js,我被调用了")
}
```
看上面的代码,我们可以知道a.js 异步依赖c.js。 在c.js 加载完成后,在做一些事情
我们在看一下对应webpack打包之后的代码
```
a.js 代码
***const c = ()=> __webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./c.js */ "./src/c.js"));
c().then((res)=>{
console.log(res);
})***
Object(_b_js__WEBPACK_IMPORTED_MODULE_0__["default"])();
console.log("我是a.js,我开始加载了");
function say(){
console.log("我是a.js,我被调用了")
}
c.js 打包之后代码
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{
/***/ "./src/c.js":
/*!******************!*\
!*** ./src/c.js ***!
\******************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return sayC; });
/* harmony import */ var _d_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./d.js */ "./src/d.js");
/* harmony import */ var _f_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./f.js */ "./src/f.js");
console.log("我是c.js,我开始加载了");
function sayC(){
console.log("我是c.js,我被调用了");
}
/***/ })
```