In depth understanding of webpack module loading principle

Time:2021-8-2

Webpack is a module packer. In its view, every file is a module.

Whether you use the commonjs specification or ES6 module specification for development, the packaged files uniformly use the module specification customized by webpack to manage and load modules. This article will start with a simple example to explain the principle of webpack module loading.

Commonjs specification

Suppose there are now two files:

// index.js
const test2 = require('./test2')

function test() {}

test()
test2()
// test2.js
function test2() {}

module.exports = test2

The above two files use the commonjs specification to import and export files. The packaged code is as follows (unnecessary comments have been deleted):

(function(modules) { // webpackBootstrap
    // The module cache
    //Module cache object
    var installedModules = {};

    // The require function
    //Require() function implemented by webpack
    function __webpack_require__(moduleId) {
        // Check if module is in cache
        //If the module has been loaded, it will return to the cache directly
        if(installedModules[moduleId]) {
            return installedModules[moduleId].exports;
        }
        // Create a new module (and put it into the cache)
        //Create a new module and put it into the cache
        var module = installedModules[moduleId] = {
            i: moduleId,
            l: false,
            exports: {}
        };

        // Execute the module function
        //Execute module functions
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

        // Flag the module as loaded
        //Identify the module as loaded
        module.l = true;

        // Return the exports of the module
        return module.exports;
    }


    // expose the modules object (__webpack_modules__)
    //Mount all modules on the require () function
    __webpack_require__.m = modules;

    // expose the module cache
    //Mount the cache object on the require() function
    __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 = "";


    // Load entry module and return exports
    //Load the entry module and return the module object
    return __webpack_require__(__webpack_require__.s = "./src/index.js");
})({
  "./src/index.js": (function(module, exports, __webpack_require__) {
    eval("const test2 = __webpack_require__(/*! ./test2 */ \"./src/test2.js\")\r\n\r\nfunction test() {}\r\n\r\ntest()\r\ntest2()\n\n//# sourceURL=webpack:///./src/index.js?");
  }),
  
  "./src/test2.js": (function(module, exports) {
    eval("function test2() {}\r\n\r\nmodule.exports = test2\n\n//# sourceURL=webpack:///./src/test2.js?");
  })
});

You can see that the module loading system implemented by webpack is very simple, with only 100 lines of code.

The packaged code is actually an immediate execution function, and the passed in parameter is an object. This object takes the file path as the key and the file content as the value. It contains all packaged modules.

{
  "./src/index.js": (function(module, exports, __webpack_require__) {
    eval("const test2 = __webpack_require__(/*! ./test2 */ \"./src/test2.js\")\r\n\r\nfunction test() {}\r\n\r\ntest()\r\ntest2()\n\n//# sourceURL=webpack:///./src/index.js?");
  }),
  
  "./src/test2.js": (function(module, exports) {
    eval("function test2() {}\r\n\r\nmodule.exports = test2\n\n//# sourceURL=webpack:///./src/test2.js?");
  })
}

Simplifying this immediate function is equivalent to:

(function(modules){
    // ...
})({
    path1: function1,
    path2: function2
})

Let’s look at what this immediate function does:

  1. A module cache object is definedinstalledModules, which is used to cache the loaded modules.
  2. A module loading function is defined__webpack_require__()
  3. … omit some other code.
  4. use__webpack_require__()Load the entry module.

The core is__webpack_require__()Function, which receives arguments that aremoduleId, in fact, is the file path.

Its execution process is as follows:

  1. Judge whether the module has a cache, and if so, return the of the cache moduleexportObject, i.emodule.exports
  2. Create a new modulemodule, and put it into the cache.
  3. Execute the module function corresponding to the file path.
  4. Identify this newly created module as loaded.
  5. After executing the module, return to the of the moduleexportsObject.
// The require function
   //Require() function implemented by webpack
function __webpack_require__(moduleId) {
       // Check if module is in cache
       //If the module has been loaded, it will return to the cache directly
    if(installedModules[moduleId]) {
        return installedModules[moduleId].exports;
    }
       // Create a new module (and put it into the cache)
       //Create a new module and put it into the cache
    var module = installedModules[moduleId] = {
        i: moduleId,
        l: false,
        exports: {}
    };

       // Execute the module function
       //Execute module functions
    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

       // Flag the module as loaded
       //Identify the module as loaded
    module.l = true;

    // Return the exports of the module
    return module.exports;
}

As can be seen from the above code, three parameters are passed in when executing the module function, namelymodulemodule.exports__webpack_require__

amongmodulemodule.exportsAnd in commonjsmodulemodule.exportsThe role of is the same, and__webpack_require__Equivalent to in commonjsrequire

At the end of the immediate function, the__webpack_require__()Load the entry module. And passed in the path of the entry module./src/index.js

__webpack_require__(__webpack_require__.s = "./src/index.js");

Let’s analyze the content of the entry module.

