This paper is written based on

webpack 5

1. Getting started (familiarize yourself with webPack configuration)

1.1 Create an engineering project

This will generate a package.json file under the current file

@1 Engineer a project

npm init -y
Copy the code

We downloaded two packages according to the official requirements

npm i webpack webpack-cli -D
Copy the code
  • It is installed in the production environment by defaultproduction
  • -d Is installed in the development environmentdevelopment

Webpack is packaged by dependency and all installations will eventually be packaged in whatever environment they are in just for the sake of specification

@3 Create a SRC in the root directory and create an index.js

@ 4 modified package. Json

@ 5 perform

npm run build1
Copy the code

Now that you’ve done the simple packaging of webpack, you’ll see a dist folder generated in the root directory

1.2 This section describes the core configuration

The first thing to know is that the underlying webpack is written based on Express, which is developed based on NodeJS, so we follow the CommonJS specification in the configuration file webpack.config.js

@1 create a webpack.config.js

After creating a webpack.config.js file in the root directory, we can configure webpack in this file.

@2 Export the configuration

// @1
module.exports = {

}
// @2
module.exports = function (){
    // The arguments command interface can be used to pass arguments
    console.log(arguments);
    return{}}Copy the code

How do I use the command interface to pass parameters?

Output from method two

@3 Core concepts

Pattern mode

Set the mode parameter by selecting one of development, production, or None

module.exports = {
  mode: 'production'};Copy the code
Entrance to the entry

The entry point indicates which module webPack should use as a starting point for building its internal dependency Graph.

Webpack recursively builds a dependency graph * the packaged files will be analyzed below

An entry

module.exports = {
  // No matter where the configuration file is located
  entry: './src/index.js'};Copy the code

Multiple entry

Waiting to write

Output the output

The Output attribute tells WebPack where to export the bundles it creates and how to name those files. The default value for the main output file is./dist/main.js, and the other generated files are placed in the./dist folder by default.

  • Where do I put my packaged path files
  • Filename Specifies the name of the packaged file
const path = require('path');

