background

Since the company’s background project is relatively large and takes a long time to build, I think it is a waste of time, so I decided to optimize the idea. Looking at some webPack optimization articles, most of them mention that Webpack 5’s persistent cache greatly improves build speed, and the official message is to keep the V5 version as long as possible. So! Let’s do it! The official version focuses on the following points.

  • Try using persistent caching to improve build performance.
  • Try to improve long-term caching with better algorithms and defaults.
  • Try to improve package sizes with better Tree Shaking and code generation.
  • Try to improve compatibility with web platforms.
  • Try to clean up internal structures that were in a strange state when V4 was implemented without introducing any disruptive changes.
  • Try to prepare for future features by introducing breakthrough changes now to keep them on v5 as long as possible

This upgrade is based on Webpack 4.3.0 upgrade to Webpack 5.54.0 again mention a sentence, this article is completely based on the configuration of our company to optimize, also only on behalf of personal opinion (webpack small white), the article also left some questions, hope you big guys to clarify, not very grateful ~

It is recommended that you also read the migration guide before starting

Upgrade webpack

Start by upgrading the WebPack tool and some base packages to the latest version

npm install --save-dev webpack-cli@latest webpack@latest webpack-merge@latest webpack-dev-server@latest
Copy the code

Webpack 5 requires node.js to be at least 10.13.0 (LTS), so if you’re still using older versions of Node.js, please upgrade them.

loader

file-loader & url-loader

Webpack5 has built-in resource module processing, which can replace the previous file-loader, URL-loader and raw-loader, so you can uninstall these loaders and directly build processing

{
  test: /\.png$/,
  loader: 'url-loader'.options: {
      limit: 10 * 1024.name: 'images/[name].[ext]'}}Copy the code

According to the above configuration, if the image size is larger than 10kb, file-loader is enabled to export the file separately. The configuration of the resource module is as follows

