Learn the basics of webpack

Keywords: Javascript node.js React Vue.js Webpack

1, Introduction to webpack

  1. What is webpack

webpack is a front-end resource building tool and a static module packer

In webpack, all file resources in the front end (js/json/css/img/less) are treated as modules. It will perform static analysis according to the dependency of the module and package the corresponding static resources.

<!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>Document</title>

    // Record processing less

    <link rel="stylesheet" href="./index.less">

</head>

<body>

    <div id="box">hello Ha ha ha</div>

    Record processing js In file es6 grammar

    <script src="./index.js"></script>

</body>

</html>

Enter from the entry file, record according to different modules to form a code block chunk, then process according to different modules, and then output to form a bundle.

  1. Core concept

  • Entry

Entry, indicating which file is the starting point for webpack to start packaging, analyze and build the internal dependency graph

  • Output

Output, indicating where the resource bundles packaged by the webpack are output

  • Loader

loader enables webpack to handle non js files (webpack itself only understands js)

  • Plugins

Plug-ins that can perform a wider range of tasks. Plug ins range from packaging optimization and compression to redefining variables in the environment.

  • Mode

Mode, indicating that the webpack uses the configuration of the corresponding mode

[external chain picture transfer failed, the source station may have anti-theft chain mechanism, It is recommended to save the picture and upload it directly (img-etaxy8tv-1630850415882)( https://le88510hbg.feishu.cn/space/api/box/stream/download/asynccode/?code=MjdlZTgyYzA0NDE3ZDg2Y2VkZGI4ZmMyOTgyODdmMGJfWmI4bmpvUnRBTDR0U0xkeG1XSzhvc2NRTHVLc1B4ZllfVG9rZW46Ym94Y25HMHBUMFg0NUI0Y0hSZHljczllZUZnXzE2MzA4NTAzOTI6MTYzMDg1Mzk5Ml9WNA )]

2, Basic usage

  1. Initialize package file
npm init
  1. Download package file (Global installation)
npm i webpack webpack-cli -g

3, Package style file

  1. webpack.config.js

Configuration file for webpack

Function: instruct webpack to do those things (the configuration will be loaded when running the webpack instruction)

All construction tools are run based on nodejs platform, and common JS is adopted by default for modularization

  1. Basic configuration

Install style loader and CSS loader

npm i style-loader css-loader -D

Create a new webpack.config.js file

const { resolve } = require("path");

// webpack configuration

// Entrance starting point

module.exports = {

    //output

    entry: './src/index.js',

    output: {

        //Output file name

        filename: 'built.js',

        //Output path

        //__ The dirname nodejs variable represents the absolute path of the current file directory

        path: resolve(__dirname, 'build')

    },



    //loader configuration

    module: {

        rules: [

            // Detailed loader configuration

            // Different files must be configured with different loader s for processing

            {

                // Used to match those files

                test: /\.css$/,

                // Use those loader s for processing

                use: [

                    // The execution order in the use array: from left to right, from top to bottom

                    // Create a style tag, insert the style resource in js, and add it to the head to take effect

                    'style-loader',

                    // Change the css file into a commonjs module and load it into js. The content inside is the style string

                    'css-loader'

                ]

            }

        ]

    },



    //plugins configuration

    plugins: [

        //Detailed plugin configuration

    ],



    //pattern

    mode: 'development'

    // mode: 'production'



}
  1. Processing css files
{

    // Used to match those files

    test: /\.css$/,

    // Use those loader s for processing

    use: [

        // The execution order in the use array: from left to right, from top to bottom

        // Create a style tag, insert the style resource in js, and add it to the head to take effect

        'style-loader',

        // Change the css file into a commonjs module and load it into js. The content inside is the style string

        // minimize in CSS loader? minimize tells CSS loader to enable CSS compression

        'css-loader?minimize'

    ]

}

Loader can be regarded as a translator with file conversion function. The module.rules array in the configuration configures a set of rules to tell Webpack which loader to use to load and convert when encountering which files. The above configuration tells Webpack to use CSS loader to read the CSS file when it encounters a file ending in. CSS, and then give it to style loader to inject the CSS content into JavaScript.

You can also use the Object method:

use: [

  'style-loader', 

  {

    loader:'css-loader',

    options:{

      minimize:true,

    }

  }

]
  1. Processing less files

Install less and less loader

{

    test: /\.less$/,

    use: [

        'style-loader',

        'css-loader',

        // Compile less files into css files

        // You need to download less loader and less

        'less-loader'

    ]

}

In addition to configuring the Loader in the webpack.config.js configuration file, you can also specify what Loader to use in the source code to process the file. Take loading CSS file as an example, modify main.js in the above example as follows:

// Entry file, where css files are imported

require('style-loader!css-loader?minimize!./main.css');

In this way, you can specify to use CSS loader first and then style loader conversion for. / main.css file.

  1. Processing sass files

Install sass loader

{

    // Added support for SCSS files

    test: /\.scss$/,

    // The processing order of SCSS files is sass loader, CSS loader and style loader

    use: ['style-loader', 'css-loader', 'sass-loader'],

},

4, Packaging html resources

  1. Download plug-ins
npm i html-webpack-plugin -D
  1. Usage path of loader and plugins

loader: 1. Download 2. Use (configure loader)

plugins: 1. Download 2. Import 3. Use

  1. Use html webpack plugin to process packaged html resources
const { resolve } = require("path");

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



module.exports = {

    entry: './src/index.js',

    output: {

        filename: 'built.js',

        path: resolve(__dirname, 'build')

    },

    module: {

        rules:[



        ]

    },

    plugins: [

        // plugins configuration

        // html-webpack-plugin

        // Function: an empty html will be created by default, and all resources (js/css) for packaged output will be automatically introduced

        // Requirements: a structured html file is required

        new HtmlWebpackPlugin({

            // Copy the '. / src/index.html' file and automatically import all resources (js/css) for packaged output

            template: './src/index.html'

        })

    ],



    mode: 'development'

}

5, Package picture resources

  1. Download plug-ins
npm i url-loader -D
  1. Handle picture references in less files
const { resolve } = require('path');

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



module.exports = {

  entry: './src/index.js',

  output: {

    filename: 'built.js',

    path: resolve(__dirname, 'build')

  },

  module: {

    rules: [

      {

        test: /\.less$/,

        // To use multiple loader s, use

        use: ['style-loader', 'css-loader', 'less-loader']

      },

      {

        // Problem: img images in html cannot be processed by default

        // Processing picture resources

        test: /\.(jpg|png|gif)$/,

        // Use a loader

        // Download URL loader file loader

        loader: 'url-loader',

        options: {

          // If the image size is less than 8kb, it will be processed by base64

          // Advantages: reduce the number of requests (reduce server pressure)

          // Disadvantages: larger picture size (slower file request)

          limit: 8 * 1024,

          // Problem: the URL loader uses es6 modular parsing by default, while the picture introduced by HTML loader is commonjs

          // There will be a problem when parsing: [object Module]

          // Solution: turn off es6 modularization of URL loader and use commonjs for parsing

          esModule: false,

          // Rename picture

          // [hash:10] take the first 10 bits of the hash of the picture

          // [ext] get the original file extension

          name: '[hash:10].[ext]'

        }

      }

    ]

  },

  plugins: [

    new HtmlWebpackPlugin({

      template: './src/index.html'

    })

  ],

  mode: 'development'

};

Handle picture references in html files

{

    test: /\.html$/,

    // Process img images of html files (responsible for introducing img so that it can be processed by URL loader)

    loader: 'html-loader',

    options: {

        esModule: false

    }

}

6, Package other resources

  1. Install plug-ins
npm i file-loader -D
  1. Configure in loader
module: {

    rules: [

        {

            test: /\.css$/,

            use: ['style-loader', 'css-loader']

        },

        // Package other resources (resources other than html/css/js resources)

        {

            // exclude

            exclude: /\.(css|js|html)$/,

            loader: 'file-loader',

            option: {

                name: '[hash:10].[ext]'

            }

        }

    ]

}

7, devServer (Automation)

  1. Install the devServer plug-in
npm i webpack-dev-server -D
  1. use

Development server devServer: used for automation (automatic compilation, automatic browser opening, automatic browser refreshing)

Features: it will only compile in memory without any output. The webpack startup above will generate the build folder and output all packaged files.

const HtmlWebpackPlugin = require("html-webpack-plugin");

const { resolve } = require("path");



module.exports = {

    entry: './src/index.js',

    output: {

        filename: 'built.js',

        path: resolve(__dirname, 'build')

    },



    module: {

        rules: [

            {

                test: /\.css$/,

                use: ['style-loader', 'css-loader']

            },

            {

                exclude: /\.(css|js|html)$/,

                loader: 'file-loader'

            }

        ]

    },



    plugins: [

        new HtmlWebpackPlugin({

            template: './src/index.html'

        })

    ],



    mode: 'development',



    // Development server devServer: used for automation (automatic compilation, automatic browser opening, automatic browser refreshing)

    // Features: only compile in memory without any output

    // The instruction to start devServer is: NPX webpack dev server

    devServer: {

        // Project post build path

        contentBase: resolve(__dirname, 'build'),

        // Start gzip compression

        compress: true,

        // Port number

        port: 3000,

        // Open browser automatically

        open: true

    }

}

The start command is

webpack serve

8, Development environment configuration

When packaging with the webpack command, specify the output path:

Export the entry js file to the following file:

output: {

    filename: 'js/built.js',

    path: resolve(__dirname, 'build')

},

Output the loader file to the specified path:

{

    test: /\.(jpg|png|gif)$/,

    loader: 'url-loader',

    options: {

      limit: 8 * 1024,

      esModule: false,

      name: '[hash:10].[ext]',

      outputPath: 'images'

    }

}

The output image file will be put into the images file

Complete development environment configuration:

/*

  Development environment configuration: it can make the code run

    Run project instructions:

      webpack The packaging results will be output

      npx webpack-dev-server It will only compile and package in memory without output

*/



const { resolve } = require('path');

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



module.exports = {

  entry: './src/js/index.js',

  output: {

    filename: 'js/built.js',

    path: resolve(__dirname, 'build')

  },

  module: {

    rules: [

      // Configuration of loader

      {

        // Handling less resources

        test: /\.less$/,

        use: ['style-loader', 'css-loader', 'less-loader']

      },

      {

        // Handling css resources

        test: /\.css$/,

        use: ['style-loader', 'css-loader']

      },

      {

        // Processing picture resources

        test: /\.(jpg|png|gif)$/,

        loader: 'url-loader',

        options: {

          limit: 8 * 1024,

          name: '[hash:10].[ext]',

          // Turn off es6 modularization

          esModule: false,

          outputPath: 'imgs'

        }

      },

      {

        // Processing img resources in html

        test: /\.html$/,

        loader: 'html-loader'

      },

      {

        // Processing other resources

        exclude: /\.(html|js|css|less|jpg|png|gif)/,

        loader: 'file-loader',

        options: {

          name: '[hash:10].[ext]',

          outputPath: 'media'

        }

      }

    ]

  },

  plugins: [

    // plugins configuration

    new HtmlWebpackPlugin({

      template: './src/index.html'

    })

  ],

  mode: 'development',

  devServer: {

    contentBase: resolve(__dirname, 'build'),

    compress: true,

    port: 3000,

    open: true

  }

};

9, Package css into a separate file

  1. Install plug-ins
npm i mini-css-extract-plugin -D
  1. Replace the style loader with the loader in MiniCssExtractPlugin and rename the plug-in
const { resolve } = require("path");

const HtmlWebpackPlugin = require("html-webpack-plugin");

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



module.exports = {

    entry: './src/js/index.js',

    output: {

        filename: 'js/built.js',

        path: resolve(__dirname, 'build')

    },



    module: {

        rules: [

            {

                test: /\.css$/,

                use: [

                    // Create a style label and put the style into

                    // 'style-loader',

                    // This loader replaces the style loader

                    // Function: extract css in js into a separate file

                    MiniCssExtractPlugin.loader,

                    'css-loader'

                ]

            }

        ]

    },



    plugins: [

        new HtmlWebpackPlugin({

            template: './src/index.html'

        }),

        new MiniCssExtractPlugin({

            // Rename the output css file

            filename: 'css/built.css'

        })

    ],



    mode: 'development'

}

10, css compatibility processing

  1. Install plug-ins
npm i postcss-loader postcss-preset-env -D
  1. Configuration rules
// >1%

// default

// dead

// last 2 version
  • Method 1: in package.json
"browserslist": {

  // Development environment -- > set node environment variable: process.env.NODE_ENV = development

  "development": [

    "last 1 chrome version",

    "last 1 firefox version",

    "last 1 safari version"

  ],

  // Production environment: the default is the production environment

  "production": [

    ">0.2%",

    "not dead",

    "not op_mini all"

  ]

}
  • Method 2: configure in. Browserlistrc

In the. Browserlistrc file:

> 1%

last 2 version

not dead
  • Method 1: configure in the webpack.config.js file:
const { resolve } = require('path');

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

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



// Set nodejs environment variable

// process.env.NODE_ENV = 'development';



module.exports = {

  entry: './src/js/index.js',

  output: {

    filename: 'js/built.js',

    path: resolve(__dirname, 'build')

  },

  module: {

    rules: [

      {

        test: /\.css$/,

        use: [

          MiniCssExtractPlugin.loader,

          'css-loader',

          /*

            css Compatibility processing: postcss -- > postcss loader postcss preset env

            Help postcss find the configuration in the browserslist in package.json, and load the specified css compatibility style through the configuration

          */

          // Use the default configuration of loader

          // 'postcss-loader',

          // Modify the configuration of the loader

          // Postcss preset env: preset, plug-in collection

          {

                loader: 'postcss-loader',

                options: {

                    postcssOptions: {

                        plugins: [['postcss-preset-env',{}]]

                    }

                }

            }

        ]

      }

    ]

  },

  plugins: [

    new HtmlWebpackPlugin({

      template: './src/index.html'

    }),

    new MiniCssExtractPlugin({

      filename: 'css/built.css'

    })

  ],

  mode: 'development'

};
  • Method 2: postcss.config.js file
module.exports = {

    plugins: [

        'postcss-preset-env'

    ]

}





// Configuration in webpack.config.js

use: [

    'style-loader',

    'css-loader',

    'postcss-loader'

]
  1. After css generation

[external chain picture transfer failed, the source station may have anti-theft chain mechanism, It is recommended to save the picture and upload it directly (img-xex9ix2y-1630850415884)( https://le88510hbg.feishu.cn/space/api/box/stream/download/asynccode/?code=MWE0ZTc2OTA4Y2JmNmQ3MTgwNGJhYjAzMDgwMzljMmVfcEw5TXBGWXEzeTAzYUxiNWtYYUlBTUN6VENid0haSU9fVG9rZW46Ym94Y255c1p4UE9hcGNvZmJiN3RCYWVzTmpjXzE2MzA4NTAzOTI6MTYzMDg1Mzk5Ml9WNA )]

11, Compress css

  1. Install plug-ins
npm i optimize-css-assets-webpack-plugin -D
// Introducing plug-ins

const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')



plugins: [

    new HtmlWebpackPlugin({

        template: './src/index.html'

    }),

    new MiniCssExtractPlugin({

        filename: 'css/built.css'

    }),

    // Compress css

    new OptimizeCssAssetsWebpackPlugin()

]

12, js syntax check (eslint)

When compiling and packaging, prompt errors according to the syntax rules specified by eslint.

  1. Install plug-ins
npm i eslint-loader eslint -D

npm i eslint-config-airbnb-base eslint-plugin-import -D
  1. Set the syntax rules in package.json
// Set syntax rules

"eslintConfig": {

    "extends": "airbnb-base"

}
  1. use
const { resolve } = require("path");



module.exports = {

    entry: './src/js/index.js',

    output: {

        filename: 'js/built.js',

        path: resolve(__dirname, 'build')

    },



    module: {

        rules: [

            // Note: only check the code written by yourself, and the code of the third-party library does not need to be checked

            {

                test: /\.js$/,

                // Exclude code from third-party libraries

                exclude: /node_modules/,

                loader: 'eslint-loader',

                // Turn on automatic repair of errors in eslint check

                options: {

                    fix: true

                }

            }



        ]

    },



    plugins: [

    ],



    mode: 'development'

}

be careful

// All rules of eslint in the next line are invalid (the next line does not check the eslint code)

// eslint-disable-next-line

console.log(add(3,4))

13, js compatibility processing

  1. Basic js compatibility processing

A. Install plug-ins

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

Problem: only basic syntax can be converted, such as promise advanced syntax

{

    test: /\.js$/,

    exclude: /node_modules/,

    loader: 'babel-loader',

    options: {

      presets: [

        ['@babel/preset-env']

      ]

    }

}
  1. All js compatibility processing

Problem: as long as some compatibility problems are solved, but all compatibility codes are introduced, the volume is too large~

A. Install plug-ins

npm i @babel/polyfill -D

Directly introduced in js code

// Introduce @ babel/polyfill

import '@babel/polyfill';



const add = (x, y) => {

  return x + y;

};

console.log(add(2, 5));



const promise = new Promise(resolve => {

  setTimeout(() => {

    console.log('The timer has finished executing~');

    resolve();

  }, 1000);

});



console.log(promise);
  1. Load on demand (recommended)

A. Install plug-ins

npm i core-js -D

Use in combination with the first method:

const { resolve } = require('path');



module.exports = {

  entry: './src/index.js',

  output: {

    filename: 'built.js',

    path: resolve(__dirname, 'build')

  },

  module: {

    rules: [

      {

        test: /\.js$/,

        exclude: /node_modules/,

        loader: 'babel-loader',

        options: {

          // Preset: indicates how babel handles compatibility

          presets: [

            [

              '@babel/preset-env',

              {

                // Load on demand

                useBuiltIns: 'usage',

                // Specify the core JS version

                corejs: {

                  version: 3

                },

                // Specify which version of browser to use

                targets: {

                  chrome: '60',

                  firefox: '60',

                  ie: '9',

                  safari: '10',

                  edge: '17'

                }

              }

            ]

          ]

        }

      }

    ]

  },

  plugins: [

  ],

  mode: 'development'

};

14, Compress html and js

  1. js compression

After changing the mode to the production environment, js compression is automatically enabled

mode: 'production'
  1. html compression

plugins: [

    new HtmlWebpackPlugin({

        template: './src/index.html',

        // Compress html code

        minify: {

            // Remove spaces

            collapseWhitespace: true,

            // Remove comment

            removeComments: true

        }

    })

]

15, Production environment configuration

  1. File types to be processed
  • Html

plugins:

A. Processing html files - > html webpack plugin

B. Handle html compression

  • Css

plugins:

A. Package css into a separate file - > Mini css extract plugin

B. Enable css compression - > optimize css assets webpack plugin

​ Loader:

A. Package as a separate file - > minicssextractplugin.loader

B. Handling css files - > css loader

C. Handling css style compatibility - > postcss loader (you need to define browserlist in package.json)

D. Handling less files - > less loader

E. Do not generate separate files, css and js together - > style loader

  • Js

Loader:

A. js code check - > eslint loader

B. js code compatibility - > Babel loader + corejs (version needs to be specified)

C. js code automatic compression

  • picture

Loader:

A. Processing image resources in css files - > URL loader

B. processing image resources in html files - > html loader

  • Other documents

Loader:

A. Processing other files - > file loader

  1. Detailed configuration
const { resolve } = require('path');

// Package css into a separate file

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

// css compression

const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');

// Processing html files

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



// Define nodejs environment variables: determine which environment to use for the browserlist

process.env.NODE_ENV = 'production';



// Reuse loader

const commonCssLoader = [

  MiniCssExtractPlugin.loader,

  'css-loader',

  {

    // css compatibility handling postcss loader

    // You also need to define the browserlist in package.json

    loader: 'postcss-loader',

    options: {

      postcssOptions: {

          plugins:['postcss-preset-env',[]]

      }

    }

  }

];



module.exports = {

  entry: './src/js/index.js',

  output: {

    filename: 'js/built.js',

    path: resolve(__dirname, 'build')

  },

  module: {

    rules: [

      {

        test: /\.css$/,

        use: [...commonCssLoader]

      },

      {

        test: /\.less$/,

        use: [...commonCssLoader, 'less-loader']

      },

      /*

        Normally, a file can only be processed by one loader.

        When a file needs to be processed by multiple loaders, the order of execution of loaders must be specified:

          Execute eslint first and babel later

      */

      {

        // js syntax check eslint

        // Eslintconfig -- > airbnb in package.json

        test: /\.js$/,

        exclude: /node_modules/,

        // Priority implementation

        enforce: 'pre',

        loader: 'eslint-loader',

        options: {

          fix: true

        }

      },

      {

        // js compatibility processing Babel loader + corejs

        test: /\.js$/,

        exclude: /node_modules/,

        loader: 'babel-loader',

        options:{

          presets: [

              '@babel/preset-env',

              {

                  useBuiltInt: 'usage',

                  corejs: {

                      verson: 3

                  },

                  target: {

                      chrome: '60',

                      firebox: '60'

                  }

              }

          ]

        }

      },

      {

        // Image processing: in css file

        test: /\.(jpg|png|gif)/,

        loader: 'url-loader',

        options: {

          limit: 8 * 1024,

          name: '[hash:10].[ext]',

          outputPath: 'imgs',

          esModule: false

        }

      },

      {

        // Image processing: in html file

        test: /\.html$/,

        loader: 'html-loader',

        options: {

            esModule: false,

            name: '[hash:10].[ext]'

        }

      },

      {

        // Other document processing

        exclude: /\.(js|css|less|html|jpg|png|gif)/,

        loader: 'file-loader',

        options: {

          outputPath: 'media'

        }

      }

    ]

  },

  plugins: [

    new MiniCssExtractPlugin({

      filename: 'css/built.css'

    }),

    new OptimizeCssAssetsWebpackPlugin(),

    new HtmlWebpackPlugin({

      template: './src/index.html',

      minify: {

        collapseWhitespace: true,

        removeComments: true

      }

    })

  ],

  mode: 'production'

};

Posted by ShadowIce on Sun, 05 Sep 2021 16:14:54 -0700