Take you to the new version of Webpack 5

Absrtact: webpack5 quick start, ship new version, recommended collection

This article is shared from Huawei cloud community< webpack5 quick start, ship new version, recommended collection >, author: Aurora Borealis night..

1, Get started quickly

1.1 Webpack function:

Packaging: package different types of resources by module.
Static: the final output of static resources after packaging.
Module: webpack supports modular development of different specifications

1.2 installing webpack:

Terminal input: npm install webpack -g

1.3 quickly simulate and build a project directory:

utiles.js:

function add(a,b){
    console.log(a+b);
}
export {add} ;

index.js:

import {add} from './utiles/utiles.js'
add(6,9);

1.4 webpack packaging:

Terminal input: webpack

webpack will automatically find the src directory, then find the index.js entry file, then package it, and finally generate a dist directory as the packaged content.

index.html import:

 <script src="../dist/main.js"></script>

result:

2, Basic usage:

2.1. Configuration file:

You can define the configuration in the configuration file, indicating how you want to package, and you can set many conditions. Webpack will be packaged according to the configuration rules of your profile. Create a new webpack.config.js file in the src peer directory to write configuration information.

Such as the most basic entrance and exit:

const path = require('path');
module.exports = {
  //Package entry file path
  entry: './src/index.js',
  //Path packaging exit path, filename writes the file name after packaging
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.js',
  },
};

After inputting webpack, the terminal successfully packaged the build.js file, which is the same as the main.js packaged above:

2.2.loader:

Why use loader:

Webpack can only understand JavaScript and JSON files, which is the built-in capability of webpack out of the box. loader enables webpack to process other types of files (such as css files, image types, txt types, etc.) and convert them into effective modules for use.

2.2.1 css-loader:

For example, I think webpack can package css. The terminal enters the following command to install css loader first:

npm i css-loader -D

1. You can specify the loader when importing the css file so that no error is reported. Add css loader before importing the css file path!:

import 'css-loader!./css/index.css'

2. Of course, you can also set in the configuration file:

const path = require('path');
module.exports = {
  //Package entry file path
  entry: './src/index.js',
  //Path packing exit path, filename packing file name
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.js',
  },
  //Define some rules
  module: {
      //Each element in the array is a rule
     rules:[
        {
            test: /\.css$/,
            use: [
                {loader: 'css-loader'}
            ]
          //Abbreviated as use: ['css loader ']    
        }
     ]
  }
};

The test attribute defines a regular expression to match the file type to be processed. Identify which files will be converted.
The use attribute defines which loader should be used during conversion.

After configuring in the configuration file, don't forget to import the css file in the index entry file.

2.2.2 style-loader:

The above css loader can only recognize css files, and the css style can be displayed on the page after the introduction of style loader.

Installation:

npm i style-loader -D

Profile rules:

because   webpack is executed from back to front  , So style loader is written in front of CSS loader.

module: {
      //Each element in the array is a rule
     rules:[
        {
            test: /\.css$/,
            use: ['style-loader','css-loader']
        }
     ]
  }

2.2.3 sass-loader:

For example, I think webpack can package scss file types. Not sass, you can see the full analysis of SASS in this article.

To install sass:

npm i sass -D

Convert scss to css (note that it is also a terminal input under the same level path of scss):

sass index.scss:ouput.css

Import in the entry file index.js:

import './css/ouput.css'

To install sass loader:

npm i sass-loader -D

Configuration rules:

 //Define some rules
  module: {
      //Each element in the array is a rule
     rules:[
        {
            test: /\.css$/,
            use: ['style-loader','css-loader']
        },
         {
            test: /\.scss$/,
            use: ['style-loader','css-loader']
        }
     ]
  }

pack:

webpack

2.3 browserslist:

Webpack supports all ES5 compliant browsers (IE8 and below are not supported). If you want to support older browsers, you need to use some tools. browserslist is installed by default when installing webpack. It can know the occupancy data of each browser and configure it.

This website can also find the current share data of various browsers. I'll talk about it in detail later.

2.4 the postcss loader handles css compatibility:

postcss is a JavaScript style conversion tool that can handle css compatibility issues. It is this tool that can add some compatible prefixes to the css code we write.

First of all, you can learn what prefix css adds and how it can be compatible with mainstream browsers through this website.

Installation:

npm i postcss-loader -D
npm i autoprefixer -D

Profile:

Add postcss loader in css file type and configure parameters:

  {
            test: /\.css$/,
            use: [
                'style-loader',
                'css-loader',
                //Add postcss loader
                {
                    loader:'postcss-loader',
                    //configuration parameter
                    options:{
                       postcssOptions:{
                           //Add a plug-in autoprefixer, which can be prefixed
                           plugins:[
                               require('autoprefixer')
                           ]
                       }
                    }
                }
            ]
        },

Create a new file named. Browserlistrc under the same level of index.js, which writes compatible conditions, such as:

> 0.1%
last 2 version
not dead

Then, the terminal inputs the webpack, and the css code will automatically add the compatible code after packaging.

The above is just a prefix. If you need stronger compatibility, you need postcss preset env. Installation:

npm i  postcss-preset-env -D

Add configuration (secondary):

const path = require('path');
module.exports = {
  //Package entry file path
  entry: './src/index.js',
  //Path packing exit path, filename packing file name
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.js',
  },
  //Define some rules
  module: {
      //Each element in the array is a rule
     rules:[
        {
            test: /\.css$/,
            use: [
                'style-loader',
                'css-loader',
                //Add postcss loader
                {
                    loader:'postcss-loader',
                    //configuration parameter
                    options:{
                       postcssOptions:{
                           //Add a plug-in autoprefixer, which can be prefixed
                           plugins:[
                               require('autoprefixer'),
                               require('postcss-preset-env')
                           ]
                       }
                    }
                }
            ]
        },
         {
            test: /\.scss$/,
            use: ['style-loader','css-loader']
        }
     ]
  }
};

You can only keep postcss preset Env, abbreviated as:

  {
            test: /\.css$/,
            use: [
                'style-loader',
                'css-loader',
                //Add postcss loader
                {
                    loader:'postcss-loader',
                    //configuration parameter
                    options:{
                       postcssOptions:{
                           //Add a plug-in autoprefixer, which can be prefixed
                           plugins:['postcss-preset-env']
                       }
                    }
                }
            ]
        },

However, generally, a new postcss.config.js file is created under the same level of index.js to write the configuration:

Content of postcss.config.js file:

module.exports = {
    plugins: [
        require('postcss-preset-env')
    ]
}

Then directly import the postcss loader in the webpack.config.js configuration file:

 use: [
                'style-loader',
                'css-loader',
                //Add postcss loader
                 'postcss-loader'
            ]

2.5 importLoaders:

importLoaders: used to configure the number of loaders before css loaders act on @ imported resources. To put it bluntly, if importLoaders is set, the css file imported through @ import will also execute the loaders that are not executed before.

As follows:

 use: [
                'style-loader',
                {
                   loader:'css-loader',
                   options:{
                       importLoaders:1
                   }
                },
                 'postcss-loader'
            ]

Originally, a css file will execute the above three loaders. If the css file imported through import syntax exists, the imported css file will not execute the last postcss loader. But I want to execute, so configure importLoaders to indicate how many loaders the imported css file will execute backward. (note that the webpack is executed from back to front)

2.6 file loader processing pictures:

File loader function:

1. When we import the picture as a module, we can recognize it.
2. You can copy a copy of binary resources to the specified directory. If it is not specified, it is the default dist directory.

Installation:

npm i file-loader -D 

2.6.1 imported through src in js:

You can create a new img folder in the src directory to store pictures.

Configuration file (continue to add a rule in the rules array):

       {
            test: /\.(png|svg|gif|jpe?g)$/,
            use:['file-loader']
        }
  • First usage:
    When importing the picture as a module, add. default at the end, such as:
    var img = document.createElement('img');
    img.src = require('../img/1.jpg').default;
    document.body.appendChild(img);
  • Second usage:
    If you do not want to add. default at the end of module import, add the parameter esModule in the configuration file:
{
            test: /\.(png|svg|gif|jpe?g)$/,
            use:{
                loader:'file-loader',
                options: {
                    esModule:false
                }
            }
        }
  • The third usage:
    If you don't want to write like this, you can also import through es6 module:

Import the picture module first:

import src from '../img/1.jpg';

Then:

   var img = document.createElement('img');
   img.src = src;
   document.body.appendChild(img);

Finally, just package the terminal webpack. At present, the pictures will be packaged to the dist directory by default.

2.6.2 imported via url in css:

The difference from src above is to modify the css type file rule and add an esModule parameter:

{
            test: /\.css$/,
            use: [
                'style-loader',
                {
                   loader:'css-loader',
                   options:{
                       importLoaders:1,
                       esModule:false
                   }
                },
                 'postcss-loader'
            ]
        },
          {
            test: /\.(png|svg|gif|jpe?g)$/,
            use: ['file-loader']
        }

Then, it can be referenced normally through url in css. After webpack is packaged, the pictures will be packaged to dist directory by default:

div {
  width: 200px;
  height: 200px;
  background-image: url("../img/1.jpg");
}

Default location, such as (the picture name is automatically obtained according to the content algorithm):

2.6.3 setting output position and picture name:

We can set the place and name where the packaged pictures are stored.

Modify the picture rule of the configuration file and add a name attribute and outputpath attribute (location):

 {
            test: /\.(png|svg|gif|jpe?g)$/,
            use: {
                loader:'file-loader',
                options:{
                    name: '[name].[hash:6].[ext]',
                    outputPath: 'img'
                }
            }
        }

The name attribute indicates: [ext] extension, [name] file name and [hash] file content. outputpath attribute: directly specify the img directory, which will be placed in the dist directory by default.

The two attributes can be combined and directly abbreviated as:

 {
            test: /\.(png|svg|gif|jpe?g)$/,
            use: {
                loader:'file-loader',
                options:{
                    name: 'img/[name].[hash:6].[ext]',
                }
            }
        }

2.7 URL loader processing pictures:

URL loader can convert the image into base64 string, which can load the image faster (for the case where there are few image files, use file loader if it is too large). File loader is slower than copy.

Installation:

npm i url-loader -D

In fact, the configuration is similar to that of file loader. Just change the loader:

{
            test: /\.(png|svg|gif|jpe?g)$/,
            use: {
                loader:'url-loader',
                options:{
                    name: 'img/[name].[hash:6].[ext]',
                }
            }
        }

Unlike file loader, the packaged images will be loaded into the code in the form of base64 string, so they are no longer visible in the directory:

The key is that actually, URL loader includes file loader. You can set a limit attribute. When the image size exceeds the limit, URL loader will admit that it can't, and will take the initiative to call file loader for execution.

As follows: set a raft value of 20kb, less than it will execute URL loader, and greater than it will execute file loader

 {
            test: /\.(png|svg|gif|jpe?g)$/,
            use: {
                loader:'url-loader',
                options:{
                    name: 'img/[name].[hash:6].[ext]',
                    limit: 20*1024
                }
            }
        }

2.8 image processing of asset:

After webpack 5, you can directly use asset to process images without configuring file loader or URL loader. It can better simplify the use. And it is a built-in module of webpack 5, so there is no need to install other things.

Picture modification rules for profile:

1. By default, the image is copied and placed in the dist directory by default (the result is the same as when the file loader is not configured with a name and path):

 {
            test: /\.(png|svg|gif|jpe?g)$/,
            type: 'asset/resource'
        }

2. Specify the location of the image after packaging and put it in the img folder under dist. the image rules are the same as above. To modify the output packaging exit path, add assetModuleFilename:

//Path packing exit path, filename packing file name
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.js',
    assetModuleFilename:'img/[name].[hash:6][ext]'
  },
    {
            test: /\.(png|svg|gif|jpe?g)$/,
            type: 'asset/resource'
        }