{
  test: /\.png$/,
  type: 'asset'.parser: {
    dataUrlCondition: {
      maxSize: 10 * 1024 // 10kb}},generator: {
    filename: 'images/[name][ext]'}}Copy the code
  • Type: Asset automatically selects between exporting a data URI and sending a separate file. Previously, the urL-loader was used and the resource volume limit was configured.
  • parser:
    • If the value of rule-type is asset, the rules.parser option may be an object or a function that encode the file contents as Base64 or emit them as a separate file to the output directory.
    • If the value of rule-type is asset or asset/inline, the rule-generator option may be an object that describes how the module’s source code is encoded, or it may be a function that encodes the module’s source code through a custom algorithm
  • DataUrlCondition: If a module source size is smaller than maxSize, the module will be injected into the package as a Base64 encoded string, otherwise the module files will be generated to the output target directory
  • Generator. filename: controls file output

vue-loader

Vue-loader used version 15.9.1 before, and the compilation failed all the time, and I also found a lot of information, which was quite embarrassing. Then I guessed whether it was incompatible with Webpack5, and then upgraded vue-Loader version. Indeed, the compilation was successful and 15.9.1 was upgraded to 15.9.8. After the upgrade, I found an error indicating incompatible completion in the page, which was manually modified.

<script>
export default {
    data() {
        return {
            // Globally injected constants via webpack.defineplugin directly report page compilation errorsDOMIN_URL,/ / changed to
            "DOMIN_URL": DOMIN_URL
        }
    }
}
</script>
Copy the code

sass-loader

Sass-loader in the previous project relied on Node Sass, which was very time-consuming. Dart Sass is more recommended by the official. As for why Dart Sass is chosen, you can see the official explanation, which is generally faster and easier to install

npm install --save-dev sass
Copy the code

Dart Sass 2.0.0 uses math.div instead of /, but this warning involves the elemental-ui package and can only be manually degraded to Dart Sass 1.32.13. The recompile warning is gone

DEPRECATION WARNING: Using / for division is deprecated and will be removed in Dart Sass 2.0. 0.

Recommendation: math.div($--tooltip-arrow-size, 2)
Copy the code

babel-loader

I read in an article that esBuild can greatly improve build speed, so I decided to give it a try. The results were amazing, and the build speed increased by 20s+

Note:The officialThe documentation mentions that esbuild only supports conversion to ES6 for most syntax, so it is only suitable for use in development environments, not recommended for production environments
// dev
module: {
  rules: [{test: /\.js$/,
      use: [
        {
          loader: 'esbuild-loader'.options: {
            loader: 'js'.target: 'es2015',}}],exclude: /node_modules/,
      include: resolve('src')}}]Copy the code

cache-loader & dllplugin

Webpack5 optimization before most rely on cache-loader to increase the cache in some time-consuming places, or rely on dllPlugin to reduce packaging content, so that the build speed. Webpack5 provides out-of-the-box persistent caching, which increases the first build time of my projects by 10% and reduces the second build time by roughly 85% with the introduction of caching

module.exports = {
  cache: {
    type: 'filesystem'.// Enable persistent caching
    cacheDirectory: resolve('.temp_cache'), // Cache file location
    buildDependencies: { // Cache invalid configuration
      config: [__filename]
    }
  }
}
Copy the code

plugins

html-webpack-plugin

If an error occurs, just upgrade to the latest version

npm i --save-dev html-webpack-plugin@latest
Copy the code

clean-webpack-plugin

Output has an extra clean parameter to clean the output directory before generating the file, so adding this parameter will remove the plug-in

optimize-css-assets-webpack-plugin

For webpack5 or later, please use csS-minimizer-webpack-plugin. After using the new plugin, we found that about 400KB is missing

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [{test: /.s? css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"."sass-loader"],},],},optimization: {
    minimizer: [
      // In webpack@5, you can use '... 'syntax to extend existing minimizer (i.e.' terser-webpack-plugin ')
      '... '.new CssMinimizerPlugin(),
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
};
Copy the code

devServer

The original configuration is as follows

devServer: { ... .// Some unchanged configurations, like hot, open, etc
  quiet: true.overlay: true.disableHostCheck: true.clientLogLevel: 'warning' // The console message level is higher than warning
}
Copy the code
  • Quiet: Removed, the official migration advice can be modified in infrastructrueLogging article, this part actually didn’t understand, at present the infrastructrueLogging. Directly to the level set to the info, display an error warning and information, Friendly-errors-webpack-plugin (none) is used, but friendly-errors-webpack-plugin (none) is used.
  • Overlay: Move to client
  • ClientLogLevel: Move to client and change to logging
  • DisableHostCheck: Change it to allowedHosts and add whitelists

The configuration is as follows

devServer: {
	client: {
    overlay: { // Only error messages are displayed
      errors: true.warnings: false,},logging: 'warn' // The console displays only warn and above information
  },
  allowedHosts: 'all'
},
infrastructrueLogging: {
  level: 'info'
}
Copy the code

other

Devtool one click to open vscode source code

Start by installing launch-editor-Middleware

npm install --save-dev launch-editor-middleware
Copy the code

Configure it in webpack.dev.js

Then add the editor to the environment variable

For example, in vscode, Command + Shift + P opens the Command Palette, enters shell Command, and selects the first one:



Click the following button in ch to open vscode corresponding component

shelljs

I’m currently running node version 14.17.1, and there are a bunch of warnings that don’t affect the running, but are still uncomfortable, so I’ll fix it

Warning: Accessing non-existent property 'cd' of module exports inside circular dependency
(node:21085) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency
(node:21085) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency
Copy the code

Follow the package.json run command line with the following command to see if node reported an error

"test": "cross-env NODE_OPTIONS=--trace-warnings ..."
Copy the code



We can guess that this is a problem with shellJS. The error disappeared after we updated shellJS

Before and after contrast

All the comparisons were made without any changes in the files. Figure 1 is after optimization, and Figure 2 is before optimization: the first package shortens 20s; the second package shortens 60s; the first build shortens 100s; the second build shortens 80s

Packaging for the first time



Secondary packaging



For the first time to build



Secondary building



Reference documentation

Sass-loader: link to esBuild Optimization: Reference article devServer: Reference article devtool: Reference article