module.exports = {
  output: {
    // Must be an absolute address
    path: path.resolve(__dirname, 'dist'),
    filename: 'mydist, }, };Copy the code
loader

What is the loader?

Let’s see what the official story says

Webpack can only understand JavaScript and JSON files, which is a built-in capability of WebPack available out of the box. Loader enables WebPack to process other types of files and convert them into valid modules for use by applications and to be added to dependency diagrams.

Loader evaluates/executes from right to left (or bottom to top)

This is explained in 1.3.2 below

Let’s take a closer look at Loader through the code

const path = require('path');

module.exports = {
  output: {
    filename: 'my-first-webpack.bundle.js',},module: {
    rules: [{ test: /\.txt$/, use: 'raw-loader'}],}};Copy the code

In the above configuration, the rules property is defined for a single Module object, which contains two required properties: test and use. This tells the Webpack compiler the following:

“Hey Webpack compiler, when you encounter a” path that is resolved to ‘.txt’ in the require()/import statement “, use the raw-loader conversion before you package it.

We will discuss common loaders in detail

Plug-in plugin

Let’s take a look at the official introduction

To use a plugin, you simply require() it and add it to the plugins array. Most plug-ins can be customized with options. You can also use the same plug-in multiple times for different purposes in a configuration file by using the new operator to create an instance of the plug-in.

@ 1 introduction

@2 is new in the plugins array

How about a brief introduction to how to use plugin in this step

We’ll take a closer look at common plugins

const HtmlWebpackPlugin = require('html-webpack-plugin'); // Install via NPM
const webpack = require('webpack'); // Used to access built-in plug-ins

module.exports = {
  plugins: [
      new HtmlWebpackPlugin({ template: './src/index.html'})]};Copy the code

1.3 Some basic requirements

1.3.1 Introduces HTML to automatically associate it with packaged JS

www.npmjs.com/package/htm…

@1 npm i -D html-webpack-plugin

This is a plugin, so follow the rules of plugin mentioned above

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

module.exports = {
  entry: 'index.js'.output: {
    path: __dirname + '/dist'.filename: 'index_bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin()
  ]
}
Copy the code

New HtmlWebpackPlugin() passes in some common arguments to an object

  • Template Specifies the HTML template address string

  • TemplateContent Specifies the template

    templateContent = ` ..... `
    Copy the code
  • Filename Specifies the name of the packaged file

    //[hash] randomly generates hash values that are useful for clearing the cache
    filename:'webpack[hash].html'
    Copy the code
  • Title Specifies the title of HTML1 as long as you follow ejS syntax

    • <title><%= htmlWebpackPlugin.options.title %></title>

    We can play like this

    @1 Create a public folder under the root directory

    @2 Create an index. HTML HTML template in the public folder

    @ 3 configuration

    plugins:[
        new HtmlWebpackPlugin({
            template:'./public/index.html'})]Copy the code

    @ 4 pack

    Then you can see in the dist folder that an index.html is generated and automatically associates us with the packaged JS

1.3.2 Each package deletes the previously packed files

www.npmjs.com/package/cle…

@ 1 introduction

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
Copy the code

@2 使用一下plugin

plugins:[
    CleanWebpackPlugin();
]
Copy the code

Later, you will find that each NPM run build is a new DIST

1.3.3 the introduction of CSS

Since Webpack only knows js and JSON files, you need to introduce a loader to tell WebPack to load CSS files

@1 Install related Loaders

npm install  css-loader style-loader
Copy the code

@2 introduces CSS into JS

import './test.css'
Copy the code

@ 3 configuration loader

module: {
    rules: [{test:/\.txt$/,
            use:'raw-loader'
        },
        {
            test:/\.css$/.// Parse principles from right to left
            use:['style-loader'.'css-loader']},]},Copy the code

To perform the CSS – loader

  • Css-loader is used to process external CSS resources
  • In layman’s terms, CSS introduced by import/require is a webPack-aware resource

To perform style – loader

+ inserts the style into the DOM by inserting a style tag into the head and writing the style into the innerHTML of the tagCopy the code

The style is then packaged in index.html

1.3.4 Improving the compatibility of the imported CSS

www.npmjs.com/package/pos…

Why postCSS-loader

figure

@ 1 installation

npm install --save-dev postcss-loader postcss
Copy the code

@2 Usage method

  • Import in loader

  • Write a postcss.config.js configuration file in the root directory

    module.exports = {
        plugins: [["postcss-preset-env",
                {
                    // Options},]],};Copy the code
  • Configuration. The browserslistrc

So what is Browserslistrc?

You can refer to this

www.jianshu.com/p/d45a31c50…

Cover 99.9%Copy the code
  • Compatible with 99.9 percent of browsers on the market

This thing is about configuring browser compatibility

//.browserslistrc
last 1 version
> 1%
maintained node versions
not dead
Copy the code

1.3.5 split CSS

Change from directly inserting the style tag to link import

www.npmjs.com/package/min…

@ 1 installation

npm install --save-dev mini-css-extract-plugin
Copy the code

2 use the @

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

module.exports = {
  plugins: [new MiniCssExtractPlugin()],
  module: {
    rules: [{test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],},],},};Copy the code
  • Where does filename’s packed CSS go in dist

1.3.5 Introducing images

Before WebPack 5, it was common to use:

  • Raw-loader imports the file as a string
  • Url-loader inlines the file into the bundle as a data URI
  • File-loader sends files to the output directory

Let’s start with url-loader file-loader

@ 1 installation

npm install url-loader file-loader --save-dev
Copy the code

@2 Introduce image resources

import img from './image.png';
Copy the code

@ 3 configuration

{
    test: /\.(png|jpg|gif)$/i,
    use: [
        {
            loader: 'url-loader'.options: {
                limit: 1024 * 50.name:'imgs/[name].[ext]'}},],},Copy the code
  • Limit The maximum size 1024 x 50 is 50 KB
  • Where do I put the name file

The official website says that if the size of the file exceeds the limit, file-loader will be used

That is, the image will not be packaged until it is more than a base64 image

Beyond that is an HTTP path address that packs the image

Use Base64 to optimize web pages with fewer HTTP requests


The effect

The image was originally 51.4KB in size and I set the limit to 50kb


webpack5

Asset Module Type replaces all of these loaders by adding 4 new module types:

  • asset/resourceSend a separate file and export the URL. Previously by usingfile-loaderThe implementation.
  • asset/inlineExport the data URI of a resource. Previously by usingurl-loaderThe implementation.
  • asset/sourceExport the source code of the resource. Previously by usingraw-loaderThe implementation.
  • assetAutomatically choose between exporting a data URI and sending a separate file. Previously by usingurl-loaderAnd configure the resource volume limitation implementation.

An example is packaged as Base64

{
    test: /\.(png|jpg|gif)$/i,
    type: 'asset/inline'
}
Copy the code

How do asset/ Resource wrapped diagrams specify paths and text

Take a look at the official documentation

By default, the Asset/Resource module is sent to the output directory with the filename [hash][ext][query].

The output can be set through in webpack configuration. AssetModuleFilename to modify this template string:

So we need to set it in output

output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'mywebpack.js'.assetModuleFilename: 'images/[name][ext]'
},
Copy the code

1.4 Split the configuration file/split webpack.config.js

What does the official say

There are huge differences in build goals between development and production environments. In a development environment, we need: a powerful source map and a Localhost Server with live reloading or hot Module replacement capabilities. Production environment goals move to other areas, focusing on bundle compression, lighter source maps, resource optimizations, and so on to improve load times. To follow logical separation, we generally recommend writing separate WebPack configurations for each environment.

Although we have made a fine distinction between production and development environments above, please note that we will follow the principle of Don’t repeat Yourself – DRY and keep a “common “configuration. To merge these configurations together, we will use a tool called Webpack-Merge. The tool references the “common” configuration, so we don’t have to write duplicate code in environment-specific configurations.

Webpack.docschina.org/guides/prod…

@ 1 installation

npm install --save-dev webpack-merge
Copy the code

@2 Create a config directory

Split up the original webpack.config.js

+ common configuration webpack.common.js + development environment configuration webpack.dev.js + production environment configuration webpack.productionCopy the code
- |- webpack.config.js
+ |- webpack.common.js
+ |- webpack.dev.js
+ |- webpack.prod.js
Copy the code

@ 3 write configuration

Common configuration webpack.common.js

const path = require("path");
module.exports = {
    entry:'./src/index.js'.output: {path: path.resolve(__dirname),
        filename: 'mywebpack.js',}}Copy the code

The development environment is configured with webpack.dev.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
    mode: 'development'
});
Copy the code

The production environment is configured with webpack.prod.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
    mode: 'production'
});
Copy the code

