Analysis of the core idea of webpack

Time:2022-6-9

Analysis of the core idea of webpack

We have been thinking about writing a construction tool, but before that, let’s try to sort out the concept of webpack. After all, it is a stone of the mountain that can be used to attack jade, which helps us figure out how to design our own projects.

brief introduction

Webpack is a static module bundler for modern JavaScript applications.
This is an introduction to webpack. In essence, it is a packer. Package JS modules into one or more. Implement the capabilities in the following code:

a.js + b.js + c.js. => bundle.js

The reasons for the appearance of packers are not discussed here. There are many articles on the Internet. Next, let’s talk about the core idea of webpack packaging multiple JS files into a bundle file.

Push back the core process from the construction product

Webpack is a huge system. If you analyze the process from beginning to end from the perspective of source code, it will be too complex and unnecessary. After all, we mainly study the core design concept.
Then, we can try to deduce the process from the results and analyze the webpack idea from the packaged code.
Under the configuration of mode: ‘none’, devtool: ‘soap source map’, we can see that the packaged code looks like this:

(function webpackUniversalModuleDefinition(root, factory) {
  if(typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if(typeof define === 'function' && define.amd)
    define([], factory);
  else if(typeof exports === 'object')
    exports["Magotan"] = factory();
  else
    root["Magotan"] = factory();
})(window, function(){
    return (function(modules){
        // xxxx    
    })([
        //xxxx
    ])['default']
})

It is obvious that this is an Iife. To simplify it, add the specific implementation code, and it will be as follows:

(function webpackUniversalModuleDefinition() {
  exports["Magotan"] = (function (modules) {
    function __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;
    }
    return __webpack_require__(0);
  })([ 
    /*0 * // / module array list the index of the array is the module ID 
    (function (module, __webpack_exports__, __webpack_require__) {
      __webpack_exports__["default"] = ({
        getInstance: function getInstance() {
          if (magotan === null) {
            Throw new error ('instance not initialized, please initialize through config first ');
          }
          return magotan;
        },
    }),
    /* 1 */
    (function (module, exports, __webpack_require__) {
      var toObject = __webpack_require__(2);
      var $keys = __webpack_require__(4);
      __webpack_require__(21)('keys', function () {
        return function keys(it) {
          return $keys(toObject(it));
        };
      });
    }),
  // ...
});
  ])['default'];
})()

From the above code, we can see that we store the codes and dependencies of all modules used in the project in an array of modules, and then recursively execute modules from the entry file, that is, the module with id = 0, through the webpack customized require method.

So far, we can analyze that the core process of webpack is two steps

  1. Recursive parsing of output dependency graphs in the reslove modules phase
  2. In the bundle stage, the products of the previous stage are assembled into arrays and wrapped with functions, which are executed recursively from the entry file

    follow-up

    After clarifying the design idea of webpack, more problems are about the specific implementation, such as how to get the relationship between modules (using AST), how to ensure that there is no circular reference (using installedmodules object), and so on. More details will be introduced in subsequent documents.

Recommended Today

CommunityToolkit.Mvvm-IOC

CommunityToolkit.Mvvm does not have IOC built in, you can use Microsoft.Extensions.DependencyInjection. Register ViewModel and other services in App public partial class App : Application { public App() { Services = ConfigureServices(); this.InitializeComponent(); } public new static App Current => (App)Application.Current; public IServiceProvider Services { get; } private IServiceProvider ConfigureServices() { var sc = new ServiceCollection(); […]