18_webpack code separation

What is code separation

Code Splitting is a very important feature of webpack s

His main purpose is to separate the code into bundle s, and then we can load them on demand or in parallel

For example, by default, all JS code (business code, third-party dependencies, showing unused modules) is loaded on the first page
This will affect the loading speed of the first page

Code separation can separate out smaller bundle s, control resource load priority, and provide code load performance

There are three types of code separation commonly used in webpack s
Entry Start: Manual code separation using entry configuration
Prevent duplication: Remove and separate code using Entry Dependencies or SplitChunks Plugin
Dynamic Import: Separate code by inline function calls to modules

 

Entry Dependencies

 

Entry manual code separation

 entry: {
    main: "./src/main.js",
    index: "./src/index.js",
  },
  output: {
    path: resolveApp("./build"),
    filename: "[name].bundle.js",
  },

But this has its drawbacks

For example: I am in main.js introduced the lodash library at index.js also introduced the lodash library, so the webpack's index after packaging. JS has a lodash, main. There is also one lodash in js, which is equivalent to two lodashs being generated

We don't want to package third-party dependencies in every js file that references third-party dependencies after packaging, so we need to separate third-party code at this point

 entry: {
                      //It can also be written as an array main: { import:
"./src/main.js", dependOn: "lodash" }, index: { import: "./src/index.js", dependOn: "lodash" }, lodash: "lodash", },

At this point, lodash will generate a separate js file, and the webpack will load lodash modularily

If we need to separate dayjs when I introduce the third-party libraries for dayjs in the main and index files, how do we set it up?
We can do this:

  entry: {
    main: { import: "./src/main.js", dependOn: ["lodash", "dayjs"] },
    index: { import: "./src/index.js", dependOn: ["lodash", "dayjs"] },
    lodash: "lodash",
    dayjs: "dayjs",
  },

It can also be set as follows:

  entry: {
    //They can add one if their two dependent libraries are the same shared attribute
    main: { import: "./src/main.js", dependOn: "shared" },
    index: { import: "./src/index.js", dependOn: "shared" },
    shared: ["lodash", "dayjs"],
  },

 

When we build, a LICENSE will be generated for us. Txt file, so how do we get rid of it?

const TerserPlugin = require("terser-webpack-plugin");

// and entry Peer
optimization: {
    minimizer: [
      new TerserPlugin({
        extractComments: false,
      }),
    ],
  },

 

 

Split Chunks

It is implemented using SplitChunks Plugin

Because the plug-in webpack is already installed and integrated by default, we do not need to install it separately, use it directly

All you need to do is provide configuration information about SplitChunks Plugin

The webpack provides the default configuration of SplitChunks Plugin, which we can also modify manually:

For example, in the default configuration where chunks is only for async requests, we can set it to initial or all

 

For example: we use import statements to import dayjs and lodash, which are equivalent to synchronization, so the plug-in will not separate him at all, so we need to modify the chunks value in them

require() and import() are asynchronously loaded js files, so the plug-in separates the imported js code

  optimization: {
    minimizer: [
      new TerserPlugin({
        extractComments: false,
      }),
    ],
    splitChunks: {
      // async: require,import function
      // initial: Synchronous imports such as:import Sentence
      // all: asynchronous/Synchronization is supported
      chunks: "all",
    },
  },

You will find that we have generated an XXX (number) in our build folder. bundle.js file, you've already separated the code

 

Because all our separation is done using SplitChunks Plugin, we need to understand its configuration

   splitChunks: {
      // async: require,import function
      // initial: Synchronous imports such as:import Sentence
      // all: asynchronous/Synchronization is supported
      chunks: "all",
      // Minimum value: Default value is: 20000 kb,If we split a package, then the smallest size of the split package is minSize,Don't split if you can't
      // minSize Priority is greater than maxSize Priority
      minSize: 2000,
      // Will be greater than maxSize The package split into no less than minSize Of the package,
      maxSize: 2000,
      // minChunks Represents an imported package, introduced at least once
      minChunks: 1,
      // Cache group: b Package matching files into vendors in
      // Put from node_modules Code for folder(Third Party Library)pack into vendors in
      // When matched lodash Do not do an output immediately, cache it first, and use it together when all matches are loaded filename Make an output with a named name
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          filename: "[id]_vendors.js",
          //Priority, if vendors and default If it's all satisfied, it will take precedence default
          priority: -20,
        },
        /* bar: {
          test: /bar_/,
          filename: "[id]_bar.js",
        }, */
        default: {
          //If a file is referenced twice, it is packaged into a separate file
          minChunks: 2,
          filename: "common_[id].js",
          //Priority is generally negative
          priority: -10,
        },
      },
    },

These configurations don't normally need to be configured, just use the default.

 

Dynamic import

Another code splitting is dynamic import, where webpack provides two ways to implement dynamic import
Using the import() syntax in ECMAScript is also currently recommended
Use the required left over from the webpack. Ensure, currently not recommended

Four files are packaged synchronously in vue
1.main.bundle.js
2.vendors_chunks.js
3.common_chunks.js
4.runtime.js

Whenever code is imported asynchronously, the webpack separates the code
No matter what your splitChunksPlugin settings are, the webpack will separate the asynchronously imported code
 
When we import dynamically using the import() function, a [id] is generated in the packaged folder. Bundle. JS
Where did the packaged file name come from?
By default, if you don't tell him what the packaged file is called, it will be based on output.filename for naming, but here the filename is set to [name].bundle.js, why is my name a number, where does it come from, and one of the attributes it comes from optimization is chunkIds, and he's here
 

optimization.chunkIds Configuration

Optimization | webpack

Optimization. The chunkIds configuration tells the webpack module what algorithm to use to generate its id

boolean = false string: 'natural' | 'named' | 'size' | 'total-size' | 'deterministic'
 
Natural: Using natural numbers, not recommended, is not good for browser caching, if my corresponding A.js is 1_vendors.js b.js is 2_vendors.js, then I deleted a.js, next time I pack it, 1_vendors.js corresponds to b.js
 
named: Use the directory where the package is located as name (recommended for development environments)
 
deterministic: generate id, for the same file, the generated ID is unchanged (default)
 
 
Normally our asynchronous code is not called xxx.bundle.js, should be xxx.cunk.js, so how do I set it up?
  output: {
    path: resolveApp("./build"),
    filename: "[name].bundle.js",
    chunkFilename: "[name].chunk.js",
  },
But we even set [name].chunk.js, then the file it generates is id.chunk.js so what to do?
We can use our magic comments

Tags: Webpack

Posted by garyb_44 on Tue, 03 May 2022 00:06:08 +0300