Webpack learning - how it works

Following the last chapter Article This paper introduces the basic concept of webpack, the whole process, and the function of some events broadcast in...
Synchronous loading
Asynchronous loading
summary

Following the last chapter Article This paper introduces the basic concept of webpack, the whole process, and the function of some events broadcast in the process of packaging. This article mainly talks about how to output the generated chunk file into a specific file. There are two cases of synchronous and asynchronous to analyze the output file using the webpack version: 3.8.0.

Module file show.js

function show(content) { window.document.getElementById('app').innerText = 'Hello,' + content; } // Export show function through CommonJS specification module.exports = show;

Synchronous loading

// main.js import show from './show'; show('TWENTY-FOUR K');

Generated bundle file

// Webbackbootstrap startup function // Modules store an array of all modules. Each module is a function (function(modules) { var installedModules = {}; // Cache installed modules to improve performance //Load the module corresponding to moduleId (index) in the modules array passed in, similar to node's require statement function __webpack_require__(moduleId) { // Check whether it has been loaded, if any, take it directly from the cache installedModules if(installedModules[moduleId]) { return installedModules[moduleId].exports; } // If not, create a new module directly and store it in the cache installedModules var module = installedModules[moduleId] = { i: moduleId, // index corresponding to modules, that is, moduleId l: false, // Flag module loaded exports: {} }; // Execute the corresponding module function and pass in the required parameters modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Set flag to true module.l = true; // Return the export value of this module return module.exports; } // Store modules array __webpack_require__.m = modules; // Storage cache installedModules __webpack_require__.c = installedModules; // Define getter function for Harmony export __webpack_require__.d = function(exports, name, getter) { if(!__webpack_require__.o(exports, name)) { Object.defineProperty(exports, name, { configurable: false, enumerable: true, get: getter }); } }; // It is used for getdefaultexport function that is compatible with uncoordinated modules. It declares module.default or non module as a property of getter 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; }; // Tool function, hasOwnProperty __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; // publicPath in the webpack configuration, used to load the separated asynchronous code __webpack_require__.p = ""; // Use the "webpack" require "function to load the module with index 0, and return the module with index 0, which is the corresponding file of main.js of the main entry file. The meaning of" webpack "require" is the corresponding index of the startup module return __webpack_require__(__webpack_require__.s = 0); }) /************************************************************************/ ([ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; // Set "esModule" to true to affect the return value of "webpack" require ". N function Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); // Load the dependent module with index 1 synchronously /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__show__ = __webpack_require__(1); // Get the export of the dependent module with index 1 /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__show___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__show__); // Synchronous loading __WEBPACK_IMPORTED_MODULE_0__show___default()('wushaobin'); /***/ }), /* 1 */ /***/ (function(module, exports) { function show(content) { window.document.getElementById('app').innerText = 'Hello,' + content; } // Export show function through CommonJS specification module.exports = show; /***/ }) ]);

Asynchronous loading

// main.js // Load show.js asynchronously import('./show').then((show) => { // Execute show function show('TWENTY-FOUR K'); });

Two files, 0.bundle.js and bundle.js, will be generated after the web pack. The reason for this is that show.js can be introduced in the form of asynchronous loading, which is also an optimization method to separate the code and reduce the file volume. The analysis of the two files is as follows.

0.bundle.js

// Load the modules contained in this file (0.bundle.js). Webbackjsonp is used to install modules from asynchronous loaded files and mount them to global (bundle.js) for other files webpackJsonp( // Module id stored in other files [0],[ // Modules included in this document /***/ (function(module, exports) { function show(content) { window.document.getElementById('app').innerText = 'Hello,' + content; } // Export show function through CommonJS specification module.exports = show; /***/ }) ]);

bundle.js

