This article is based on the latest Webpack5 configurationHMR hot replacement,JS,CSS,Image compression.Based optimizationAnd generateSource Map

· HMR · Hot Module Replace

JS and CSS hot replacement

Simply set hot to true, without introducing hot replacement, add module.hot.accept() to the entry.js

// Configuration: webpack.config.js
devServer: {
  hot: true
}
// entry: index.js
if (module.hot) {
    module.hot.accept(); // bundle.js supports HMR
}
import './style.css'; // CSS is introduced as a module to support HMR
Copy the code

Note: If the CSS module name contains [Contenthash] or [chunkhash], HMR will be invalid. It is recommended that you configure hash only in the production environment

new MiniCssExtractPlugin({
  filename: 'style.[contenthash].css' // Development environment: style.css
}),
Copy the code

HTML hot update

After hot replace is enabled,.html does not refresh automatically by default. You can:

  1. inhotAdd parameters underwatchContentBase, is set totrue
    • contentBase(default current working directory) file changes will trigger the refresh,JSandCSSThe hot replacement of
  2. throughraw-loaderwill.htmlAs a resource import entry.js
    • .htmlBecome modules that can be hot updated,JSandCSSHot substitution is valid and may be required inhtmlRefer to them manually
  3. HtmlWebpackPluginMore used tohtmlAs a template, automatically reference the packagedJSandCSS

Instead of using the plugin, use nodejs’ chokidar with the before parameter to notify the server when the.html content changes

npm i chokidar -D
Copy the code
devServer: {
  hot: true.before(_, server) {
      const chokidar = require('chokidar');
      const files = [
          resolve('src-es6/index-tpl.html') // Corresponds to the template of the HtmlWebpackPlugin
      ];
      chokidar.watch(files).on('all'.() = > {
          server.sockWrite(server.sockets, 'content-changed'); }}})Copy the code

In summary, we have implemented JS and CSS hot replacement (do not refresh the update) and HTML hot update (automatically refresh the page).

JavaScript compression

TerserPlugin

Webpack5 is delivered with Webpack5. Forget UglifyjsPlugin ParallelUglifyPlugin and environment variables for a moment

