In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
Today, the editor will share with you the relevant knowledge of what the webpack dynamic import principle is. The content is detailed and the logic is clear. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.
Example / / index.jsimport ('. / test') .then (fn = > {console.log (fn.default ());}) / / test.jsexport default function func () {return 1}
The packaged code contains two files, bundle.js and 0.js
Click to expand bundle.js
/ * / (function (modules) {/ / webpackBootstrap/*/ install a JSONP callback for chunk loading/*/ 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()();/******/ }/******//******/ };/******//******//******/ // The module cache/******/ var installedModules = {};/******//******/ // object to store loaded and loading chunks/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched/******/ // Promise = chunk loading, 0 = chunk loaded/******/ var installedChunks = {/******/ "main": 0/******/ };/******//******//******//******/ // script path function/******/ function jsonpScriptSrc(chunkId) {/******/ return __webpack_require__.p + "" + chunkId + ".bundle.js"/******/ }/******//******/ // The require function/******/ function __webpack_require__(moduleId) {/******//******/ // Check if module is in cache/******/ if(installedModules[moduleId]) {/******/ return installedModules[moduleId].exports;/******/ }/******/ // Create a new module (and put it into the cache)/******/ var module = installedModules[moduleId] = {/******/ i: moduleId,/******/ l: false,/******/ exports: {}/******/ };/******//******/ // Execute the module function/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);/******//******/ // Flag the module as loaded/******/ module.l = true;/******//******/ // Return the exports of the module/******/ return module.exports;/******/ }/******//******/ // 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);/******/ };/******//******/ // expose the modules object (__webpack_modules__)/******/ __webpack_require__.m = modules;/******//******/ // expose the module cache/******/ __webpack_require__.c = installedModules;/******//******/ // define getter function for harmony exports/******/ __webpack_require__.d = function(exports, name, getter) {/******/ if(!__webpack_require__.o(exports, name)) {/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });/******/ }/******/ };/******//******/ // define __esModule on exports/******/ __webpack_require__.r = function(exports) {/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });/******/ }/******/ Object.defineProperty(exports, '__esModule', { value: true });/******/ };/******//******/ // create a fake namespace object/******/ // mode & 1: value is a module id, require it/******/ // mode & 2: merge all properties of value into the ns/******/ // mode & 4: return value when already ns object/******/ // mode & 8|1: behave like require/******/ __webpack_require__.t = function(value, mode) {/******/ if(mode & 1) value = __webpack_require__(value);/******/ if(mode & 8) return value;/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;/******/ var ns = Object.create(null);/******/ __webpack_require__.r(ns);/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));/******/ return ns;/******/ };/******//******/ // getDefaultExport function for compatibility with non-harmony modules/******/ __webpack_require__.n = function(module) {/******/ var getter = module && module.__esModule ?/******/ function getDefault() { return module['default']; } :/******/ function getModuleExports() { return module; };/******/ __webpack_require__.d(getter, 'a', getter);/******/ return getter;/******/ };/******//******/ // Object.prototype.hasOwnProperty.call/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };/******//******/ // __webpack_public_path__/******/ __webpack_require__.p = "";/******//******/ // on error function for async loading/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };/******//******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);/******/ jsonpArray.push = webpackJsonpCallback;/******/ jsonpArray = jsonpArray.slice();/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);/******/ var parentJsonpFunction = oldJsonpFunction;/******//******//******/ // Load entry module and return exports/******/ return __webpack_require__(__webpack_require__.s = "./src/index.js");/******/ })/************************************************************************//******/ ({/***/ "./src/index.js":/*!**********************!*\ !*** ./src/index.js ***! \**********************//*! no static exports found *//***/ (function(module, exports, __webpack_require__) {eval("__webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./test */ \"./src/test.js\")).then(function (fn) {\n console.log(fn[\"default\"]());\n});\n\n//# sourceURL=webpack:///./src/index.js?");/***/ })/******/ }); 点击展开0.js (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{/***/ "./src/test.js":/*!*********************!*\ !*** ./src/test.js ***! \*********************//*! exports provided: default *//***/ (function(module, __webpack_exports__, __webpack_require__) {"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return func; });\nfunction func() {\n return 1;\n}\n\n//# sourceURL=webpack:///./src/test.js?");/***/ })}]);1. 模块加载 webpack通过__webpack_require__加载模块代码 // bundle.jsfunction __webpack_require__(moduleId) // 如果模块已经加载,直接返回模块导出 if(installedModules[moduleId]) { return installedModules[moduleId].exports; } // 模块导出和模块信息 var module = installedModules[moduleId] = { i: moduleId, l: false, exports: {} } // 执行模块代码 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__) module.l = true // 标记模块已经加载完成 return module.exports;}__webpack_require__('index.js') 然后执行index.js编译后的代码,如下。 Promise.all( [ __webpack_require__.e(0) ]).then( __webpack_require__.bind(null, "./src/test.js")).then(function (fn) { console.log(fn.default());}));2. jsonp动态加载script 先一步步来,看下__webpack_require__.e这个方法,它是最先调用的。 // bundle.js__webpack_require__.e = function requireEnsure(chunkId) { var promises = [] var installedChunkData = installedChunks[chunkId]; // 如果这个chunk已经加载过了 就不需要加载了 if(installedChunkData !== 0) { // 0 means "already installed" if(installedChunkData) { promises.push(installedChunkData[2]); } else { // 为这个chunk创建一个promise var promise = new Promise(function(resolve, reject) { // 记录这个chunk对应promise的resolve和reject方法 installedChunkData = installedChunks[chunkId] = [resolve, reject]; }); // promises数组里添加这个chunk对应的promise promises.push(installedChunkData[2] = promise) // ============== 动态创建script ================= 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);}; 总结一下,上述代码做的事情 如果chunk没有被加载过,会为这个chunk创建一个promise对象 将promise对象存在promises数组中 将promise的resolve 和 reject存在installedChunks[chunkId]中 3. 执行异步脚本 经过上面的过程,会动态加载0.js的脚本代码 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{"./src/test.js":(function(module, __webpack_exports__, __webpack_require__) {"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return func; });\nfunction func() {\n return 1;\n}\n\n//# sourceURL=webpack:///./src/test.js?");/***/ })}]); 可以看到window上有一个webpackJsonp数组,那么这个东西是从哪里来的呢?,我们来看下面的代码。 // bundle.jsvar jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);jsonpArray.push = webpackJsonpCallback;jsonpArray = jsonpArray.slice();for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);var parentJsonpFunction = oldJsonpFunction; 其实一开始初始化时已经覆盖实现了webpackJsonp.push方法 (window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{ // test.js引入的模块代码})// 等价于webpackJsonpCallback([[0],{ // test.js引入的模块代码}) 下面再看看webpackJsonpCallback代码的实现 4. webpackJsonpCallback// bundle.jsfunction webpackJsonpCallback(data) { // chunkid var chunkIds = data[0]; // chunkid对应的模块 var moreModules = data[1] var moduleId, chunkId, i = 0, resolves = []; for(;i < chunkIds.length; i++) { chunkId = chunkIds[i]; if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) { // 收集chunk对应的resolve方法 resolves.push(installedChunks[chunkId][0]); } // 标记该chunk已经加载 installedChunks[chunkId] = 0; } for(moduleId in moreModules) { if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { // 添加chunk模块,到全局modules对象中 modules[moduleId] = moreModules[moduleId]; } } if(parentJsonpFunction) parentJsonpFunction(data) // 依次执行chunk对应promise的resolve方法 while(resolves.length) { resolves.shift()(); }}; 还是总结一下上面代码的过程 收集chunk对应的resolve方法, 前面执行__webpack_require__.e时放在了installedChunks[chunkId]里 将异步chunk下的所有模块 添加到 全局modules 依次执行chunk对应promise的resolve方法 5. 执行异步模块代码 回到一开始index.js的代码 Promise.all( [ __webpack_require__.e(0) ]).then( __webpack_require__.bind(null, "./src/test.js")).then(function (fn) { console.log(fn.default());})); 经过上面的步骤,此时promise已经resolve了,__webpack_require__.bind(null, "./src/test.js") 会被执行, 此时异步模块的代码已经在modules上了,所以可以直接加载。 最后,执行fn方法 console.log(fn.default());流程图These are all the contents of the article "what is the principle of webpack dynamic import?" Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 290
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.