Sum up 18 webpack plugins, there will always be what you want!

Sum up 18 webpack plugins, there will always be what you want!

What is a plug-in? A functional module that focuses on processing a specific task in the compilation process of webpack can be called a plug-in.

Plugin is an extender, it enriches webpack itself, for the whole process of webpack packaging after the loader is over, it does not directly manipulate files, but works based on the event mechanism, it will monitor some nodes in the webpack packaging process, and execute A wide range of tasks.

Features of Plugin

  • Is an independent module
  • The module exposes a js function
  • The function prototype (prototype) defines an apply method that injects the compiler object. The apply function requires a webpack event hook mounted through the compiler object. The currently compiled compilation object can be obtained in the callback of the hook. If it is an asynchronous compilation plug-in You can get the callback callback
  • Complete the custom sub-compilation process and process the internal data of the completion object
  • If the plug-in is compiled asynchronously, the callback will be executed after the data processing is completed.

Here are 18 commonly used webpack plugins.

HotModuleReplacementPlugin

Module hot update plug-in. The hot update of Hot-Module-Replacement relies on webpack-dev-server. The latter is to update the packaged file or reload to refresh the entire page when the packaged file changes. HRM only updates the modified part.

HotModuleReplacementPlugin comes with the webpack module, so after introducing webpack, you can use it directly in the plugins configuration item.

const webpack = require('webpack')

plugins: [
  new webpack.HotModuleReplacementPlugin(), // 热更新插件
]

html-webpack-plugin

Generate html file. Insert the relevant entry chunk of the entry configuration in webpack and the css style extracted by the extract-text-webpack-plugin into the template provided by the plugin or the content specified by the templateContent configuration item to generate an html file. The specific insertion method is to insert the style link To the head element, the script is inserted into the head or body.

const HtmlWebpackPlugin = require('html-webpack-plugin')

plugins: [
  new HtmlWebpackPlugin({
    
    
    filename: 'index.html',
    template: path.join(__dirname, '/index.html'),
    minify: {
    
    
      // 压缩HTML文件
      removeComments: true, // 移除HTML中的注释
      collapseWhitespace: true, // 删除空白符与换行符
      minifyCSS: true, // 压缩内联css
    },
    inject: true,
  }),
]

inject has four option values

  • true: the default value, the script tag is located at the bottom of the body of the html file
  • body: The script tag is located at the bottom of the body of the html file (same as true)
  • head: The script tag is inside the head tag
  • false: do not insert the generated js file, just generate a html file

Multi-page application packaging

Sometimes, our application is not necessarily a single-page application, but a multi-page application, so how to use webpack for packaging.

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    
    
  entry: {
    
    
    index: './src/index.js',
    login: './src/login.js',
  },
  output: {
    
    
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[hash:6].js',
  },
  //...
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './public/index.html',
      filename: 'index.html', //打包后的文件名
    }),
    new HtmlWebpackPlugin({
    
    
      template: './public/login.html',
      filename: 'login.html', //打包后的文件名
    }),
  ],
}

If you need to configure multiple HtmlWebpackPlugins, the filename field cannot be defaulted, otherwise index.html will be generated by default.

But there is a problem. Index.html and login.html will find that both index.f7d21a.js and login.f7d21a.js are introduced at the same time. Usually this is not what we want. We hope that index.html only introduces index.f7d21a .js, login.html only introduce login.f7d21a.js.

HtmlWebpackPlugin provides a parameter of chunks, which can accept an array. Configuring this parameter will only introduce the js specified in the array into the html file

module.exports = {
    
    
  //...
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: './public/index.html',
      filename: 'index.html', //打包后的文件名
      chunks: ['index'],
    }),
    new HtmlWebpackPlugin({
    
    
      template: './public/login.html',
      filename: 'login.html', //打包后的文件名
      chunks: ['login'],
    }),
  ],
}