optimization: {
  minimize: true.// Can be omitted, default optimal configuration: production environment, compression true. Development environment, uncompressed false
  minimizer: [
      new TerserPlugin({
          parallel: true.// Can be omitted. Parallelism is enabled by default
          terserOptions: {
              toplevel: true.// At the highest level, delete useless code
              ie8: true.safari10: true,}})}Copy the code

The cache is no longer configured separately. Follow WebPack’s cache setup (same as Optimization)

cache: true // Can be omitted, default optimal configuration: production environment, no cache false. Development environment, cache to memory, memory
Copy the code

SourceMap is no longer configured separately. Follow webPack’s Devtool configuration (level with cache)

devtool: env.NODE_ENV === 'production' ? 'source-map' : 'inline-source-map' // Production and development environments are officially recommended
Copy the code

Babel

Enable cache babel-loader? CacheDirectory is still a very effective way to improve Babel performance. Cache-loader is similar to HappyPack. Use NPM I cache-loader -d NPM I thread-loader -d before the loader to be used

module: {
  rules: [{
      test: /\.js$/, 
      include: resolve('src-es6/js'), // test, include, exclude narrow the search scope
      use: [
          'cache-loader'.// Cache subsequent loader results
          'thread-loader'.// Then loader starts the independent worker pool
          {
              loader: 'babel-loader? cacheDirectory'.// Enable the babel-loader cache
              options: {
                  presets: '@babel/preset-env'.plugins: [['@babel/plugin-transform-runtime',
                       { 'corejs': 3}]]}}]}Copy the code

Preset – ENV-2015 and other preset ending in the latest are a thing of the past. Just for ES5 + to ES5, can be directly

npm i @babel/preset-env -D
Copy the code

By default, Babel’s new interface to ES6, such as includes, will not be converted to the old interface. In order to be compatible, we need to introduce polyfill in the old browser, that is, pure JS implementation of the new interface @babel/ Polyfill7.4.0 will be abandoned, do not need to configure useBuiltIns. With @ Babel/plugin – transform – runtim

npm i @babel/plugin-transform-runtime -D
Copy the code

Specify the corejs version

  • 2Only global variables, such asPromiseEtc.
  • 3Instance attributes are also supported, includingincludesEtc.

Can be installed

npm i @babel/runtime-corejs3 -D
Copy the code

Scope promotion · Scope promotion

Multiple ES6 modules put closures to reduce redundancy and speed up. ModuleConcatenationPlugin was preferred, Webpack4 + support by default

optimization: {
  concatenateModules: true // Can be omitted, default optimal configuration, production environment scope promotion enabled true, development environment disabled false
}
Copy the code

other

HardSourceWebpackPlugin DllPlugin and DLLReferencePlugin, as Webpack4+ compiles itself to speed up the once lucrative optimization approach, are no longer necessary in some projects, but their contributions are obvious and are still used today

CSS compression

MiniCssExtractPlugin

After Webpack4+, extract CSS to a separate file, using MiniCssExtractPlugin to achieve

npm i mini-css-extract-plugin -D
// entry: index.js
import './style.css';
// Configuration: webpack.config.js
module: {
    rules: [{test: /\.css$/,
            include: resolve('src-es6/css'), // test, include, exclude narrow the search scope
            use: [
                MiniCssExtractPlugin.loader, // Place it before csS-loader
                { loader: 'css-loader'.options: { sourceMap: true}}// Affect all csS-loader-dependent plug-ins to generate sourceMap]]}},plugins: [
  new MiniCssExtractPlugin({
      filename: 'style.css'.[contenthash].css to avoid cache problems}),]Copy the code

CssMinimizerPlugin

MiniCssExtractPlugin Recommends CssMinimizerPlugin to compress CSS and come with CSsnano. Forget PurgeCSS for a moment

NPM I CSS -minimizer-webpack-plugin -D configuration: webpack.config.jsoptimization: {
    minimizer: [
     new CssMinimizerPlugin({
            parallel: true.// Can be omitted. Parallelism is enabled by default
            sourceMap: true.// Can be omitted, default follows webPack devtool configuration
            minimizerOptions: {
                preset: 'advanced'.// Additional installation is required}})]}Copy the code

sourceMapIt can be configured separately. Follow this rule if no configuration is requiredwebpackthedevtoolConfiguration (withoptimizationAt the same level)

Built-in plug-inpresetThe default isdefault.cssnanoThree preset optimization schemes are supported

Remove unused CSSdiscardUnused. In advance, install CSsnano-preset -advanced

npm i cssnano-preset-advanced -D
Copy the code

Image compression

CSS inline images

Url-loader if the size is smaller than the specified size, transfer the image to base64

module: {
    rules: [{
      test: /\.(png|jpe? g|gif|svg)(\? . *)? $/,
      loader: 'url-loader'.options: {
        limit: 10.// If the image is smaller than 10KB, switch to Base64 encoding}}}]Copy the code

Image module

Import /require diagrams into.js or.html require(image path)

  • file-loader + image-webpack-loader
rules: [{
  test: /\.png$/i.// Take PNG as an example
  use: [
    'file-loader',
    {
      loader: 'image-webpack-loader'.options: {
        pngquant: {
          quality: [0.65.0.90] // Set the PNG quality interval},},],}]Copy the code

The images directory

If the image is imported directly into.html, or loaded via.js, the above method does not work in the actual project

  • The pictures are mostly in the same directory
  • CopyPluginAt compile time, from the source directorysrcCopy to the publishing directorydist
npm i imagemin-webpack-plugin -D
Copy the code

Note that gifsicle is installed by default. If your network environment fails all the time, please use CNPM to install it. After using CNPM, delete node_modules directory, and then CNPM I will install it again using NPM to avoid other problems

plugins: [
    new CopyPlugin({
      patterns: [{
          from: resolve('src-es6/images'),
          to: resolve('dist/images'),}}]),new ImageminPlugin({ // After the CopyPlugin. If you merge multiple configuration files, CopyPlugin is placed in the merged configuration of common
        test: /\.(png|jpe? g)$/i,
        pngquant: {
            quality: '70-75' // Set the PNG quality interval
        },
        plugins: [ // Other image compression plug-ins can be introduced
            ImageminMozjpeg({
                quality: 70.// Set the jpeg/ JPG quality
                progressive: true // Progressive: true: fuzzy to clear false: load from top to bottom})]}),]Copy the code

Jpegtran can not be adjusted quality, in the “ImageminPlugin support image compression plug-in list” select plug-in ImageminMozjpeg can be installed

npm i imagemin-mozjpeg -D
Copy the code

This is yu’s first article in nuggets, thank you for reading, wish you a happy life!