千家信息网

webpack动态import原理是什么

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,今天小编给大家分享一下webpack动态import原理是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下
千家信息网最后更新 2026年11月02日webpack动态import原理是什么

今天小编给大家分享一下webpack动态import原理是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

例子

// index.jsimport('./test').then(fn => {  console.log(fn.default());})
// test.jsexport default function func() {  return 1}

打包后的代码包含两个文件 bundle.js 和 0.js

点击展开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());

流程图

以上就是"webpack动态import原理是什么"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。

模块 代码 方法 动态 知识 篇文章 面的 对象 数组 原理 全局 内容 标记 脚本 过程 不同 很大 东西 两个 中将 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技有限公司 港股互联网科技股 科技服务与互联网 互联网科技公司电话 致骋互联网科技 互联网科技公司介绍 四川狮子座互联网科技 海南购全球互联网科技 湖南洣水互联网科技有限公司扣款 互联网实体化科技化 玖二柒互联网科技公司待遇 岳阳华臻互联网科技有限公司 互联网科技公司有风险吗 恒生互联网科技指数跳水 哈尔滨屹滨互联网科技有限公司 徐州市互联网科技有限公司 互联网科技企业商标注意事项 好易买互联网科技 现代科技的标志之一的互联网 高科技和互联网的现代国家 互联网是第几次科技革命的成果 中国互联网科技工作委员会毛军 厦门中拓互联网络科技有限公司 智慧科技互联网 国外互联网科技网站 中国互联网金融科技基金 受益于互联网科技的高速发展 杭州壁岐互联网科技有限公司 徐州市互联网科技有限公司 沐思想互联网科技有限公司
0