If you execute npm run build in this way, you can see that only the js file of index is introduced in index.html, and only the js file of login is introduced in login.html.

clean-webpack-plugin

clean-webpack-plugin is used to clean up the bundle file generated by the last project before packaging. It will automatically clean up the folder according to the output.path; this plug-in is used very frequently in the production environment, because the production environment often generates a lot of hashes If the bundle file is not cleaned up, a new one will be generated every time, resulting in a very large folder.

const {
    
     CleanWebpackPlugin } = require('clean-webpack-plugin')

plugins: [
  new HtmlWebpackPlugin({
    
    
    template: path.join(__dirname, '/index.html'),
  }),
  new CleanWebpackPlugin(), // 所要清理的文件夹名称
]

extract-text-webpack-plugin

Make css into a file instead of inline. The main purpose of this plugin is to extract the CSS styles and prevent the page style loading disorder caused by packaging the styles in js.

const ExtractTextPlugin = require('extract-text-webpack-plugin')

plugins: [
  // 将css分离到/dist文件夹下的css文件夹中的index.css
  new ExtractTextPlugin('css/index.css'),
]

mini-css-extract-plugin

A plugin that extracts CSS as a separate file, creates a CSS file for each js file containing css, and supports loading css and sourceMap on demand. It can only be used in webpack4. Compared with another plug-in extract-text-webpack-plugin, it has the following features:

  • Asynchronous loading
  • No repeated compilation, better performance
  • Easier to use
  • Only for CSS

This plug-in should only be used in production environment configuration, and style-loader is not used in the loaders chain, and this plug-in does not support HMR temporarily

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
    
    
  module: {
    
    
    rules: [
      {
    
    
        test: /\.(le|c)ss$/,
        use: [
          {
    
    
            loader: MiniCssExtractPlugin.loader,
            options: {
    
    
              publicPath: '../',
            },
          },
          'css-loader',
          'postcss-loader',
          'less-loader',
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
    
    
      filename: 'css/[name].[contenthash:8].css',
      chunkFilename: 'css/[id].[contenthash:8].css',
    }),
  ],
}

purifycss-webpack

Sometimes we write too much or repetitive css, which results in redundant code, which we hope to remove in the production environment.

const path = require('path')
const PurifyCssWebpack = require('purifycss-webpack') // 引入PurifyCssWebpack插件
const glob = require('glob') // 引入glob模块,用于扫描全部html文件中所引用的css

module.exports = merge(common, {
    
    
  plugins: [
    new PurifyCssWebpack({
    
    
      paths: glob.sync(path.join(__dirname, 'src/*.html')),
    }),
  ],
})

optimize-css-assets-webpack-plugin

We want to reduce the volume of css after packaging, you can use optimize-css-assets-webpack-plugin.

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin") // 压缩css代码

