打包前文件
index.js文件
import('./bundle/a').then((add) => {
console.log('add---')
})
a.js文件
const add = function (a, b) {
return a + b
}
export default add
使用webpack的mode为development打包
第一步
加载
__webpack_require__(__webpack_require__.s = "./index.js")
__webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./bundle/a */ \"./bundle/a.js\")).then((add) => {\n console.log('add---')\n })")
webpack_require.e 函数
/******/ // This file contains only the entry chunk.
/******/ // The chunk loading function for additional chunks
/******/ __webpack_require__.e = function requireEnsure(chunkId) {
/******/ var promises = [];
/******/
/******/
/******/ // JSONP chunk loading for javascript
/******/
/******/ var installedChunkData = installedChunks[chunkId];
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
/******/
/******/ // a Promise means "currently loading".
/******/ if(installedChunkData) {
/******/ promises.push(installedChunkData[2]);
/******/ } else {
/******/ // setup Promise in chunk cache
/******/ var promise = new Promise(function(resolve, reject) {
/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject];
/******/ });
/******/ promises.push(installedChunkData[2] = promise);
/******/
/******/ // start chunk loading
/******/ var script = document.createElement('script');
/******/ var onScriptComplete;
/******/
/******/ script.charset = 'utf-8';
/******/ script.timeout = 120;
/******/ if (__webpack_require__.nc) {
/******/ script.setAttribute("nonce", __webpack_require__.nc);
/******/ }
/******/ script.src = jsonpScriptSrc(chunkId);
/******/
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ onScriptComplete = function (event) {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
/******/ clearTimeout(timeout);
/******/ var chunk = installedChunks[chunkId];
/******/ if(chunk !== 0) {
/******/ if(chunk) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ chunk[1](error);
/******/ }
/******/ installedChunks[chunkId] = undefined;
/******/ }
/******/ };
/******/ var timeout = setTimeout(function(){
/******/ onScriptComplete({ type: 'timeout', target: script });
/******/ }, 120000);
/******/ script.onerror = script.onload = onScriptComplete;
/******/ document.head.appendChild(script);
/******/ }
/******/ }
/******/ return Promise.all(promises);
/******/ };
installedChunkData 有三种状态 为0 代表已加载,undefined代表未加载,promise代表加载中
此时,新建一个promise对象,将当前的installedChunkData状态为[resolve, reject, promise],
新建script标签,src通过 jsonpScriptSrc函数获取,在事件script.onerror 、 script.onload 中添加回调函数
/******/ onScriptComplete = function (event) {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
/******/ clearTimeout(timeout);
/******/ var chunk = installedChunks[chunkId];
/******/ if(chunk !== 0) {
/******/ if(chunk) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ chunk[1](error);
/******/ }
/******/ installedChunks[chunkId] = undefined;
/******/ }
/******/ };
回调函数 onScriptComplete 是处理文件加载失败,调用 chunk1; 即installedChunkData 中的reject函数
问题:成功的回调函数在哪里?
第一次执行时:在window[“webpackJsonp”]中添加一个push回调函数
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
/******/ jsonpArray.push = webpackJsonpCallback;
当 script文件加载完毕时
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{
/***/ "./bundle/a.js":
/*!*********************!*\
!*** ./bundle/a.js ***!
\*********************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);const add = function (a, b) {\n return a + b\n}\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (add);\n\n//# sourceURL=webpack:///./bundle/a.js?");
/***/ })
}]);
可知0.build.js文件是一个立即执行函数,window[“webpackJsonp”]调用push函数,即上文中的
webpackJsonpCallback回调函数
/******/ function webpackJsonpCallback(data) {
/******/ var chunkIds = data[0];
/******/ var moreModules = data[1];
/******/
/******/
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0, resolves = [];
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ resolves.push(installedChunks[chunkId][0]);
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ for(moduleId in moreModules) {
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
/******/ modules[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
/******/
/******/ while(resolves.length) {
/******/ resolves.shift()();
/******/ }
/******/
/******/ };
其中installedChunks[chunkId][0] 即指resolve函数
二
__webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./bundle/a */ \"./bundle/a.js\"))
这步就很简单了,使用__webpack_require__ 执行./bundle/a.js 文件里的内容