webpack 懒加载原理
Posted 前端精髓
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack 懒加载原理相关的知识,希望对你有一定的参考价值。
分析
__webpack_require__.f =
__webpack_require__.e = (chunkId) =>
return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) =>
// promises = [], key = "j"
// chunkId = src_title_js, promises = []
__webpack_require__.f[key](chunkId, promises);
return promises;
, []));
;
var installedChunks =
"main": 0
;
__webpack_require__.f.j = (chunkId, promises) =>
var installedChunkData = installedChunks[chunkId]
if(installedChunkData)
promises.push(installedChunkData[2]);
else
var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
promises.push(installedChunkData[2] = promise);
__webpack_require__.l(url);
__webpack_require__.l = (url) =>
var script;
script = document.createElement('script');
script.src = url;
document.head.appendChild(script);
当懒加载的时候会调用push方法
// install a JSONP callback for chunk loading
var webpackJsonpCallback = (parentChunkLoadingFunction, data) =>
var [chunkIds, moreModules, runtime] = data;
var moduleId, chunkId, i = 0;
for(moduleId in moreModules)
if(__webpack_require__.o(moreModules, moduleId))
// 把返回的模块定义合并到当前的模块定义里面
__webpack_require__.m[moduleId] = moreModules[moduleId];
if(runtime) var result = runtime(__webpack_require__);
if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
for(;i < chunkIds.length; i++)
chunkId = chunkIds[i];
if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId])
// installedChunks[chunkId][0] 是 resolve 方法,调用之后就加载成功
installedChunks[chunkId][0]();
installedChunks[chunkIds[i]] = 0;
var chunkLoadingGlobal = self["webpackChunkwebpack5"] = self["webpackChunkwebpack5"] || [];
chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
源码
src_titile_js.bundle.js
(self["webpackChunkwebpack5"] = self["webpackChunkwebpack5"] || []).push([["src_title_js"],
/***/ "./src/title.js":
/*!**********************!*\\
!*** ./src/title.js ***!
\\**********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) =>
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__,
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ );
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ('hello world');
/***/ )
]);
bundle.js
(() => // webpackBootstrap
var __webpack_modules__ = ();
/************************************************************************/
// The module cache
var __webpack_module_cache__ = ;
// The require function
function __webpack_require__(moduleId)
// Check if module is in cache
var cachedModule = __webpack_module_cache__[moduleId];
if (cachedModule !== undefined)
return cachedModule.exports;
// Create a new module (and put it into the cache)
var module = __webpack_module_cache__[moduleId] =
// no module.id needed
// no module.loaded needed
exports:
;
// Execute the module function
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
// Return the exports of the module
return module.exports;
// expose the modules object (__webpack_modules__)
__webpack_require__.m = __webpack_modules__;
/************************************************************************/
/* webpack/runtime/define property getters */
(() =>
// define getter functions for harmony exports
__webpack_require__.d = (exports, definition) =>
for(var key in definition)
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key))
Object.defineProperty(exports, key, enumerable: true, get: definition[key] );
;
)();
/* webpack/runtime/ensure chunk */
(() =>
__webpack_require__.f = ;
// This file contains only the entry chunk.
// The chunk loading function for additional chunks
__webpack_require__.e = (chunkId) =>
return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) =>
__webpack_require__.f[key](chunkId, promises);
return promises;
, []));
;
)();
/* webpack/runtime/get javascript chunk filename */
(() =>
// This function allow to reference async chunks
__webpack_require__.u = (chunkId) =>
// return url for filenames based on template
return "" + chunkId + ".bundle.js";
;
)();
/* webpack/runtime/global */
(() =>
__webpack_require__.g = (function()
if (typeof globalThis === 'object') return globalThis;
try
return this || new Function('return this')();
catch (e)
if (typeof window === 'object') return window;
)();
)();
/* webpack/runtime/hasOwnProperty shorthand */
(() =>
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
)();
/* webpack/runtime/load script */
(() =>
var inProgress = ;
var dataWebpackPrefix = "webpack5:";
// loadScript function to load a script via script tag
__webpack_require__.l = (url, done, key, chunkId) =>
if(inProgress[url]) inProgress[url].push(done); return;
var script, needAttach;
if(key !== undefined)
var scripts = document.getElementsByTagName("script");
for(var i = 0; i < scripts.length; i++)
var s = scripts[i];
if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) script = s; break;
if(!script)
needAttach = true;
script = document.createElement('script');
script.charset = 'utf-8';
script.timeout = 120;
if (__webpack_require__.nc)
script.setAttribute("nonce", __webpack_require__.nc);
script.setAttribute("data-webpack", dataWebpackPrefix + key);
script.src = url;
inProgress[url] = [done];
var onScriptComplete = (prev, event) =>
// avoid mem leaks in IE.
script.onerror = script.onload = null;
clearTimeout(timeout);
var doneFns = inProgress[url];
delete inProgress[url];
script.parentNode && script.parentNode.removeChild(script);
doneFns && doneFns.forEach((fn) => (fn(event)));
if(prev) return prev(event);
;
var timeout = setTimeout(onScriptComplete.bind(null, undefined, type: 'timeout', target: script ), 120000);
script.onerror = onScriptComplete.bind(null, script.onerror);
script.onload = onScriptComplete.bind(null, script.onload);
needAttach && document.head.appendChild(script);
;
)();
/* webpack/runtime/make namespace object */
(() =>
// define __esModule on exports
__webpack_require__.r = (exports) =>
if(typeof Symbol !== 'undefined' && Symbol.toStringTag)
Object.defineProperty(exports, Symbol.toStringTag, value: 'Module' );
Object.defineProperty(exports, '__esModule', value: true );
;
)();
/* webpack/runtime/publicPath */
(() =>
var scriptUrl;
if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
var document = __webpack_require__.g.document;
if (!scriptUrl && document)
if (document.currentScript)
scriptUrl = document.currentScript.src
if (!scriptUrl)
var scripts = document.getElementsByTagName("script");
if(scripts.length) scriptUrl = scripts[scripts.length - 1].src
// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
// or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\\?.*$/, "").replace(/\\/[^\\/]+$/, "/");
__webpack_require__.p = scriptUrl;
)();
/* webpack/runtime/jsonp chunk loading */
(() =>
// no baseURI
// object to store loaded and loading chunks
// undefined = chunk not loaded, null = chunk preloaded/prefetched
// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
var installedChunks =
"main": 0
;
__webpack_require__.f.j = (chunkId, promises) =>
// JSONP chunk loading for javascript
var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
if(installedChunkData !== 0) // 0 means "already installed".
// a Promise means "currently loading".
if(installedChunkData)
promises.push(installedChunkData[2]);
else
if(true) // all chunks have JS
// setup Promise in chunk cache
var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
promises.push(installedChunkData[2] = promise);
// start chunk loading
var url = __webpack_require__.p + __webpack_require__.u(chunkId);
// create error before stack unwound to get useful stacktrace later
var error = new Error();
var loadingEnded = (event) =>
if(__webpack_require__.o(installedChunks, chunkId))
installedChunkData = installedChunks[chunkId];
if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
if(installedChunkData)
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;
installedChunkData[1](error);
;
__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
else installedChunks[chunkId] = 0;
;
// install a JSONP callback for chunk loading
var webpackJsonpCallback = (parentChunkLoadingFunction, data) =>
var [chunkIds, moreModules, runtime] = data;
// add "moreModules" to the modules object,
// then flag all "chunkIds" as loaded and fire callback
var moduleId, chunkId, i = 以上是关于webpack 懒加载原理的主要内容,如果未能解决你的问题,请参考以下文章
webpack4 系列教程: 单页面解决方案--代码分割和懒加载