Analyze Webpack-Packaged code

Source: Internet
Author: User
Tags hasownproperty

Written in front of

1. Release Notes

Webpack version 3.0.0 is used.

2. Webpack's core ideas

    • Everything "module"
    • Load on Demand

First, start

1. Preparation

Currently only one file is created, Index.js, as the entry file, the code is as follows.

Console.log (' Hello, world ');

Then use Webpack to package and execute the following commands.

Webpack Index.js Index.bundle.js

2. Analysis

A bunch of code generated by a packaged file is actually a self-executing function that passes only one parameter to modules, and that object is an array.

(function  (modules) {    //  ...}) ([function  (module, exports) {    function  SayHello () {        console.log (' Hello ');    }}])

The function is to manage the module, which internally defines two main object Installedmodules objects and __webpack_require__ (ModuleID) function objects.

The Installedmodules object initialization code is as follows.

var installedmodules = {};

Take a look at the definition of the function object __webpack_require__, which works the same as the Require function.

//Require function
function__webapck_require__ (ModuleID) {
If the module is in the cacheif(Installedmodules[moduleid]) {returnInstalledmodules[moduleid].exports; }
Create a new module (and put it in the cache)varmodule = Installedmodules[moduleid] ={I:moduleid, L:false,//L is the abbreviation for loaded, whether it has been loadedExports: {}};
Function of the Execution module Modules[moduleid].call (module.exports, module, Module.exports, __webpack_require__);
Tag module already loaded MODULE.L=true;
Returns the exports object of the modulereturnModule.exports; }

See here, we can see that the Installedmodules object is actually used as a dictionary, key is the module's id,value is a module state and export an object, as follows.

{    //  module ID    false//  L is an abbreviation for loaded, whether the reference is already loaded    //  Export Object of the module }

__WEBPACK_REQUIRE__ is also defined by a number of static and static methods.

//Speaker Modules Object (__webpack_modules__)__WEBPACK_REQUIRE__.M =modules;//cache of the speaker module__WEBPACK_REQUIRE__.C =Installedmodules;//Define getter functions to load modules with friendliness__WEBPACK_REQUIRE__.D =function(exports, name, getter) {if(!__WEBPACK_REQUIRE__.O (exports, name)) {Object.defineproperty (exports, name, {configurable:false, Enumerable:true, get:getter}); }};
__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) {Object.prototype.hasOwnProperty.call (object);};

__webpack_public_path__
__WEBPACK_REQUIRE__.P = "";

At the end of the function, the result is a module that imports ModuleID = 0, which is the execution of a portal file.

return __webpack_require__ (__webpack_require__.s = 0);

The contents of the portal file that you defined are converted to.

(function  (module, __webpack_exports__, __webpack_require__) {    console.log (' Hello, world! '); });

The arguments passed in an immediate function expression are an array object, and the entry file converts the function to the first element in the group. Note Webpack added comments/* 0 */ModuleID for this module is 0, and Webpack actually considers each resource file as a module and assigns it an identity moduleid.

[/** *(function(module, __webpack_exports__, __webpack _require__) {    //  ... })]

Second, add dependency

1. Preparation

Add a new JS file named Util.js and the code is as follows.

(A, B) {
return a + b;}

The entry file Index.js code is modified as follows.

Import util from './util.js 'console.log (' 1 + 2 = ' + Util.add (1, 2));

Execute the previous command and use the Webpack build tool to package.

2. Analysis

Now look at the code under Index.bundle.js, and then the incoming parameters of the generated immediate execution function change, remember that the argument is an array, and the array is as follows.

[/*0*/(function(module, __webpack_exports__, __webpack_require__) {"Use Strict"; Object.defineproperty (__webpack_exports__,"__esmodule", {value:true }); /*Harmony Import*/ var__webpack_imported_module_0__util_js__ = __webpack_require__ (1); Console.log (' 1 + 2 = ' + __webpack_imported_module_0__util_js__["a"/*default*/].add (1 + 2));}),/*1*/(function(module, __webpack_exports__, __webpack_require__) {"Use Strict";
Object.defineproperty (__webpack_exports__, "__esmodule", {value:true}); /*Harmony Default Export*/__webpack_exports__["Add" = add;
function(A, b) {returnA +b; }})]

As can be seen, webpack each file as a separate module, which analyzes the dependencies between modules and replaces the import export related content in the module, for example.

Import b from './b'default  {    ' C '  }//  last converted to var __webpack_imported_module_0_b__ = __webpack_require__ (0)//  There is a special need to note that WEBPACK will property as the default value of a block __webpack_exports__["a"] = (    {' C '})

Add a wrapper function outside all modules, make it a module initialization function, and then synthesize all the module initialization functions into an array and assign the value to the modules variable.

Iii. Dynamic import of modules

1. Preparation

The code to modify the portal file Index.js is as follows.

Import ('./util.js '). Then (function  (util) {    console.log (' 1 + 2 = ' + util.add (1 + 2));})

Execute the previous command and use the Webpack build tool to package.

2. Analysis

After this package not only acquired the Index.bundle.js file, but also produced a 0.index.bundle.js file, the next analysis o.index.bundle.js.

WEBPACKJSONP ([0],[/*0*/,/*1*//***/(function(module, __webpack_exports__, __webpack_require__) {"Use Strict"; Object.defineproperty (__webpack_exports__,"__esmodule", {value:true });/*Harmony Export (immutable)*/__webpack_exports__["Add"] =add;functionAdd (A, b) {returnA +b;}/***/ })]);

You can then see that the block code is loaded in JSONP form, where it can be seen that the code is executed immediately after loading the Webpackjsonp method, which is a new method in Index.bundle.js. Before looking at this method, take a look at one of the new objects in Index.bundle.js.

var installedchunks = {    1:0}; 

The object records the installation state of the chunk and does not log chunk-related content, which is still saved to the Installedmodules object. Installedchunks is also used as a dictionary, key is the ID of chunk (here to note the difference with Mouleid, each chunk will have at least one module), value can be 0 (loaded), [Resolve, Reject ] (loading), undefined (not loaded), you can see the change in this state in the Requireensure (Chunkid) method.

__WEBPACK_REQUIRE__.E = functionRequireensure (chunkid) {var installedchunkdata =Installedchunks[chunkid]; if (installedchunkdata = = = 0) {return new Promise (function(resolve)    {resolve ();}); }//A Promise means "loading" if(Installedchunkdata) {return installedchunkdata[2]; } var promise = new Promise (function(Resolve, Reject) {Installedchunkdata = Installedchunks[chunkid] =[Resolve, Reject]; }); INSTALLEDCHUNKDATA[2] =Promise 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 ; if  (__WEBPACK_REQUIRE__.NC) {Script.setattribute ("nonce" , __WEBPACK_REQUIRE__.NC);} script.src = __WEBPACK_REQUIRE__.P + "" + ({}[chunkid]| | Chunkid) + ". Bundle.js" ; var timeout = setTimeout (onscriptcomplete, 120000 ); script.onerror = Script.onload =  onscriptcomplete; function  Onscriptcomplete () {//Avoid mem leaks in IE. script.onerror = Script.onload = Nu ll ; cleartimeout (timeout); var chunk =  Installedchunks[chunkid]; if (chunk!== 0 ) {if  (chunk) {Chu NK[1] (New Error (' Loading chunk ' + Chunkid + ' failed. ') )); } Installedchunks[chunkid] =  undefined;}}; Head.appendchild (script); return  promise;};               

Finally, look at the WEBPACKJSONP function, as follows.

varParentjsonpfunction = window["Webpackjsonp"];window["Webpackjsonp"] =functionWebpackjsonpcallback (Chunkids, Moremodules, executemodules) {//Add "Moremodules" to modules object    //then all the "Chunkids" have been loaded and called callback    varModuleID, 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(ModuleIDinchmoremodules) {        if(Object.prototype.hasOwnProperty.call (Moremodules, ModuleID)) {Modules[moduleid]=Moremodules[moduleid]; }    }    if(parentjsonfunction) parentjsonpfunction (Chunkids, Moremodules, executemodules);  while(resolves.length) {resolves.shift () ();            }}; 

The method has three parameters, Chunkids for the module's first chunk,moremodules for the newly added module, Executemodules temporarily do not know its role. This method first to the loading of the antecedent chunk processing, also remember? The value of the object being loaded chunk represents its state is [Resolve, reject], where their resolve method is saved to the locally defined resolves array. Remember the Modules object, which is the webpack of the outermost generation that executes the function immediately, and continues to install Moremodules into the Modules object. Finally, the resolve method saved in the resolves array is executed.

It is visible that the module is loaded asynchronously using Promise to wrap the chunk file required by the JSONP request, and then add it to the modules parameter, followed by the same call as the synchronized step.

Analyze Webpack-Packaged code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.