(function(module, exports, __webpack_require__) {
    eval("const test2 = __webpack_require__(/*! ./test2 */ \"./src/test2.js\")\r\n\r\nfunction test() {}\r\n\r\ntest()\r\ntest2()\n\n//# sourceURL=webpack:///./src/index.js?");
  })

The parameters of the entry module function are exactly the three parameters mentioned just now, and the content of the eval function is the same as the following after beautification:

const test2 = __webpack_require__("./src/test2.js")
function test() {}
test()
test2()
//# sourceURL=webpack:///./src/index.js?

Comparing the packaged module code with the original module code, you can find that only one place has changed, that isrequireBecome__webpack_require__

Take another looktest2.jsCode of:

function test2() {}
module.exports = test2
//# sourceURL=webpack:///./src/test2.js?

From the analysis just now,__webpack_require__()After the module is loaded, the function corresponding to the module will be executed first, and then the function of the module will be returnedexportsObject. andtest2.jsExport object formodule.exportsnamelytest2()Function. So the entrance module can pass through__webpack_require__()introducetest2()Function and execute.

So far, it can be found that the module specification customized by webpack perfectly fits the commonjs specification.

ES6 module

Replace the two files just written with the commonjs specification with the ES6 module specification, and then perform packaging.

// index.js
import test2 from './test2'

function test() {}

test()
test2()
// test2.js
export default function test2() {}

Most of the code packaged with ES6 module specification is the same as that packaged with commonjs specification.

The same place means that the code of the webpack custom module specification is the same. The only difference is that the code of the above two files is different after packaging.

{
     "./src/index.js":(function(module, __webpack_exports__, __webpack_require__) {
        "use strict";
        eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _test2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./test2 */ \"./src/test2.js\");\n\r\n\r\nfunction test() {}\r\n\r\ntest()\r\nObject(_test2__WEBPACK_IMPORTED_MODULE_0__[\"default\"])()\n\n//# sourceURL=webpack:///./src/index.js?");
    }),
    
    "./src/test2.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 test2; });\nfunction test2() {}\n\n//# sourceURL=webpack:///./src/test2.js?");
    })
}

You can see that the second parameter passed in is__webpack_exports__, and the second parameter corresponding to the commonjs specification isexports。 Beautify the contents of the two module codes:

// index.js
__webpack_require__.r(__webpack_exports__);
 var _test2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/test2.js");
 function test() {}
 test()
 Object(_test2__WEBPACK_IMPORTED_MODULE_0__["default"])()
 //# sourceURL=webpack:///./src/index.js?
// test2.js
 __webpack_require__.r(__webpack_exports__);
 __webpack_require__.d(__webpack_exports__, "default", function() { return test2; });
 function test2() {}
 //# sourceURL=webpack:///./src/test2.js?

As you can see, one is executed at the beginning of each module__webpack_require__.r(__webpack_exports__)sentence. alsotest2.jsOne more__webpack_require__.d()Function.

Let’s take a look first__webpack_require__.r()and__webpack_require__.d()What is it?

__webpack_require__.d()

// 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 });
    }
};

original__webpack_require__.d()Yes__webpack_exports__Defines the for exporting variables. For example, the following line of code:

__webpack_require__.d(__webpack_exports__, "default", function() { return test2; });

Its function is equivalent to__webpack_exports__["default"] = test2。 this"default"Because you useexport defaultTo export the function. If you export the function as follows:

export function test2() {}

It will become__webpack_require__.d(__webpack_exports__, "test2", function() { return test2; });

__webpack_require__.r()

// 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 });
};

__webpack_require__.r()The function gives__webpack_exports__Add a__esModulebytrueProperty of, indicating that this is an ES6 module.

What’s the use of adding this attribute?

This is mainly to deal with the mixed use of ES6 module and commonjs.

For example, the export uses commonjsmodule.export = test2Export function, import using ES6 moduleimport test2 from './test2

The packaged code is as follows:

// index.js
__webpack_require__.r(__webpack_exports__);
var _test2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/test2.js");
var _test2__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(_test2__WEBPACK_IMPORTED_MODULE_0__);
function test() {}
test()
_test2__WEBPACK_IMPORTED_MODULE_0___default()()
//# sourceURL=webpack:///./src/index.js?
// test2.js
 function test2() {}
 module.exports = test2
 //# sourceURL=webpack:///./src/test2.js?

From the above code, we can find that there is another one__webpack_require__.n()Function:

__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;
};

Let’s first analyze the processing logic of the entry module:

  1. take__webpack_exports__The exported object ID is ES6 module.
  2. loadtest2.jsModule, and the exported object of the module is passed in as a parameter__webpack_require__.n()Function.
  3. __webpack_require__.nAnalyze theexportWhether the object is an ES6 module. If yes, it returnsmodule['default']Namelyexport defaultCorresponding variable. If it is not an ES6 module, it will be returned directlyexport

Load on demand