3. The above is equivalent to the global configuration. No matter what image will be executed, it is not good, so it is better to add the image output location and name in the rule. Add a generator, and the filename in the rule will write the location and name:

 {
            test: /\.(png|svg|gif|jpe?g)$/,
            type: 'asset/resource',
            generator:{
                filename:'img/[name].[hash:6][ext]'
            }
        }

4. If you want to convert the image to base64 string instead of copying, the modification rules are as follows:

    {
        test: /\.(png|svg|gif|jpe?g)$/,
        type: 'asset/inline',
    }  

5. Of course, you can also set a threshold like the URL loader setting limit. After exceeding the limit, you still use copy. The modification rules are as follows: set the size with maxSize, where the threshold is 30kb:

     {
            test: /\.(png|svg|gif|jpe?g)$/,
            type: 'asset',
            generator:{
                filename:'img/[name].[hash:6][ext]'
            },
            parser:{
                dataUrlCondition: {
                    maxSize: 30*1024
                }
            }
        }

2.9 Font Icon of asset processing:

Add the following rules:

 // Font Icon
        {
            test: /\.(ttf|woff2?)$/,
            type:'asset/resource',
            generator:{
                filename:'font/[name].[hash:3][ext]'
            },
        }

2.10 use of webpack plug-in:

As we all know, plug-ins can help us do more things more conveniently.

2.10.1 plug in for automatic emptying of dist Directory:

Every time we repackage the webpack, we have to delete the dist directory we packed last time. It's troublesome, so here we download a plug-in to automatically empty the dist directory. In the future, the content of the last package will be cleared by default.

To install the clean webpack plugin:

npm i clean-webpack-plugin -D

Set the configuration item plugins of the configuration file:

const path = require('path');
// 1. Import the downloaded plug-in first
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.js',
  },
  module: {. . . },
  //2. Define the plugins attribute of plug-in configuration and store each plug-in
  plugins: [
      //3. Each plug-in is a class. Just new
      new CleanWebpackPlugin()
  ]
};

Each plug-in is a class. Just click new. You can view the official website of the corresponding plug-in to understand what functions the parameters passed correspond to.

2.10.2 HTML webpack plugin:

It can help us generate an html file template in the packaging directory after packaging, and reference the entry file.

To install the HTML webpack plugin:

npm i html-webpack-plugin -D

Set the configuration item plugins of the configuration file:

const path = require('path');

const {CleanWebpackPlugin} = require('clean-webpack-plugin');
// 1. Import the downloaded plug-in first
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.js',
  },
  module: {. . . },
  plugins: [
      new CleanWebpackPlugin(),
    // 2. Add
     new HtmlWebpackPlugin()
  ]
};

After webpack packaging:

html default content:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Webpack App</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <script defer="defer" src="build.js"></script>
  </head>
  <body></body>
</html>

For html that can be set in many places, such as the content of title, just pass the corresponding parameters in the configuration file new (refer to the official website of the plug-in for details):

. . . slightly
plugins: [
      new CleanWebpackPlugin(),
      new HtmlWebpackPlugin({
          title:'Aurora Borealis night.'
      })
  ]

Content of html file generated after packaging:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Aurora Borealis night.</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <script defer="defer" src="build.js"></script>
  </head>
  <body></body>
</html>

Of course, you can provide an html template yourself and generate a new html template based on the template I provide:

1. Create a new public directory under src level, and create an index.html file as a template:

2. For example, the content of index.html is as follows:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <div class="app" id="app">test</div>
  </body>
</html>

<% = htmlwebpackplugin. Options. Title% > indicates that the title in the configuration is used.

3. Add a template parameter with the value of template path:

  new HtmlWebpackPlugin({
          title:'Aurora Borealis night.',
          template:'./public/index.html'
      })

4. Packaging results:

2.11 Babel loader processing js compatibility:

Can handle js compatibility issues, such as es6 syntax compatibility.

Installation:

npm i @babel/core -D
npm i babel-loader -D

Create a babel.config.js file under the index.js level to write the configuration:

Contents of babel.config.js file:

 module.exports = {
    presets: ['@babel/preset-env']
}

