1. Analyze related files using stats built in Webpack

Stats: Built statistics. Stats is used in package.json as follows:

"scripts": {"build:stats": "webpack --env production --json > stats.json"
}
Copy the code

If you are a vuE-CLI3 built project, you can also use it as follows:

"scripts": {"build:stats": "vue-cli-service build --mode prod --json > stats.json"
}
Copy the code

Once configured, running the command generates a stats.json file in the root directory where you can view the results of the analysis. This method is only a primary analysis, the granularity is larger.

2. Use speed-measure-webpack-plugin for speed analysis

// install NPM install --save-dev speed-measure-webpack-plugin const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
 
const smp = new SpeedMeasurePlugin();
 
const webpackConfig = smp.wrap({
  plugins: [
    new MyPlugin(),
    new MyOtherPlugin()
  ]
});
Copy the code

Once configured, you can see the execution time of each loader and plug-in when you run the package command. Reference: www.npmjs.com/package/spe…

Use WebPack-bundle-Analyzer for volume analysis

This plug-in should be most front-end partners have used it!

// Install NPM install --save-dev webpack-bundle-Analyzer //'webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}
Copy the code

After the build is complete, the relevant file sizes are shown at http://127.0.0.1:8888. Follow the prompts to analyze dependent third-party module file sizes and component code sizes within the business.

Four, use multi-process, multi-instance build

In this way, resources are parsed in parallel. The solutions are as follows:

  1. How threadloader works: Each time webpack parses a module, threadloader assigns it and its dependencies to worker threads.
Module.exports ={exports. module:{ rules:[ {test:/\.js$/,
            use:[{
                loader:'thread-loader',
                options:{
                    workers: 3
                }
            },
            'babel-loader']}}]... }Copy the code
  1. The Parallel-WebPack principle: Parallel-WebPack helps speed up builds significantly by allowing you to run multiple WebPack builds in parallel, spreading the work out across the processors. Reference: www.npmjs.com/package/par…
  2. HappyPack principle: Every time webapck parses a module, HappyPack assigns it and its dependencies to the worker thread. Note: HappyPack is not friendly to file-loader and URl-loader, so it is not recommended to use HappyPack. The operation mechanism is shown in the figure below:

// 安装
npm install --save-dev happypack

// 使用
const HappyPack=require('happypack')

module.exports = {
    plugins:[
        new HappyPack({
        id: 'jsx',
        threads: 4,
        loaders: [ 'babel-loader' ]
      }),
      new HappyPack({
        id: 'styles',
        threads: 2,
        loaders: [ 'style-loader'.'css-loader'.'less-loader']]}})Copy the code

Reference: www.npmjs.com/package/hap… If you build a project using VUE-CLI3, multi-threaded packaging is automatically turned on.

Five, multi process parallel compression code

Method 1: Use the webpack-parallel-ugli-fi -plugin

const parallelUglifyPlugin=require('webpack-parallel-uglify-plugin');

module.exports = {
  plugins: [
    new parallelUglifyPlugin({
      // Optional regex, or array of regex to match file against. Only matching files get minified.
      // Defaults to /.js$/, any file ending in .js.
      test,
      include, // Optional regex, or array of regex to include in minification. Only matching files get minified.
      exclude, // Optional regex, or array of regex to exclude from minification. Matching files are not minified.
      cacheDir, // Optional absolute path to use as a cache. If not provided, caching will not be used.
      workerCount, // Optional int. Number of workers to run uglify. Defaults to num of cpus - 1 or asset count (whichever is smaller)
      sourceMap, // Optional Boolean. This slows down the compilation. Defaults to false.
      uglifyJS: {
        // These pass straight through to uglify-js@3.
        // Cannot be used with uglifyES.
        // Defaults to {} if not neither uglifyJS or uglifyES are provided.
        // You should use this option if you need to ensure es5 support. uglify-js will produce an error message
        // if it comes across any es6 code that it can't parse. }, uglifyES: { // These pass straight through to uglify-es. // Cannot be used with uglifyJS. // uglify-es is a version of uglify that  understands newer es6 syntax. You should use this option if the // files that you're minifying do not need to run in older browsers/versions of node.
      }
    }),
  ],
};

