The preface

In fact, many people will be asked about webpack optimization in the interview, whether it is to build or pack loading, maybe we can not do without DllPlugin, maybe many people are familiar with DllPlugin, but many people don’t know DllPlugin at all. Whether we have seen it before or not, let’s take a look at what the DllPlugin does for us.

instructions

In fact, we are the DLL packaging results and webpack packaging results are analyzed, not webpack into DLL packaging analysis, please remember!!

What does the DllPlugin do?

For example, we used vUE/vue-Router/vuex to write the project. Although we only wrote 5K of code, the package result was 200K. What’s going on here?? In fact, the vUE and other files are packaged into the main file. If we want to speed up loading and need to separate common files, then the opportunity for the plugin DllPlugin is here.

  • Take a look at the definition of DllPlugin

The use of DllPlugin

1. Run the project structure

Comrades!! This is the directory structure of our test demo, and the code will be pasted out again and again. If you are interested, you can run it yourself

1. Webpack.dll.config.js configuration implementation

const path = require('path')
const { DllPlugin } = require('webpack')

const pathResolve = (url) = > path.resolve(__dirname, url)

module.exports = {
  mode: 'development'.entry: {
    utils: ['isarray'.'is-promise']},output: {
    path: pathResolve('.. /dist'),
    filename: 'utils.dll.js'.library: '_dll_utils'
  },
  plugins: [
    new DllPlugin({
      name: '_dll_utils'.path: path.join(__dirname, '.. /dist'.'utils.manifest.json')]}})Copy the code
  • The above code is a simple configuration of the DllPlugin, and we will focus on the following points:
    • output.libraryAs well asnew DllPlugin().nameYou have to be consistent. Because the generated files rely on this for association, as for what this is?? We’ll talk about that later in the packaging analysis
    • Following the above configuration we will generate two filesutils.dll.jsAs well asutils.manifest.json.
    • For more information about plug-ins, see DllPlugin for details

2. Webpack.config. js configuration implementation

const path = require('path')
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

const pathResolve = (url) = > path.resolve(__dirname, url)

module.exports = {
  mode: 'development'.devtool: false.entry: pathResolve('.. /src/index.js'),
  output: {
    path: pathResolve('.. /dist'),
    filename: 'bundle.js'
  },
  plugins: [
    new DllReferencePlugin({
      manifest: require('.. /dist/utils.manifest.json')}),new HtmlWebpackPlugin({
      template: pathResolve('.. /public/index.html')]}})Copy the code
  • The code above is the compiled configuration file, which is relatively simple here. Our main focus is on plug-insDllReferencePluginIn the. The rest are sparse and ordinary

SRC /index.js code implementation

let isarray = require('isarray')
console.log('isarray([1, 2, 3])=', isarray([1.2.3]))
Copy the code

4. Package. Json configuration

{
  "scripts": {
    "dll": "webpack --config build/webpack.dll.config.js"."build": "webpack --config build/webpack.config.js"}}Copy the code

Analysis of compilation results

1. Compile the result directory

2. Code analysis of utils.dlL. js

// The exposed global variable package content will be globally mounted here
var _dll_utils;

