What will require. Ensure be packaged into?
First, let’s take a look at what webpack looks like when you use Require. ensure in your code
require.ensure([], function () {
let module2 = require("./module2")
console.log(module2)
});
Copy the code
Will be compiled by Webpack like this
// The argument 0 is the id of the code block generated for module2
__webpack_require__.e( / *! require.ensure */ 0)
.then((function () {
let module2 = __webpack_require__( / *! ./module2 */ "./module2.js")
console.log(module2)
})
...// The following code is omitted, mainly doing exception handling
Copy the code
The __webpack_require__. E returns a promise, and the second argument you pass to require.ensure is a promise callback that holds the asynchronously loaded module2
__webpack_require__ is the equivalent of the require method, which takes asynchronously loaded modules, in this case module2
How does require. Ensure implement asynchronous loading? Got the promise?
To put it simply:
// Define a global array object
widow.webpackJsonp = []
// Override the push method of this
webpackJsonp.push = webpackJsonpCallback;
function webpackJsonpCallback(data) {
var chunkIds = data[0];
var moreModules = data[1];
var executeModules = data[2];
var moduleId, chunkId, i = 0,
resolves = [];
for (; i < chunkIds.length; i++) {
chunkId = chunkIds[i];
if (Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
// When a promise is created in __webpack_require__.e,
InstalledChunks [chunkId] = [resolve, reject];
// installedChunks[chunkId][0] is the promise. Resolve method
resolves.push(installedChunks[chunkId][0]);
}
// installedChunks[chunkId] is set to 0 to determine whether the module is successfully loaded.
// script.onload will also be used to determine whether the load failed, and display a message
installedChunks[chunkId] = 0;
}
while(resolves.length) { resolves.shift()(); }... }; __webpack_require__.e =function (chunkId) {
var promises = [];
// Get the current module to be loaded from installedChunks
var installedChunkData = installedChunks[chunkId];
if(installedChunkData ! = =0) { // 0 indicates that the loading is successful
// Create a promise and store resolve and reject in the array
var promise = new Promise(function (resolve, reject) {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
});
promises.push(promise);
// Create a script tag
var script = document.createElement('script');
// Set the request address
script.src = chunkId + ".bundle.js";
// Listen for successful and failed script loading events
script.onerror = script.onload = function (event) {
// Remove the module after loading
var chunk = installedChunks[chunkId];
// If the load succeeds, chunk will be 0
// If the load fails, the user fails to load
if(chunk ! = =0) {
Chunk [1] is actually the reject function of promise
var error = {
message: 'Loading chunk ' + chunkId + ' failed.';
}
chunk[1](error); }};// Tags are inserted into the DOM
document.head.appendChild(script);
}
return Promise.all(promises);
}
Copy the code
Module2. Js after packaging
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0] and {/ * * * / "./module2.js":
/ *! * * * * * * * * * * * * * * * * * * * *! * \! *** ./module2.js ***! \ * * * * * * * * * * * * * * * * * * * * /
/ *! no static exports found */
/ * * * / (function(module.exports) {
eval(Module.exports = function () {\n console.log(' ha ha ha ha ')\n}\n\n//# sourceURL=webpack:///./module2.js?");
/ * * * /}}));Copy the code
Implementation step resolution
- 1 Create a
promise
将[resolve, reject]
depositinstalledChunks[chunkId]
var promise = new Promise(function (resolve, reject) {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
});
Copy the code
- 2 Create a
script
Tag, set itsrc
To load this module for the actual requested address, givescript
Label the bindingonload
Event handler to handle load failures - 3
module2.js
When loaded, it’s actually a callwebpackJsonp
thepush
Method, becausepush
The method is rewritten aswebpackJsonpCallback
; Therefore,push
Called when the method is calledwebpackJsonpCallback
- 4
webpackJsonpCallback
When executed, get the callpush
MethodchunkId
Set the module’s load success status to 0
installedChunks[chunkId] = 0;
Copy the code
- 5 from
installedChunks
Remove thechunkId
Corresponding moduleresolve
Method to retrieve the component after execution
Ensure is used in Vue
const home = r => require.ensure([], () => r(require('.. /page/home/home')), 'home')
Ensure ([], () => resolve(require(‘.. /page/home/home’)), ‘home’)
Why do you write that? Since this is the syntax of vUE asynchronous components, you can see the vUE official website for asynchronous components, as shown below
Vue.component('async-example'.function (resolve, reject) {
setTimeout(function () {
// Pass the component definition to the 'resolve' callback
resolve({
template: '
I am async!
'})},1000)})Copy the code
The then method of the promise returned by require. Ensure calls require(‘.. /page/home/home’) takes the compile result of the home component (the component’s object) and passes the component object as a parameter to the resolve method provided by VUE. Vue takes the definition of the component and can proceed with its component rendering logic