Copy the code

Method 2: Use uglip-webpack-plugin to enable the PARALLEL parameter (note: the previous webpack version used, does not support compression ES6 syntax).

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
 
module.exports = {
  optimization: {
    minimizer: [new UglifyJsPlugin()],
  },
};
Copy the code

Use the terser-webpack-plugin to enable the PARALLEL parameter (recommended, supports compressed ES6 syntax).

Terset-webpack-plugin NPM install terser-webpack-plugin --save-dev  // webpack.config.js const TerserPlugin = require('terser-webpack-plugin');
 
module.exports = {
  optimization: minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true}})];Copy the code

Vi. Use subcontracting to precompile resource modules

You can package vUE, VUex, VUE-Router base packages, and business base packages into one file. Method: The DLLPlugin is used for subcontracting, and the DllReferencePlugin references manifest.json. Step 1: Create a webpack.dlL.js using DLLPlugin for subcontracting

const path=require("path");
const webpack=require("webpack");

module.exports = {
    entry:{
        library:['vue'.'vuex'.'vue-router']
    },
    output:{
        filename:'[name]_[chunkhash].dll.js',
        path:path.resolve(__dirname,'./build/library'),
        library:'[name]'
    },
    plugins: [
        new webpack.DllPlugin({
            name: '[name]_[hash]',
            path: resolve(__dirname,'./build/library/[name].json')]}})Copy the code

Step 2: Add configuration to package.json:

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

Running this command generates a detached base package. Step 3: Add a plug-in configuration to the WebPack configuration file that works in production

module.exports={
    plugins:[
        new webpack.DllReferencePlugin({
            manifest: require('./build/library/library.json')})]}Copy the code

7. Use cache to improve the speed of secondary construction

Methods: (1) babel-loader enables caching; (2) terset-webpack-plugin enables caching (recommended by Webpack4); (3) Cache-loader or hard-source-webpack-plugin is used

8. Narrow the build goals

Method 1: For example, babel-loaader does not parse node_modules

module.exports={
    module:{
        rules:[
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: 'node_modules'}}}]Copy the code

Method 2: Reduce the file search scope (1) optimize resolve. Modules configuration (reduce the module search level) (2) optimize resolve. MainFields configuration (3) Optimize resolve

Use tree-shaking

A module may have multiple methods, and as long as one of them is used, the whole file will be sent to the bundle. Tree shaking is only putting used methods into the bundle, and unused methods will be erased during the Uglify phase.

Use: Webpack supports modules: false in.babelrc. Production mode is enabled by default

Requirements: must be ES6 syntax, CJS mode is not supported

Remove unwanted CSS code from webPack builds. Use purgecss-Webpack-Plugin with mini-CSS-extract-Plugin.

const glob = require('glob');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const PurgecssPlugin = require('purgecss-webpack-plugin');

const PATHS = {
    src: path.join(__dirname, 'src')}; module.exports={ module:{ rules:[ {test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
        ]
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename: '[name]_[contenthash:8].css'
        }),
        new PurgecssPlugin({
            paths: glob.sync(`${PATHS.src}/**/*`,  { nodir: true}})})]Copy the code

Ten, the compression of picture resources

Images can be compressed using some online image compression sites before they are introduced, or compressed using tools in webpack. Here we use an image-webpack-loader to compress the image.

Module. exports={rules: [{// install image-webpack-loader --save-dev // module.exports={rules: [{// install image-webpack-loader --save-dev //test: /\.(gif|png|jpe? g|svg)$/i, use: ['file-loader',
                {
                  loader: 'image-webpack-loader',
                  options: {
                    disable: true},},],}]}Copy the code

Finally, use advanced versions of WebPack and Node whenever possible. Due to version optimization, many features are built in and webPack speed can be optimized as well.

In addition, in the process of using VUE-CLI3 to build the project, VUE-CLI3 itself has actually done a lot of optimization, the above optimization means vue-cli3 this tool some optimization has actually helped us to do, we do not need to repeat the configuration, specific want to know if you can look at vue-CLI3 configuration source code

The above is some study notes in the process of learning optimization webpack packaging, hereby record, welcome friends to exchange learning!