On demand loading, also known as asynchronous loading and dynamic import, is to download the corresponding resource files only when necessary.

Can be used in webpackimportandrequire.ensureTo introduce the code that needs to be dynamically imported, for example, the following example:

// index.js
function test() {}

test()
import('./test2')
// test2.js
export default function test2() {}

Which useimportImportedtest2.jsWhen the file is packaged, it will be packaged into a single file instead of andindex.jsPack togetherbundle.js

In depth understanding of webpack module loading principle
this0.bundle.jsThe corresponding code is imported dynamicallytest2.jsCode for.

Next, let’s look at the contents of these two packaged files:

// 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":(function(module, exports, __webpack_require__) {
    eval("function test() {}\r\n\r\ntest()\r\n__webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./test2 */ \"./src/test2.js\"))\n\n//# sourceURL=webpack:///./src/index.js?");
  })
});
// 0.bundle.js
(window["webpackJsonp"] = window["webpackJsonp"] || []).push(
  [
    [0],
    {
      "./src/test2.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 test2; });\nfunction test2() {}\n\n//# sourceURL=webpack:///./src/test2.js?");
      })
    }
  ]
);

The amount of code packaged this time is a little inflated,bundle.jsThere are 200 lines of code. Let’s take a look at the differences from the synchronously loaded webpack module specification:

  1. An object is definedinstalledChunks, which is used to cache dynamic modules.
  2. Defines an auxiliary functionjsonpScriptSrc(), which is used to generate URL based on module ID.
  3. Two new core functions are defined__webpack_require__.e()andwebpackJsonpCallback()
  4. Defines a global variablewindow["webpackJsonp"] = [], it is used to store modules that need to be imported dynamically.
  5. rewritewindow["webpackJsonp"]Arraypush()Method iswebpackJsonpCallback()。 in other wordswindow["webpackJsonp"].push()In fact, the implementation iswebpackJsonpCallback()

And from0.bundle.jsThe file can be found that it is usedwindow["webpackJsonp"].push()To put into the dynamic module. The dynamic module data item has two values. The first is[0], which is the ID of the module; The second value is the module pathname and module content.

Then let’s take a look at the code of the packaged entry module. After beautification:

function test() {}
test()
__webpack_require__.e(0).then(__webpack_require__.bind(null, "./src/test2.js"))
//# sourceURL=webpack:///./src/index.js?

In the original module codeimport('./test2')Translated into__webpack_require__.e(0).then(__webpack_require__.bind(null, "./src/test2.js"))

that__webpack_require__.e()What is the role of?

__webpack_require__.e()

__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);
};

Its processing logic is as follows:

  1. First check whether the cached value corresponding to the module ID is 0. 0 means that the module has been loaded successfully. The first value isundefined
  2. If not 0 and notundefinedRepresents the state that is already loading. Then push the promise in the loadpromisesArray.
  3. If not 0 and yesundefinedCreate a promise to load modules that need to be imported dynamically.
  4. Generate ascriptTags, URL usagejsonpScriptSrc(chunkId)Generate, that is, the URL of the module needs to be dynamically imported.
  5. For thisscriptThe tag sets a 2-minute timeout and sets aonScriptComplete()Function to handle timeout errors.
  6. Then add to the pagedocument.head.appendChild(script), start loading the module.
  7. returnpromisesArray.

When the JS file is downloaded, the file content will be executed automatically. That is to say, after downloading0.bundle.jsAfter, it will be executedwindow["webpackJsonp"].push()

becausewindow["webpackJsonp"].push()Has been reset towebpackJsonpCallback()Function. So this operation is executionwebpackJsonpCallback(), let’s seewebpackJsonpCallback()What did you do.

webpackJsonpCallback()

Execute the promise corresponding to the module IDresolve()At the same time, set the value in the cache object to 0, indicating that the loading has been completed. Compared to__webpack_require__.e(), this function is quite understandable.

Summary

In general, the logic of dynamic import is as follows:

  1. rewritewindow["webpackJsonp"].push()method.
  2. Access module usage__webpack_require__.e()Download dynamic resources.
  3. Execute after resource downloadwindow["webpackJsonp"].push(), i.ewebpackJsonpCallback()
  4. Identifying the resource as 0 means that the load is complete. Since the load module uses promise, it needs to be executedresolve()
  5. Take another look at the loading code of the entry module__webpack_require__.e(0).then(__webpack_require__.bind(null, "./src/test2.js")), execute after downloadingthen()Method, calling__webpack_require__()Really start loading code,__webpack_require__()It has been explained above. If you don’t understand it, it is recommended to read it again.

Please pay attention to more articles

Recommended Today

Implementation example of go operation etcd

etcdIt is an open-source, distributed key value pair data storage system, which provides shared configuration, service registration and discovery. This paper mainly introduces the installation and use of etcd. Etcdetcd introduction etcdIt is an open source and highly available distributed key value storage system developed with go language, which can be used to configure sharing […]