// The outermost layer of IIFE
(() = > {
  var __webpack_modules__ = {
    "./node_modules/isarray/index.js": (module) = > {
      eval(
        "var toString = {}.toString; \n\nmodule.exports = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]'; \n}; \n\n\n//# sourceURL=webpack://_dll_utils/./node_modules/isarray/index.js?"
      );
    },

    "? 2e89": (module, __unused_webpack_exports, __webpack_require__) = > {
      eval(
        "module.exports = __webpack_require__; \n\n//# sourceURL=webpack://_dll_utils/dll_utils?"
      );
    },

    "./node_modules/is-promise/index.mjs": (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) = > {
      "use strict";
      eval(
        "__webpack_require__.r(__webpack_exports__); \n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "default": () => (/* binding */ isPromise)\n/* harmony export */ }); \nfunction isPromise(obj) {\n return !! obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; \n}\n\n\n//# sourceURL=webpack://_dll_utils/./node_modules/is-promise/index.mjs?"); }};var __webpack_module_cache__ = {};

  // Load the module method
  function __webpack_require__(moduleId) {
    // Get and judge the cache
    var cachedModule = __webpack_module_cache__[moduleId];
    if(cachedModule ! = =undefined) {
      return cachedModule.exports;
    }
    var module = (__webpack_module_cache__[moduleId] = {
      exports: {},});// Start loading modules
    __webpack_modules__[moduleId](module.module.exports, __webpack_require__);

    return module.exports;
  }
  var __webpack_exports__ = __webpack_require__("? 2e89"); _dll_utils = __webpack_exports__; }) ();Copy the code
  • The above code has corresponding comments, please read carefully, but it doesn’t matter if you don’t read, we will parse one by one:
    • The first thing you see is codevar _dll_utilsThis variable is configured in webpack.dll.config.js. After the code is compiled, it’s actually put globally, as a global variable
    • codevar __webpack_exports__ = __webpack_require__("? 2e89"); _dll_utils = __webpack_exports__;Is the entry point to execute the file. Webpack gives the entry a random value, in this case (? 2e89). Start loading the module
      • The above description is not pasted code, but in the way of screenshots, mainly for fear of incomplete, can not be linked before and after.
      • See the codemodule.exports = __webpack_require__;Essentially, the function (__webpack_require__) assigned to the _dll_utils global variable. So far, the _dll_utils variable is the global load function

3. Bandle.js code analysis

// The outermost layer IIFE
(() = > {
  // Module method
  var __webpack_modules__ = {
    B / / modules
    "./node_modules/isarray/index.js": (
      module,
      __unused_webpack_exports,
      __webpack_require__
    ) = > {

      < dL-reference _dll_utils>
      module.exports = __webpack_require__("dll-reference _dll_utils") ("./node_modules/isarray/index.js"
      );
    },

    "dll-reference _dll_utils": (module) = > {
      "use strict";
      module.exports = _dll_utils; }};var __webpack_module_cache__ = {};

  // Load the module
  function __webpack_require__(moduleId) {
    // Check whether the module exists
    var cachedModule = __webpack_module_cache__[moduleId];
    if(cachedModule ! = =undefined) {
      return cachedModule.exports;
    }


    var module = (__webpack_module_cache__[moduleId] = {
      exports: {},});// Load the execution module
    __webpack_modules__[moduleId](module.module.exports, __webpack_require__);

    return module.exports;
  }

  var __webpack_exports__ = {};

  // Execute the function entry
  (() = > {

    // Load the module 
      
    let isarray = __webpack_require__("./node_modules/isarray/index.js");
    console.log("isarray([1, 2, 3])=", isarray([1.2.3])); }) (); }) ();Copy the code
  • The code above is the result of webPack compilation, but with appropriate cuts, here is the entry:
    • let isarray = __webpack_require__("./node_modules/isarray/index.js");The code on the left is the entry to the entire file, starting to load the module
      • When we load the module./node_modules/isarray/index.jsIs executed in the screenshot aboveSecond frameThe place where
      • Remember our analysis of _dll_utils above?? In this case _dll_utils is actually a module loading function, and the loaded module is shown above./node_modules/isarray/index.jsThis module.

Optimization:

  • After so much analysis, I believe you also have a certain understanding of this. Here we can talk about the optimization of DllPlugin (*.dll. Js after packaging) :
    • We can put the file (*.dl.js) on the server, but we can use strong caching. We can use strong caching because once we have successfully packaged the DLL files, it means that the files are very unlikely to change. But you always have to load it once. What about the first time?
    • We can import files as CDN, use CDN to speed up loading, and there are many strategies. For example, preload. Preloading, packaging compression, etc. Keep packages as small and fast as possible
    • For example, in our actual production process, vUE/VUe-Router/vuex/ Element-plus/loadsh are packaged. Can be accelerated at the request, the speed can be imagined!!!!!

At the end

Well, that’s all for the crap. I hope it helps. If there is something wrong, I hope you can correct it. You said so much nonsense, introduced myself to forget, you see my brain…

  • GitHub
  • Personal blog
  • Exhibition collection of personal works