Webpack packaging performance optimization checklist

Time:2021-9-27

speed-measure-webpack-plugin

You can use the speed measure webpack plugin to measure the packaging time

Optimization list

Optimize loader configuration

Since the file conversion operation by the loader is time-consuming, it is necessary to let as few files as possible be processed by the loader.
The file to which the loader applies rules can be hit through the three configuration items test / include / exclude.

Optimize the configuration of resolve.modules

The default value of resolve.modules is [‘node]_ modules’],
It means to go to the node of the current directory first_ Go to the modules directory to find the module we are looking for,
If you can’t find it, go to the next level directory.. / node_ Modules. If you don’t have any more, go to.. /.. / node_ Modules, and so on.

module.exports = {
  resolve: {
    modules: [path.resolve(__dirname, "node modules")]
  }
};

Optimize the configuration of resolve.mainfields

There will be a package.json file in the installed third-party module to describe the properties of the module. There can be multiple field description entry files,
The reason is that some modules can be used in multiple environments at the same time, and different codes need to be used for different running environments.
The default value of resolve.mainfields is related to the current target configuration, and the corresponding relationship is as follows.
When target web or webworker, the value is [‘browser’, ‘module’, ‘main’].
When target is other cases, the value is [‘module’, ‘main’].
Taking target equals web as an example, webpack will first use the browser field in the third-party module to find the module entry file. If it does not exist, it will use the module field, and so on.

module.exports = {
  resolve: {
    //Only the main field is used as the description field of the entry file to reduce the search steps
    mainFields: ["main"]
  }
};

Optimize the resolve.alias configuration

  • One set is modular code using commonjs specification. These files are recorded in lib,
    Take the entry file react.js specified in package.json as the entry of the module
  • One is to package all the relevant codes of react into a single file,
    These codes are not modular and can be executed directly. Dist / react.js is used in the development environment,
    It contains check and warning codes. Dist / react.min.js is used in the online environment and is minimized
module.exports = {
  resolve: {
    //Use alias to replace the imported react statement with a separate and complete react.min.js file,
    //Reduce time-consuming recursive parsing operations
    alias: {
      react: path.resolve(__dirname, "./node_modules/react/dist/react.min.js")
    }
  }
};

Optimize the resolve.extensions configuration

When there is no file suffix in the import statement, webpack will automatically bring the suffix to try to ask whether the file exists

  • The suffix attempt list should be as small as possible. Do not write the impossible situations in the project into the suffix attempt list.
  • The file suffix with the highest frequency should be put first, so as to exit the search process as soon as possible.
  • When writing import statements in the source code, you should bring suffixes as much as possible, so as to avoid the search process. For example, in the case of determination, write require (‘. / data’) as require (‘. / data. JSON’)
module.exports = {
  resolve: {
    //Minimize the possibility of suffix attempts
    extensions: ["js"]
  }
};

Optimize module.noparse configuration

Do not parse when packaging, so as to speed up the packaging speed.

module.exports = {
  module: {
    noParse: /jquery/
  }
};

Using dllplugin

module.exports = {
  // mode: "development || "production",
  plugins: [
    new webpack.DllReferencePlugin({
      context: path.join(__dirname, "..", "dll"),
      manifest: require("../dll/dist/alpha-manifest.json") // eslint-disable-line
    }),
    new webpack.DllReferencePlugin({
      scope: "beta",
      manifest: require("../dll/dist/beta-manifest.json"), // eslint-disable-line
      extensions: [".js", ".jsx"]
    })
  ]
};

webpack5

const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");
const plugins = [new HardSourceWebpackPlugin()];

Using happypack

const HappyPack = require('happypack')
    const os = require('os')
    const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })

    {
        test: /\.js$/,
        // loader: 'babel-loader',
        Loader: 'happypack / loader? Id = happy Babel JS' // add a new happypack build loader
        include: [resolve('src')],
        exclude: /node_modules/,
    }
    
    plugins: [
        new HappyPack({
        id: 'happy-babel-js',
        loaders: ['babel-loader?cacheDirectory=true'],
        threadPool: happyThreadPool
        })
    ]

Using paralleluglifyplugin

Optimize file listening performance

module.export = {
        watchOptions : {
            //Node not listening_ Files in the modules directory
            ignored : /node_modules/,
        }
    }