2. Development server (devServer)

At the bottom of webpack-dev-server is the HTTP module for NodeJS

Running it will run the wrapped index.html

@ 1 installation

npm i webpack-dev-server
Copy the code

@ 2 USES webpack – dev – server

Configuration @ 2.1

var path = require('path');

module.exports = {
  / /...
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true.port: 9000,}};Copy the code

@2.2 Add serve after webpack

When the server is started, it prints a message before parsing the module list:


Here are some webPack Server-related properties

contentBase

Tell the server where the content came from. Configure this only if you need to provide static files

const path = require('path');
module.exports = {
  / /...
  devServer: {
    contentBase: path.join(__dirname, 'public'),}};Copy the code

before

Provides a custom execution function before all middleware execution within devServer.

Take a look at the official example

module.exports = {
  / /...
  devServer: {
    before: function (app, server, compiler) {
      app.get('/some/path'.function (req, res) {
        res.json({ custom: 'response'}); }); ,}}};Copy the code

If you know the Node Express framework, do you think it looks like express interface syntax

Let’s do that with get

It can run through

We can use this feature to simulate requests to do some fake data


In the template index.html

fetch('/api/list').then((res) = > {
    return res.json()
}).then((res) = > {
    console.log(res);
})
Copy the code

webpack.config.js

before: function (app, server, compiler) {
    app.get('/api/list'.function (req, res) {
        res.json({ custom: 'hello' });
    });
},
Copy the code

open

Tell dev-server to open the browser after the server starts. Set it to true to open the default browser

module.exports = {
  //...
  devServer: {
    open: true,
  },
};
Copy the code

proxy

The configuration agent’s vue.config.js is similar to this one and its underlying is probably merged with the Webpack configuration

Simple notation

module.exports = {
  / /...
  devServer: {
    proxy: {
      '/api': 'http://localhost:3000',}}};Copy the code

Any request that begins with/API will be forwarded to http://localhost:3000

Expand the writing

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
      },
    },
  },
};
Copy the code

Any request that begins with/API is forwarded to http://localhost:3000 and ‘/ API’ is overwritten as an empty string

For example, the /list interface is actually requested

axios('/api/list').then(res= >{})
Copy the code

changeOrigin: true

By default, the agent retains the source of the host header, and changeOrigin can be set to True to override this behavior

This thing can sometimes trick the back end into intercepting

For example, the interface for sending a localhost:3000 request to localhost:9000 is /list

ChangeOrigin: true -> Source (host/origin) obtained by the backend localhost:9000

ChangeOrigin: false -> Source (host/origin) obtained by the backend localhost:3000

progress

Outputs the run progress to the console

Method of use

webpack serve --progress
Copy the code

hotOnly

Enable hot module replacement (see devServer.hot) without a page refresh as a fallback in case of a build failure. Hot update

webpack.config.js

module.exports = {
  / /...
  devServer: {
    hotOnly: true,}};Copy the code

Through the command line

webpack serve --hot-only
Copy the code