optimization: {
    
    
  minimizer: [
    // 压缩css
    new OptimizeCSSAssetsPlugin({
    
    })
  ]

UglifyJsPlugin

uglifyJsPlugin is the default compression code method used by vue-cli to compress js files, thereby reducing the size of js files and accelerating the load speed. It uses single-threaded compression code, and the packaging time is slow, so you can close it in the development environment and open it again when deploying in the production environment.

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

plugins: [
  new UglifyJsPlugin({
    
    
    uglifyOptions: {
    
    
      compress: {
    
    
        warnings: false
      }
    },
    sourceMap: true,  //是否启用文件缓存
    parallel: true   //使用多进程并行运行来提高构建速度
  })

ParallelUglifyPlugin

Open multiple sub-processes, and assign the work of compressing multiple files to multiple sub-processes to complete. Each sub-process actually uses UglifyJS to compress the code, but it becomes a parallel execution.

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')

plugins: [
  new ParallelUglifyPlugin({
    
    
    //cacheDir 用于配置缓存存放的目录路径。
    cacheDir: '.cache/',
    sourceMap: true,
    uglifyJS: {
    
    
      output: {
    
    
        comments: false,
      },
      compress: {
    
    
        warnings: false,
      },
    },
  }),
]

terer-webpack-plugin

Webpack4.0 uses the compression plug-in terser-webpack-plugin by default. Before that, uglifyjs-webpack-plugin was used. The difference between the two is that the latter does not compress ES6 very well. At the same time, we can turn on the parallel parameter and use more Process compression, speed up compression.

const TerserPlugin = require('terser-webpack-plugin') // 压缩js代码

optimization: {
    
    
  minimizer: [
    new TerserPlugin({
    
    
      parallel: 4, // 开启几个进程来处理压缩,默认是 os.cpus().length - 1
      cache: true, // 是否缓存
      sourceMap: false,
    }),
  ]
}

NoErrorsPlugin

Report an error but do not exit the webpack process. When compilation errors occur, use NoEmitOnErrorsPlugin to skip the output phase. This ensures that the output resource does not contain errors.

plugins: [new webpack.NoEmitOnErrorsPlugin()]

compression-webpack-plugin

All modern browsers support gzip compression. Enabling gzip compression can greatly reduce the size of transmission resources, thereby shortening the resource download time, reducing the time for the first white screen, and improving the user experience.

gzip has the best compression effect on text-based files (such as CSS, JavaScript, and HTML). It can often achieve a compression rate of up to 70-90% when compressing larger files. For already compressed resources (such as pictures) Gzip compression processing, the effect is very bad.

const CompressionPlugin = require('compression-webpack-plugin')

plugins: [
  new CompressionPlugin({
    
    
    // gzip压缩配置
    test: /\.js$|\.html$|\.css/, // 匹配文件名
    threshold: 10240, // 对超过10kb的数据进行压缩
    deleteOriginalAssets: false, // 是否删除原文件
  }),
]

Of course, this method also requires back-end configuration support.

DefinePlugin

We can define some global variables through DefinePlugin. We can use these variables directly in the module without any declaration. DefinePlugin is a plug-in that comes with webpack.

plugins: [
  new webpack.DefinePlugin({
    
    
    DESCRIPTION: 'This Is The Test Text.',
  }),
]

// 直接引用
console.log(DESCRIPTION)

ProvidePlugin

Load modules automatically. At any time, when the identifier is treated as an unassigned variable, the module will be automatically loaded, and the identifier will be assigned by the output of this module. This is a plugin that comes with webpack.

module.exports = {
    
    
  resolve: {
    
    
    alias: {
    
    
      jquery: './lib/jquery',
    },
  },
  plugins: [
    //提供全局的变量,在模块中使用无需用require引入
    new webpack.ProvidePlugin({
    
    
      $: 'jquery',
      React: 'react',
    }),
  ],
}

DLLPlugin

This is to create a dll-only bundle (dll-only-bundle) in an additional independent webpack setup. This plug-in will generate a file named manifest.json, which is used to map DLLReferencePlugin to related dependencies.

The use steps are as follows

1. Create webpack.dll.config.js under build

const path = require('path')
const webpack = require('webpack')
module.exports = {
    
    
  entry: {
    
    
    vendor: [
      'vue-router',
      'vuex',
      'vue/dist/vue.common.js',
      'vue/dist/vue.js',
      'vue-loader/lib/component-normalizer.js',
      'vue',
      'axios',
      'echarts',
    ],
  },
  output: {
    
    
    path: path.resolve('./dist'),
    filename: '[name].dll.js',
    library: '[name]_library',
  },
  plugins: [
    new webpack.DllPlugin({
    
    
      path: path.resolve('./dist', '[name]-manifest.json'),
      name: '[name]_library',
    }),
    // 建议加上代码压缩插件,否则dll包会比较大。
    new webpack.optimize.UglifyJsPlugin({
    
    
      compress: {
    
    
        warnings: false,
      },
    }),
  ],
}

2. Add configuration behind the plugin of webpack.prod.conf.js

new webpack.DllReferencePlugin({
    
    
  manifest: require('../dist/vendor-manifest.json'),
})

3. Add a shortcut command (build:dll) to the package.json file

 "scripts": {
    
    
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "lint": "eslint --ext .js,.vue src",
    "build": "node build/build.js",
    "build:dll": "webpack --config build/webpack.dll.conf.js"
  }

When packaging the production environment, the npm run build:dll command will generate the vendor-manifest.json file and vendor.dll.js file in the packaging directory. Then npm run build produces other files.

4. Add reference to the entry index.html in the root directory

<script type="text/javascript" src="./vendor.dll.js"></script>

HappyPack
HappyPack allows webpack to split tasks into multiple sub-processes for concurrent execution, and send the results to the main process after the sub-processes are processed. It should be noted that HappyPack is not friendly to file-loader and url-loader support, so it is not recommended to use this loader.

1. HappyPack plug-in installation

npm i -D happypack

2. The webpack.base.conf.js file configures module.rules

module: {
    
    
  rules: [
    {
    
    
      test: /\.js$/,
      use: ['happypack/loader?id=babel'],
      include: [resolve('src'), resolve('test')],
      exclude: path.resolve(__dirname, 'node_modules'),
    },
    {
    
    
      test: /\.vue$/,
      use: ['happypack/loader?id=vue'],
    },
  ]
}

3. Configure in the production environment webpack.prod.conf.js file

const HappyPack = require('happypack')
// 构造出共享进程池,在进程池中包含5个子进程
const HappyPackThreadPool = HappyPack.ThreadPool({
    
     size: 5 })
plugins: [
  new HappyPack({
    
    
    // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
    id: 'babel',
    // 如何处理.js文件,用法和Loader配置中一样
    loaders: ['babel-loader?cacheDirectory'],
    threadPool: HappyPackThreadPool,
  }),
  new HappyPack({
    
    
    id: 'vue', // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
    loaders: [
      {
    
    
        loader: 'vue-loader',
        options: vueLoaderConfig,
      },
    ],
    threadPool: HappyPackThreadPool,
  }),
]

Note that when the project is small, multi-threaded packaging will slow down the packaging speed.

copy-webpack-plugin

We introduced static resources in public/index.html, but webpack will not help us copy to the dist directory when packaging, so copy-webpack-plugin can do the copying work for me well.

const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
    
    
  plugins: [
    new CopyWebpackPlugin({
    
    
      patterns: [
        {
    
    
          from: 'public/js/*.js',
          to: path.resolve(__dirname, 'dist', 'js'),
          flatten: true,
        },
      ],
    }),
  ],
}

IgnorePlugin

This is a built-in webpack plug-in. Its function is to ignore the specified directories of third-party packages and prevent these specified directories from being packaged.

For example, we want to use moment, a third-party dependent library, which mainly formats time and supports multiple national languages. Although I set the language to Chinese, when packaging, all languages ​​will be packaged. This results in a large package and slow packaging speed. In this regard, we can use IgnorePlugin to make the specified directory ignored, so that the packaging becomes faster and the files smaller.

const Webpack = require('webpack')
plugins: [
  //moment这个库中,如果引用了./locale/目录的内容,就忽略掉,不会打包进去
  new Webpack.IgnorePlugin(/\.\/locale/, /moment/),
]

Although we ignore the file directory containing the field path of'./locale/' according to the above method, it also prevents us from displaying the Chinese language when we use it, so we can manually import the Chinese language directory at this time.

import moment from 'moment'

//手动引入所需要的语言包
import 'moment/locale/zh-cn'

moment.locale('zh-cn')

let r = moment().endOf('day').fromNow()
console.log(r)

Reprinted from https://juejin.cn/post/6844904193589772301

Guess you like

Origin blog.csdn.net/weixin_43881166/article/details/115351434
Recommended