Then add rules in the webpack.config.js configuration file:

        {
            test:/\.js$/,
            use:['babel-loader']
        }

Like the postcss loader mentioned earlier, write compatible conditions in the. Browserlistrc file, such as:

0.1%
last 2 version
not dead

Finally, just pack the webpack.

2.12 polyfill processing js compatibility:

Babel loader doesn't handle enough js compatibility. It can only handle simple. If promise exists, these new grammars are not good. So you need polyfill.

Installation:

npm i @babel/polyfill --save

Modify babel.config.js:

module.exports = {
    presets: [
        '@babel/preset-env',
        {
            useBuiltIns: 'entry',
            crorejs: 3
        }
    ]
}

2.13 automatic update:

After you modify the source code, the packaged code can also be updated automatically without manual packaging every time.

1. Before webpack dev serve is not used, the watch attribute can be added to the configuration file to be true, and automatic updates can also be realized. However, the performance is not very good, and local updates cannot be made. All updates are made as soon as there are updates:

For example:

module.exports = {
//  Here, update automatically
    watch: true,
  //Package entry file path
  entry: './src/index.js',
  //Path packing exit path, filename packing file name
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.js',
    //assetModuleFilename:'img/[name].[hash:6][ext]'
  },
  . . . slightly
}  

2. Webpack dev serve has good performance, can realize local update and save performance.

Install at the terminal first:

npm install webpack-dev-server --save-dev

Later, the packaging command will be changed to:

webpack serve

2.14 HMR module hot replacement:

Function: when a module changes, only one module will be repackaged (instead of all modules), which greatly improves the construction speed.

Configure first:

module.exports = {
  target: 'web',
  // Turn on HMR
  devServer:{
      hot: true
  }
  . . . 
}

Then hot update the module that needs hot update through judgment at the entry file:

import './title'
if(module.hot){
  module.not.accept(['./title.js'])
}

2.15 output path:

output has a publicPath attribute, which is a basic path when css, js, img and other resources are referenced in the project. It outputs the directory of the parsing file, specifies the directory referenced by the resource file, and is a common part of the url path when the browser accesses the service after packaging.

 output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'build.js',
    publicPath:''
  },

2.16 common configurations of devserver:

 devServer:{
      hot: true
      hotOnly:true,
      //Default port
      port:4000
      //Open browser automatically
      open:false
      //Enable server compression
      compress: true
      //When using the History routing mode, if 404 is wrong, it will be replaced with index.html
      historyApiFallback: true
  } 

2.17 proxy:

Set up proxy through webpack to solve the cross domain problem of browser. Add a proxy attribute under devServer:

devServer:{
    ....
      proxy: {
        //Define a tag. For example, all requests starting with the api will follow the proxy settings
          '/api': {
             // The real service base address to be requested is equivalent to being replaced by / api
             target: 'https://...',
            //Rewrite the api to empty because no one else has / api
             pathRewrite: {"^/api":""},
             //The host in the send request header will be set to target
             changeOrigin: true
          }
      }
  } 

At this time, if the server address we originally wanted to request is https: / /... / user, we can replace it with / api/user, and then rewrite / api to be empty, it is actually equivalent to writing https: / /... / user, such as:

axios.get('/api/user').then(res=>{...})

2.18 mode:

Provide mode configuration options to tell webpack to use some built-in optimizations of the corresponding mode. If it is not set, webpack will set the default value of mode to production.

string = 'production': 'none' | 'development' | 'production'
module.exports = {
  mode: 'development',
};

2.19 packaged vue files:

1. Installation:

$ cnpm i vue-loader vue-template-compiler -D

2. Add rule:

   {
            test:/\.vue$/,
            use:['vue-loader']
        }

3. Import the plug-in and use:

const VueLoaderPlugin = require('vue-loader/lib/plugin');

Not finished, updating continuously...

Click focus to learn about Huawei cloud's new technologies for the first time~

Tags: Javascript node.js Vue.js Webpack Programmer

Posted on Sun, 17 Oct 2021 21:57:25 -0400 by ngubie