(function(modules) { // Webbackbootstrap startup function // Install JSONP callback for block loading var parentJsonpFunction = window["webpackJsonp"]; // chunkIds the chunkId corresponding to the module to be installed stored in the asynchronous load file (0.bundle.js) // The moreModules asynchronous load file (0.bundle.js) holds the list of modules to be installed // The executeModules asynchronous load file (0.bundle.js) stores the index corresponding to the modules to be installed and executed after installation window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { // Add "moreModules" to the modules object, // Mark all modules corresponding to chunkIds as loaded successfully var moduleId, chunkId, i = 0, resolves = [], result; for(;i < chunkIds.length; i++) { chunkId = chunkIds[i]; if(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(chunkIds, moreModules, executeModules); // implement while(resolves.length) { resolves.shift()(); } }; // Cache installed modules var installedModules = {}; // Store the loading status of each chunk // The key is the id of chunk, and a value of 0 means the loading is successful var installedChunks = { 1: 0 }; // Load the module corresponding to the moduleId (index) in the modules array passed in. It is similar to the node's require statement, as above. It is omitted here function __webpack_require__(moduleId) { ... } // It is used to load the file corresponding to the chunk to be loaded asynchronously, // The chunk id needs the id corresponding to the chunks loaded asynchronously. A promise is returned __webpack_require__.e = function requireEnsure(chunkId) { // Get the loading status of the chunk file corresponding to the chunkId from installedChunks var installedChunkData = installedChunks[chunkId]; // If the loading status is 0, it means that the chunk has been loaded successfully, and the promise resolve is returned directly if(installedChunkData === 0) { return new Promise(function(resolve) { resolve(); }); } // When installedChunkData is not empty and 0, it means that chunk is loading on the network if(installedChunkData) { return installedChunkData[2]; } // If the installedChunkData is empty, it means that the chunk has not been loaded. Load the file corresponding to the chunk var promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; }); installedChunkData[2] = promise; // Through dom operation, insert a script tag into html head to load the javascript file corresponding to chunk asynchronously var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = "text/javascript"; script.charset = 'utf-8'; script.async = true; script.timeout = 120000; // The nonce property of the HTMLElement interface returns the encrypted number that is used only once, and is used by the content security policy to determine whether the request is allowed to be processed. if (__webpack_require__.nc) { script.setAttribute("nonce", __webpack_require__.nc); } // The path of the file is spliced by the configured publicPath and chunkid script.src = __webpack_require__.p + "" + chunkId + ".bundle.js"; // Set the maximum timeout for asynchronous loading var timeout = setTimeout(onScriptComplete, 120000); script.onerror = script.onload = onScriptComplete; // Callback when script loading and execution are complete function onScriptComplete() { // Prevent memory leaks script.onerror = script.onload = null; clearTimeout(timeout); var chunk = installedChunks[chunkId]; // Judge whether the chunk corresponding to chunkid is installed successfully if(chunk !== 0) { if(chunk) { chunk[1](new Error('Loading chunk ' + chunkId + ' failed.')); } installedChunks[chunkId] = undefined; } }; head.appendChild(script); return promise; }; // Multiple properties and methods will be set for webpack require, as above, omitted here // Error functions loaded asynchronously __webpack_require__.oe = function(err) { console.error(err); throw err; }; // Load entry module and return exports return __webpack_require__(__webpack_require__.s = 0); }) /************************************************************************/ ([ // Store the modules that are not loaded asynchronously and loaded with the execution of the entry file, that is, the synchronized modules /* 0 */ /***/ (function(module, exports, __webpack_require__) { // Load the chunk corresponding to show.js asynchronously through "webpack" and "require" // Load show.js asynchronously __webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, 1)).then((show) => { // Execute show function show('Webpack'); }); /***/ }) ]);

summary

Here we compare the simple application of synchronous loading and asynchronous loading to analyze the differences between the two cases. We find that the asynchronous loading bundle.js is basically similar to the synchronous bundle.js, which simulates the node.js's require statement to import the module. The difference is that there is an additional \\\\\\\ The files corresponding to the chunk s that need to be loaded asynchronously, as well as a wepackJsonp function, are used to install modules from the asynchronously loaded files.

4 December 2019, 00:32 | Views: 2241

Add new comment

For adding a comment, please log in
or create account

0 comments