This chapter is suitable for siege lion with certain webpack foundation, I am a student now, in the learning stage, if there is a bad place to write, welcome the big god to correct.

This chapter mainly includes the following parts:

  • Webpack profile

  • At the beginning of Webpack experience

  • Basic configuration of the Webpack development environment

  • Basic configuration of the Webpack production environment

  • Webpack optimizes configuration

  • Webpack configuration details

  • Webpack5 use

You can continue to learn Webpack from the beginning to the master – advanced chapter, the advanced chapter is mainly about the following content:

  • React/Vue scaffolding configuration details
  • Customize the Loader/Plugin based on Webpack5
  • Implement a simple Webpack5 yourself

This part mainly explains the common Webpack configuration. For more detailed configuration, you can check the Webpack official website

Webpack from beginner to Master – Basic source

Let’s get down to business

Introduction to WebPack

1.1 What is Webpack

Webpack is a front-end resource builder, a static Module bundler. In webpack’s view, all the front-end resource files (JS /json/ CSS /img/less/…) Will be treated as modules. It will carry out static analysis according to module dependencies and generate corresponding static resources (bundles).

1.2 Five core concepts of Webpack

1.2.1 Entry

The Entry indicates which file webPack starts packing as the Entry point, analyzing and building the internal dependency diagram.

1.2.2 the Output

Output indicates where the resource bundles Output from WebPack go and how to name them.

1.2.3 Loader

Loader: Enables Webpack to handle non-JS files, such as style files, image files (Webpack only understands JS)

1. The Plugins

Plugins: Can be used to perform a wider range of tasks. Plug-ins range from packaging optimization and compression to redefining variables in the environment.

1.2.5 Mode

Mode: Instructs Webpack to use the configuration of the corresponding Mode.

options describe The characteristics of
development The value of process.env.node_env in DefinePlugin is set to development. Enable NamedChunksPlugin and NamedModulesPlugin. An environment in which code debugging can run locally
production The value of process.env.node_env in DefinePlugin is set to production. Enable FlagDependencyUsagePlugin FlagIncludedChunksPlugin, ModuleConcatenationPlugin NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin and TerserPlugin. An environment that optimizes code to run online

2. Initial experience of Webpack

2.1 Initial Configuration

  1. Initialize the package.json file

2. Download and install webpack input command: NPM install webpack webpack-cli -g (global install)

2.2 Compiling and Packaging Applications

  1. Create a file
  2. Operation instruction

Webpack SRC /js/index.js -o build/js/built. Webpack compiles packaged JS and JSON files and translates es6’s modular syntax into a syntax that browsers can recognize. Production environment directive: webpack SRC /js/index.js -o build/js/built. Js –mode=production Webpack can compile packaged JS and JSON files. The ability to translate es6’s modular syntax into a syntax that the browser can recognize. Can compress code. 4. The CSS and IMG files cannot be compiled and packaged. Js basic ES6 syntax cannot be converted to es5 syntax.

3. Basic configuration of WebPack development environment

3.1 Creating a Configuration File

  1. Create the file webpack.config.js
  2. The configuration is as follows
const { resolve } = require('path'); // Node has a built-in core module to handle path problems.

module.exports = {
  entry: './src/js/index.js'.// Import file
  output: {
    // Output configuration
    filename: './built.js'.// Output the file name
    path: resolve(__dirname, 'build/js')// Output file path configuration
  },
  mode: 'development'// Development environment
};
Copy the code
  1. Run instruction: webpack
  2. Conclusion: The function is the same as in the previous section

3.2 Packaging style resources

  1. Create a file
  2. Downloading the Installation package

npm i css-loader style-loader less-loader less -D

  1. Modify the configuration file webpack.config.js
/* webpack.config.js webpack configuration file (SRC to write project code, webpack to write configuration code) It tells webPack what to do (when you run the WebPack directive, the configuration inside is loaded). All build tools run on the NodeJS platform. * /

// resolve the method used to concatenate absolute paths
const {
  resolve
} = require('path');

module.exports = {
  / / webpack configuration
  // The entry point
  entry: './src/index.js'.// Output (output to the build.js file under the build folder)
  output: {
    // Output the file name
    filename: 'built.js'.// Output path
    // the __dirname nodejs variable, which represents the absolute directory path of the current file (representing the build folder at the same level as the current webpack.config.js)
    path: resolve(__dirname, 'build')},// Loader configuration
  module: {
    rules: [
      // Details loader configuration
      // Different files must be processed by different Loaders
      {
        // Which files to match
        test: /\.css$/.// Which loaders are used for processing
        use: [
          // The sequence of loader execution in the use array is from right to left and from bottom to top
          // Create a style tag and insert the js style resource into the head
          'style-loader'.// Change the CSS file into a commonJS module and load the js file with the style string
          'css-loader'] {},test: /\.less$/,
        use: [
          'style-loader'.'css-loader'.// Compile less files into CSS files
          Less-loader and less need to be downloaded
          'less-loader']]}},// Plugins are configured
  plugins: [
    // Specify the plugins configuration].// mode (which mode to use)
  mode: 'development'.// Development mode
  // mode: 'production'
}

/* Perform the following steps: analyze less (install loader:style-loader CSS-loader less-loader less) (install the first two loaders for CSS.) 1. / SRC /index.js' 2. Less files are not JS or JSON files. Find the loader of less in the rules of module. Find test: /\.less$/ and execute the code from the rules array in that object (right to left, bottom to top) 4. Using less-Loader to compile less files into CSS files 5. Use csS-loader to convert CSS files into commonJS modules and load them into JS modules. Use style-loader to create style tags, insert js style resources, add them to head. Add the code to the build.js file */ under the build folder of the export file that is parallel to the current webpack.config.js
Copy the code
  1. Run instruction: webpack

3.3 Packaging HTML Resources

  1. Create a file
  2. Downloading the Installation package

npm install --save-dev html-webpack-plugin

  1. Modify the configuration file webpack.config.js
/* loader: 1. Plugins: 1. Download 2. introduce 3. use */
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: [
      // Loader configuration]},plugins: [
    // Plugins are configured
    // html-webpack-plugin
    // Function: creates an empty HTML by default, automatically importing all the resources (JS/CSS) that are packaged as output.
    // Requirements: need a structured HTML file, need to add a template
    new HtmlWebpackPlugin({
      // Copy the file './ SRC /index.html' and automatically import all the resources (JS/CSS) that are packaged as output.
      template: './src/index.html'})].mode: 'development'
};
/* HTML (install plugin: HTML -webpack-plugin) 1. / SRC /index.js' 2. The HTML file is not a JS or JSON file. The HtmlWebpackPlugin is found in the plugins array. 4. Use less-loader to compile less files into CSS files, automatically import all the resources (JS/CSS) that are packaged (JS files are imported by script tag, CSS files are imported by link tag). Otherwise repeated introductions will cause problems) */
Copy the code
  1. Run instruction: webpack

3.4 Packaging Image Resources

  1. Create a file
  2. Downloading the Installation package

npm install --save-dev html-loader url-loader file-loader

  1. Modify the configuration file webpack.config.js
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 loaders, use use
      use: ['style-loader'.'css-loader'.'less-loader'] {},// Problem: img images in HTML cannot be processed by default
      // Process image resources
      test: /\.(jpg|png|gif)$/.// Use a loader
      // download url-loader file-loader(url-loader depends on file-loader)
      loader: 'url-loader'.options: {
        If the image size is less than 8KB, it will be base64 processed. (Usually, small images (8-12KB) will be processed using limit. For 9KB images, we can write limit as 10 * 1024.)
        // Advantages: reduce the number of requests (reduce server stress)
        // Disadvantages: Larger image size (slower file request)
        limit: 8 * 1024.// Problem: Because url-loader uses ES6 modular parsing by default, htMl-loader imports images by commonJS
        [object Module]
        // Resolve: Disable ES6 modularization of urL-loader and use CommonJS parsing
        esModule: false.// Rename the image
        // [hash:10] takes the first 10 bits of the hash of the image
        // [ext] takes the original extension of the file
        name: '[hash:10].[ext]'}}, {test: /\.html$/.// Handle img images of HTML files, not HTML files, which are processed by HtmlWebpackPlugin (which is responsible for importing img and can be processed by URL-loader)
      loader: 'html-loader'}},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'development'
};
/* Install loader:url-loader file-loader html-loader 1. / SRC /index.js' 2. Found the entry file introduces JPG | PNG | GIF files, and JPG | PNG | GIF files is not js or json file, to find the module rules inside looking for loader 3 JPG | PNG | GIF. Find the test: / \ JPG | PNG | gifs $/, implement the rules in the object in the array code 4. Select * from HTNL; select * from HTNL; select * from HTNL; select * from HTNL; select * from HTNL; Processing images need to find the test introduced in HTML: / \ JPG | PNG | gifs $/, execute inside HTML - loader 7. This is because url-loader uses es6 Module by default, while HTMl-loader uses commonJS to import images, using esModule: False Disable THE ES6 modularization of url-loader and use commonJS to parse 8. Rename the image */ using name: '[hash:10].[ext]'
Copy the code
  1. Run instruction: webpack

3.5 Packing Other Resources

  1. Create a file
  2. Downloading the Installation package

npm install --save-dev file-loader

  1. Modify the configuration file webpack.config.js
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: /\.css$/,
        use: ['style-loader'.'css-loader']},// Package other resources (other than HTML/JS/CSS resources)
      {
        // Exclude CSS /js/ HTML resources
        exclude: /\.(css|js|html|less)$/,
        loader: 'file-loader'.options: {
          name: '[hash:10].[ext]'}}},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'development'
};

Copy the code
  1. Run instruction: webpack

3.6 devserver

  1. Create a file
  2. Modify the configuration file webpack.config.js
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: /\.css$/,
        use: ['style-loader'.'css-loader']},// Package other resources (other than HTML/JS/CSS resources)
      {
        // Exclude CSS /js/ HTML resources
        exclude: /\.(css|js|html|less)$/,
        loader: 'file-loader'.options: {
          name: '[hash:10].[ext]'}}},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'development'.// Install webpack-dev-server (NPX webpack-dev-server, NPX webpack-dev-server)
  // devServer: to automate (automatically compile, automatically open browser, automatically refresh browser ~~)
  // Features: only packages are compiled in memory, with no output
  // Start devServer with NPX webpack-dev-server
  devServer: {
    // Project build path
    contentBase: resolve(__dirname, 'build'),
    // Enable gzip compression (to make packaged code smaller)
    compress: true./ / the port number
    port: 3000.// Automatically open the browser
    open: true}};Copy the code
  1. Run instruction: webpack

3.7 Configuring the Development Environment (Basic Template)

  1. Create a file
  2. Downloading the Installation package

Loader/Plugin files downloaded from 3.2 to 3.6 above

  1. Modify the configuration file webpack.config.js
/* Development environment configuration: enables code to run. Webpack will export the package. NPX webpack-dev-server will just compile the package in memory, not output all the code package to js/built. Js file. CSS, less and other files do not need to set a special outputPath, because they are directly packaged into strings into js files */

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: [
      // Loader configuration
      {
        // Process less resources
        test: /\.less$/,
        use: ['style-loader'.'css-loader'.'less-loader'] {},// Process CSS resources
        test: /\.css$/,
        use: ['style-loader'.'css-loader'] {},// Process image resources
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader'.options: {
          limit: 8 * 1024.name: '[hash:10].[ext]'.// Disable es6 modularization
          esModule: false.outputPath: 'imgs'}}, {// Process img resources in HTML
        test: /\.html$/,
        loader: 'html-loader'
      }, {
        // Process other resources
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: 'file-loader'.options: {
          name: '[hash:10].[ext]'.outputPath: 'media'}}},plugins: [
    // Plugins are configured
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'development'.devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3000.open: true}};Copy the code
  1. Run instruction: webpack

Basic configuration of Webpack production environment

4.1 Extracting the CSS into a separate file

  1. Create a file
  2. Download the plug-in installation package

npm install --save-dev mini-css-extract-plugin

  1. Modify the configuration file webpack.config.js
const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// What this plugin does: The style style is not placed in the style tag, but is used via link
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: [
        // 'style-loader'
        // This loader replaces style-loader. Function: Extract CSS from JS into a separate file
        MiniCssExtractPlugin.loader,
        // Integrate CSS files into js files
        'css-loader']]}},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      // Rename the output CSS file
      filename: 'css/built.css'})].mode: 'development'
};
Copy the code
  1. Run instruction: webpack

4.2 CSS Compatibility

  1. Create a file
  2. Download the Loader installation package

npm install --save-dev postcss-loader postcss-preset-env

  1. Modify the configuration file webpack.config.js
const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// Set the 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'./* PRESET: postcss --> postcss-loader postCSs-preset -env Postcss-preset -env helps PostCSS recognize the environment and load the appropriate configuration, making the code compatible with every browser version) postCSs-preset -env: Json to load the specified CSS compatibility style. // Browserslist should be written in package.json "browserslist": {// development environment --> Set the node environment variable: process.env.node_env = development" development": [" Last 1 Chrome version",// Compatible with the latest version" last 1 Firefox version", "last 1 Safari version"], // Production environment: the default is to look at the production environment "production": [">0.2%", "not dead",// no dead browser "not op_mini all"// no op_mini browser]} */
        // Use the default loader configuration
        // 'postcss-loader',
        // Modify the loader configuration in the form of the following object
        {
          loader: 'postcss-loader'.options: {
            ident: 'postcss'.plugins: () = > [
              // PostCSS plugin
              require('postcss-preset-env')()]}}]}]},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/built.css'})].mode: 'development'
};
Copy the code
  1. Modify the package. The json
 "browserslist": {
            // Development environment --> Set the node environment variable: process.env.node_env = development
            "development": [
              "last 1 chrome version".// Compatible with the latest version
              "last 1 firefox version"."last 1 safari version"].// Production environment: The default is production environment
            "production": [
              "0.2%" >."not dead".// Don't use dead browsers
              "not op_mini all"// Do not use op_mini browser]}Copy the code
  1. Run instruction: webpack

4.3 compressed CSS

  1. Create a file
  2. Download the plug-in installation package

npm install --save-dev optimize-css-assets-webpack-plugin

  1. Modify the configuration file webpack.config.js
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')

// Set the 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',
          {
            loader: 'postcss-loader'.options: {
              ident: 'postcss'.plugins: () = > [
                // PostCSS plugin
                require('postcss-preset-env')()]}}]}]},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/built.css'
    }),
    / / compress CSS
    new OptimizeCssAssetsWebpackPlugin()
  ],
  mode: 'development'
};
Copy the code
  1. Run instruction: webpack

4.4 JS Syntax Check

  1. Create a file
  2. Download the plug-in installation package

npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import

  1. Modify the configuration file webpack.config.js
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: [
      /* Eslint-loader: eslint-loader: eslint-loader: eslint-loader: eslint-loader: eslint-loader: eslint-loader: eslint-loader: eslint-loader { "extends": "airbnb-base" } airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint */
      {
        test: /\.js$/,
        exclude: /node_modules/.// Check only your own code, excluding third-party code
        loader: 'eslint-loader'.options: {
          // Automatically fixes esLint errors
          fix: true}}},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'development'
};
Eslint-loader eslint: eslint-loader eslint: eslint-loader eslint: eslint-loader eslint: eslint-loader eslint: eslint-loader eslint: eslint-loader eslint: eslint-loader eslint Use exclude: /node_modules/ to exclude third-party code and only check your own code. Syntax check usually adopt an (can find in the web site, https://github.com/topics/javascript, a detailed look at the inside of the introduction, we want to someone whose library and eslint together, To NPMJS website search elsint found eslint - config - reality - base, point in it can be installed according to the requirements to download, eslint - config - reality is to detect the react code, use the react when writing code you can use this library), Eslint-config-airbnb-base eslint-plugin-import eslint 4. Eslint: fix: true esLint: fix: true EsLint: fix: true esLint: fix Eslint will display a warning if you use console.log() syntax in your code, // eslint-disable-next-line indicates that all ESLint rules on the next line are invalidated (the next line is not checked by ESLint) */
Copy the code
  1. Configure the package.json file
"eslintConfig": {
    "extends": "airbnb-base"."env": {
      "browser": true}}Copy the code
  1. Run instruction: webpack

4.5 JS Compatibility Processing

  1. Create a file
  2. Download the plug-in installation package

npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/polyfill core-js

  1. Modify the configuration file webpack.config.js
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: [
      /* install babel-loader @babel/core Only basic syntax can be converted, such as promise advanced syntax cannot be converted 2. Install the core-js library as needed and configure the presets as follows: Install babel-loader @babel/ core@babel /preset-env @babel/polyfill. Just import '@babel/polyfill' in the main entry file. Problem: I only want to solve part of the compatibility problem, but importing all the compatibility code is too bulky, so we don't use this method
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'.options: {
          // Default: tell Babel what compatibility processing to do
          presets: [['@babel/preset-env', {
                // Load as needed
                useBuiltIns: 'usage'.// Specify the core-js version
                corejs: {
                  version: 3
                },
                // Specify which browser version is compatible
                targets: {
                  chrome: '60'.firefox: '60'.ie: '9'.safari: '10'.edge: '17'}}]]}}]},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'development'
};
Copy the code
  1. Run instruction: webpack

4.6 js compressed

  1. Create a file
  2. Modify the configuration file webpack.config.js
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')},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})].// The production environment will automatically compress js code // some plug-ins will automatically load internally
  mode: 'production'
};
Copy the code
  1. Run instruction: webpack

4.7 HTML compression

  1. Create a file
  2. Modify the configuration file webpack.config.js
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')},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// Compress the HTML code
      minify: {
        // Remove whitespace
        collapseWhitespace: true.// Remove comments
        removeComments: true}})].mode: 'production'
};

Copy the code
  1. Run instruction: webpack

4.8 Configuring the Production Environment

  1. Create a file
  2. Download the plug-in installation package

Download all the previous installation packages

  1. Modify the configuration file webpack.config.js
const {
  resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// Define the nodeJS environment variable: Determines which environment to use browserslist
process.env.NODE_ENV = 'production';

/ / reuse loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader', {
    // You also need to define browserslist in package.json
    loader: 'postcss-loader'.options: {
      ident: 'postcss'.plugins: () = > [require('postcss-preset-env') (the)]}}];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, only one loader can process a file. When a file is to be processed by multiple Loaders, it is important to specify the order in which loader executes: esLint before Babel */
      {
        // In package.json eslintConfig --> Airbnb
        test: /\.js$/,
        exclude: /node_modules/.// Priority execution
        enforce: 'pre'.loader: 'eslint-loader'.options: {
          fix: true}}, {test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'.options: {
          presets: [['@babel/preset-env', {
                useBuiltIns: 'usage'.corejs: {
                  version: 3
                },
                targets: {
                  chrome: '60'.firefox: '60'.ie: '9'.safari: '10'.edge: '17'}}]]}}, {test: /\.(jpg|png|gif)/,
        loader: 'url-loader'.options: {
          limit: 8 * 1024.name: '[hash:10].[ext]'.outputPath: 'imgs'.esModule: false}}, {test: /\.html$/,
        loader: 'html-loader'
      }, {
        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'
};
Copy the code
  1. Run instruction: webpack

Five, Webpack optimization configuration

Webpack performance optimization

  • Development environment performance optimization
  • Production environment performance optimization
Development environment performance optimization
  • Optimize packaging build speed
    • HMR
  • Optimized code debugging
    • source-map
Production environment performance optimization
  • Optimize packaging build speed
    • oneOf
    • Babel cache
    • Multi-process packaging
    • externals
    • dll
  • Optimize the performance of code execution
    • Cache (hash – chunkhash – contenthash)
    • tree shaking
    • code split
    • Lazy loading/preloading
    • pwa

5.1 HMR

  1. Create a file
  2. Modify the configuration file webpack.config.js
/* 1. Why hot updates? When we change the CSS file in the page, the whole file including the JS file will be repackaged for update, which will cause a slow packaging speed, which is what we do not want, so we need to do hot update, only the modified file will be repackaged for update. 2.HMR: Hot Module replacement (on devServer, setting hot to true is enabled) What it does: When a module changes, only that module is repackaged (not all modules), which greatly improves build speed: The HMR function can be used: because style-loader internally implements ~ JS files: HMR function cannot be used by default --> Need to modify the JS code, add the code that supports HMR function note: HMR function can only handle other files that are not entry JS files. HTML files: the HMR function is disabled by default. The HTML file can not be hot updated ~ (do not do HMR function, because there is only one HTML file, as long as the contents of the file changes, the file must be updated

const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: ['./src/js/index.js'.'./src/index.html'].output: {
    filename: 'js/built.js'.path: resolve(__dirname, 'build')},module: {
    rules: [
      // Loader configuration
      {
        // Process less resources
        test: /\.less$/,
        use: ['style-loader'.'css-loader'.'less-loader'] {},// Process CSS resources
        test: /\.css$/,
        use: ['style-loader'.'css-loader'] {},// Process image resources
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader'.options: {
          limit: 8 * 1024.name: '[hash:10].[ext]'.// Disable es6 modularization
          esModule: false.outputPath: 'imgs'}}, {// Process img resources in HTML
        test: /\.html$/,
        loader: 'html-loader'
      }, {
        // Process other resources
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: 'file-loader'.options: {
          name: '[hash:10].[ext]'.outputPath: 'media'}}},plugins: [
    // Plugins are configured
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'development'.devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3000.open: true.// Enable HMR
    When the WebPack configuration is modified, the webPack service must be restarted for the new configuration to take effect
    hot: true}};Copy the code
  1. The js code needs to be added to the code
if (module.hot) {
	// Once module.hot is true, HMR is enabled. --> Make the HMR function code work
	module.hot.accept('./print.js'.function() {
		// The print.js method listens for changes in the print.js file, and when changes occur, other modules are not repackaged and built.
		// The following callback functions are executed
		// This is equivalent to listening for print.js changes and executing print()
		print();
	});
}
Copy the code
  1. Run instruction: webpack

5.2 the source – the map

  1. Create a file
  2. Modify the configuration file webpack.config.js
const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: ['./src/js/index.js'.'./src/index.html'].output: {
    filename: 'js/built.js'.path: resolve(__dirname, 'build')},module: {
    rules: [
      // Loader configuration
      {
        // Process less resources
        test: /\.less$/,
        use: ['style-loader'.'css-loader'.'less-loader'] {},// Process CSS resources
        test: /\.css$/,
        use: ['style-loader'.'css-loader'] {},// Process image resources
        test: /\.(jpg|png|gif)$/,
        loader: 'url-loader'.options: {
          limit: 8 * 1024.name: '[hash:10].[ext]'.// Disable es6 modularization
          esModule: false.outputPath: 'imgs'}}, {// Process img resources in HTML
        test: /\.html$/,
        loader: 'html-loader'
      }, {
        // Process other resources
        exclude: /\.(html|js|css|less|jpg|png|gif)/,
        loader: 'file-loader'.options: {
          name: '[hash:10].[ext]'.outputPath: 'media'}}},plugins: [
    // Plugins are configured
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'development'.devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true.port: 3000.open: true.hot: true
  },
  devtool: 'eval-source-map' // Use: just add this sentence
};

/* source-map: A technique that provides source-to-build-after code mapping (if the build-after code goes wrong, By mapping can track source code error) [inline - | hidden - | eval -] [nosources -] [being - [module -]] source - the map source - the map: External error code exact information and source code error location inline-source-map: inline generates only one inline source-map error code exact information and source code error location hidden-source-map: External error code error cause, but no error location can trace the source code error, only after the built code error location eval-source-map: Nosource-source-map: external error code exact information, but nosource code exact information: The module will add the loader's source map to the inline and external source map. Development environment: fast, debug friendly and fast (eval>inline> Cheap >... Eval-cheap-souce-map (fastest) eval-source-map (best) cheap-module-souce-map cheap-souce-map (best) Eval-source-map > : eval-cheap-module-souce-map Production Environment: Should source code be hidden? Inline makes the code bigger, so in a production environment you don't have to inline nosource-source-map to hide all hidden-source-map to hide only the source code, Source-map ()/cheap-module-souce-map ()/source-map () */
Copy the code
  1. Run instruction: webpack

5.3 oneOf

  1. Create a file
  2. Modify the configuration file webpack.config.js
const {
  resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

process.env.NODE_ENV = 'production';

/ / reuse loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader', {
    loader: 'postcss-loader'.options: {
      ident: 'postcss'.plugins: () = > [require('postcss-preset-env') (the)]}}];module.exports = {
  entry: './src/js/index.js'.output: {
    filename: 'js/built.js'.path: resolve(__dirname, 'build')},module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/.// Priority execution
      enforce: 'pre'.loader: 'eslint-loader'.options: {
        fix: true}}, {// Only one of the following loaders will be matched.
      / / note: You can't have two configurations that handle the same type of file (for example, we'll use both ble-loader and eslint-loader, so we'll extract eslint-loader in front of oneOf, OneOf (eslint-loader)
      oneOf: [{
          test: /\.css$/,
          use: [...commonCssLoader]
        }, {
          test: /\.less$/,
          use: [...commonCssLoader, 'less-loader']},/* Normally, only one loader can process a file. When a file is to be processed by multiple Loaders, it is important to specify the order in which loader executes: esLint before Babel */
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel-loader'.options: {
            presets: [['@babel/preset-env', {
                  useBuiltIns: 'usage'.corejs: {
                    version: 3
                  },
                  targets: {
                    chrome: '60'.firefox: '50'}}]]}}, {test: /\.(jpg|png|gif)/,
          loader: 'url-loader'.options: {
            limit: 8 * 1024.name: '[hash:10].[ext]'.outputPath: 'imgs'.esModule: false}}, {test: /\.html$/,
          loader: 'html-loader'
        }, {
          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'
};
Copy the code
  1. Run instruction: webpack

5.4 the cache

  1. Create a file
  2. Modify the configuration file webpack.config.js
const {
  resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

/* cache: 1. Babel cache cacheDirectory: true --> make the second package build faster 2. File resource cache Hash: A unique hash value is generated for each Wepack build. Problem: Because JS and CSS use the same hash value. If repackaged, all caches will be invalidated. Chunkhash: Hash value generated by chunk. If the package comes from the same chunk, the hash value will be the same. Problem: JS and CSS have the same hash value. Since CSS is introduced in JS, it belongs to the same chunk as CONTenthash. To sum up, there are two steps to enable cache: 1. Setting cacheDirectory: true 2. Add contenthash */ to the output array

// Define the nodeJS environment variable: Determines which environment to use browserslist
process.env.NODE_ENV = 'production';

/ / reuse loader
const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader', {
    // You also need to define browserslist in package.json
    loader: 'postcss-loader'.options: {
      ident: 'postcss'.plugins: () = > [require('postcss-preset-env') (the)]}}];module.exports = {
  entry: './src/js/index.js'.output: {
    filename: 'js/built.[contenthash:10].js'.// Where this section is modified
    path: resolve(__dirname, 'build')},module: {
    rules: [{
      // In package.json eslintConfig --> Airbnb
      test: /\.js$/,
      exclude: /node_modules/.// Priority execution
      enforce: 'pre'.loader: 'eslint-loader'.options: {
        fix: true}}, {oneOf: [{
          test: /\.css$/,
          use: [...commonCssLoader]
        }, {
          test: /\.less$/,
          use: [...commonCssLoader, 'less-loader'] {},test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel-loader'.options: {
            presets: [['@babel/preset-env', {
                  useBuiltIns: 'usage'.corejs: {
                    version: 3
                  },
                  targets: {
                    chrome: '60'.firefox: '50'}}]],// Enable the Babel cache
            // On the second build, the previous cache is read
            cacheDirectory: true // The position modified in this section}}, {test: /\.(jpg|png|gif)/,
          loader: 'url-loader'.options: {
            limit: 8 * 1024.name: '[hash:10].[ext]'.outputPath: 'imgs'.esModule: false}}, {test: /\.html$/,
          loader: 'html-loader'
        }, {
          exclude: /\.(js|css|less|html|jpg|png|gif)/,
          loader: 'file-loader'.options: {
            outputPath: 'media'}}]}]},plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.[contenthash:10].css' // Where this section is modified
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html'.minify: {
        collapseWhitespace: true.removeComments: true}})].mode: 'production'.devtool: 'source-map'
};
Copy the code

3. Run the command: webpack

5.5 the tree shaking

  1. Modifying a Configuration File
const {
  resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

/* tree shaking: Make code smaller 2. Enable production environment effects: reduce code size in package.json: Problem: It is possible to dry out CSS / @babel/polyfill files, so use the following line "sideEffects": ["*.css", "*.less"] (adding this sentence does not remove CSS and less files) */

process.env.NODE_ENV = 'production';

const commonCssLoader = [
  MiniCssExtractPlugin.loader,
  'css-loader', {
    loader: 'postcss-loader'.options: {
      ident: 'postcss'.plugins: () = > [require('postcss-preset-env') (the)]}}];module.exports = {
  entry: './src/js/index.js'.output: {
    filename: 'js/built.[contenthash:10].js'.path: resolve(__dirname, 'build')},module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      enforce: 'pre'.loader: 'eslint-loader'.options: {
        fix: true}}, {oneOf: [{
        test: /\.css$/,
        use: [...commonCssLoader]
      }, {
        test: /\.less$/,
        use: [...commonCssLoader, 'less-loader'] {},test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'.options: {
          presets: [['@babel/preset-env', {
                useBuiltIns: 'usage'.corejs: {
                  version: 3
                },
                targets: {
                  chrome: '60'.firefox: '50'}}]],cacheDirectory: true}}, {test: /\.(jpg|png|gif)/,
        loader: 'url-loader'.options: {
          limit: 8 * 1024.name: '[hash:10].[ext]'.outputPath: 'imgs'.esModule: false}}, {test: /\.html$/,
        loader: 'html-loader'
      }, {
        exclude: /\.(js|css|less|html|jpg|png|gif)/,
        loader: 'file-loader'.options: {
          outputPath: 'media'}}}}]],plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.[contenthash:10].css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html'.minify: {
        collapseWhitespace: true.removeComments: true}})].mode: 'production'.devtool: 'source-map'
};
Copy the code
  1. Run instruction: webpack

5.5 code the split

Multientry file

  1. Modifying a Configuration File
const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // Single entry package output a file, multi-entry package output multiple files, there are several entries package output how many files
  // Single entry (single page application uses single entry) (single entry application uses more during development)
  // entry: './src/js/index.js',
  entry: {
    // Multiple entries: There is one entry, and the final output has a bundle (multi-page applications use multiple entries)
    index: './src/js/index.js'.test: './src/js/test.js'
  },
  output: {
    // [name] : select a file name (for example, if the entry name is index, the output file name will have index name)
    filename: 'js/[name].[contenthash:10].js'.path: resolve(__dirname, 'build')},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.minify: {
        collapseWhitespace: true.removeComments: true}})].mode: 'production'
};
Copy the code
  1. Run instruction: webpack

Single entry file split multiple files -1

  1. Modifying a Configuration File
const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  / / a single entrance
  // entry: './src/js/index.js',
  entry: {
    index: './src/js/index.js'.test: './src/js/test.js'
  },
  output: {
    // [name] : Indicates the name of the file
    filename: 'js/[name].[contenthash:10].js'.path: resolve(__dirname, 'build')},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.minify: {
        collapseWhitespace: true.removeComments: true}})]./* 1. The node_modules code can be packaged in a separate chunk of final output (other people's third-party stuff is packaged separately, own stuff is packaged separately) 2. Automatic analysis of multi-entry chunks, whether there are public files. 3. This single-entry form is not often used */
  optimization: {
    splitChunks: {
      chunks: 'all'}},mode: 'production'
};
Copy the code
  1. Run instruction: webpack

Single entry file Output multiple exit files -2 (common)

  1. Modifying a Configuration File
const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  / / a single entrance
  entry: './src/js/index.js'.output: {
    // [name] : Indicates the name of the file
    filename: 'js/[name].[contenthash:10].js'.path: resolve(__dirname, 'build')},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.minify: {
        collapseWhitespace: true.removeComments: true}})]./* 1. This form of single entry is often used to achieve functions: single entry package output multiple exit files, thus making multiple files run in parallel, increasing the speed of operation 2. In this way, the node_modules code can be separately packaged into a chunk final output, and the import file can be packaged into an export file. If you want to package an independent file into a file, you need to perform the following configuration: 1. Optimization configuration 2. Enter the relevant code */ in the packaged export file for files that need to be packaged separately
  optimization: {
    splitChunks: {
      chunks: 'all'}},mode: 'production'
};
Copy the code
  1. Entry file input code
function sum(. args) {
  return args.reduce((p, c) = > p + c, 0);
}

/* Dynamic import syntax: webpackChunkName: webpackChunkName: 'test' is used to name the output package. Otherwise, the package name will be named according to the OUTPUT ID of each package. Each package output will have a different ID and name
import ( /* webpackChunkName: 'test' */ './test')
.then(({ mul, count }) = > {
    // The file is successfully loaded ~
    // eslint-disable-next-line
    console.log(mul(2.5));
  })
  .catch(() = > {
    // eslint-disable-next-line
    console.log('File load failed ~');
  });

// eslint-disable-next-line
console.log(sum(1.2.3.4));
Copy the code
  1. Run instruction: webpack

5.6 a lazy loading

  1. Modifying a Configuration File
const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  / / a single entrance
  entry: './src/js/index.js'.output: {
    // [name] : Indicates the name of the file
    filename: 'js/[name].[contenthash:10].js'.path: resolve(__dirname, 'build')},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.minify: {
        collapseWhitespace: true.removeComments: true}})]./* 1. This form of single entry is often used to achieve functions: single entry package output multiple exit files, thus making multiple files run in parallel, increasing the speed of operation 2. In this way, the node_modules code can be separately packaged into a chunk final output, and the import file can be packaged into an export file. If you want to package an independent file into a file, you need to perform the following configuration: 1. Optimization configuration 2. Enter the relevant code */ in the packaged export file for files that need to be packaged separately
  optimization: {
    splitChunks: {
      chunks: 'all'}},mode: 'production'
};
Copy the code
  1. Enter in the entry file
console.log('index.js file loaded ~');

// import { mul } from './test'; Normal loading

document.getElementById('btn').onclick = function() {
	// Lazy loading ~ : files are loaded only when they are needed
	// Preload webpackPrefetch: true: preloads the JS file before using it
	// Normal loading can be considered parallel loading (multiple files are loaded at the same time)
	// Prefetch: Wait until other resources are loaded and the browser is free, then secretly load the resources (poor compatibility) (check whether prefetch is loaded by opening the console and checking the network to see if it is preloaded)
	/* 1. In general, lazy loading takes a long time if the file to be loaded is large, which blocks the user. The implementation of lazy loading is based on the previous code segmentation. Lazy loading can only be used after the configuration of the previous code segmentation. The function of this case is to load the JS code in the test file after clicking the button. Lazy loading may be slower the first time, but not slower the second time. The first load will be cached, and the second load will be loaded directly from the cache
	import ( /* webpackChunkName: 'test', webpackPrefetch: true */ './test').then(({ mul }) = > {
		console.log(mul(4.5));
	});
};
Copy the code
  1. Run instruction: webpack

5.7 pwa

  1. Downloading the Installation package

npm install --save-dev workbox-webpack-plugin

  1. Modifying a Configuration File
const {
  resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');


const WorkboxWebpackPlugin = require('workbox-webpack-plugin');

/* PWA: progressive web development application (offline access) workbox --> workbox-webpack-plugin */

process.env.NODE_ENV = 'production';


module.exports = {
  entry: './src/js/index.js'.output: {
    filename: 'js/built.[contenthash:10].js'.path: resolve(__dirname, 'build')},module: {
    rules: []},plugins: [

    new WorkboxWebpackPlugin.GenerateSW({
      2. Delete the old ServiceWorker and generate a Serviceworker profile ~ */
      clientsClaim: true.skipWaiting: true})].mode: 'production'.devtool: 'source-map'
};
Copy the code
  1. Enter in the entry file
import { mul } from './test';
import '.. /css/index.css';

function sum(. args) {
  return args.reduce((p, c) = > p + c, 0);
}

// eslint-disable-next-line
console.log(mul(2.3));
// eslint-disable-next-line
console.log(sum(1.2.3.4));

{"env": {"browser": {"env": {"env": 2. Sw code must run on the server --> nodejs --> NPM I serve-g serve-s build Expose all resources in the build directory as static resources */
/ / register serviceWorker
// Handle compatibility issues
if ('serviceWorker' in navigator) {
  window.addEventListener('load'.() = > {
    navigator.serviceWorker
      .register('/service-worker.js')
      .then(() = > {
        console.log('Sw registered successfully ~');
      })
      .catch(() = > {
        console.log('SW registration failed ~');
      });
  });
}
Copy the code

View the registered Service workersSuccessfully registered cached offline data4. Run the command: webpack

5.8 Multi-process Packaging

  1. Downloading the Installation package

npm install --save-dev thread-loader

  1. Modifying a Configuration File
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');


const WorkboxWebpackPlugin = require('workbox-webpack-plugin');//



module.exports = {
  entry: './src/js/index.js'.output: {
    filename: 'js/built.[contenthash:10].js'.path: resolve(__dirname, 'build')},module: {
    rules: [{oneOf: [{test: /\.css$/,
            use: [...commonCssLoader]
          },
          {
            test: /\.less$/,
            use: [...commonCssLoader, 'less-loader'] {},test: /\.js$/,
            exclude: /node_modules/,
            use: [
              /* Enable multi-process packaging. Process startup takes about 600ms and process communication is also overhead. Multi-process packaging is required only if the work takes a long time
              {
                loader: 'thread-loader'.options: {
                  workers: 2 // Process 2}}, {loader: 'babel-loader'.options: {
                  presets: [['@babel/preset-env',
                      {
                        useBuiltIns: 'usage'.corejs: { version: 3 },
                        targets: {
                          chrome: '60'.firefox: '50'}}]],cacheDirectory: true}}]}, {test: /\.(jpg|png|gif)/,
            loader: 'url-loader'.options: {
              limit: 8 * 1024.name: '[hash:10].[ext]'.outputPath: 'imgs'.esModule: false}}, {test: /\.html$/,
            loader: 'html-loader'
          },
          {
            exclude: /\.(js|css|less|html|jpg|png|gif)/,
            loader: 'file-loader'.options: {
              outputPath: 'media'}}]}]},plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.[contenthash:10].css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html'.minify: {
        collapseWhitespace: true.removeComments: true}}),new WorkboxWebpackPlugin.GenerateSW({
      clientsClaim: true.skipWaiting: true})].mode: 'production'.devtool: 'source-map'
};
Copy the code
  1. Run instruction: webpack

5.9 externals

  1. Modifying a Configuration File
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')},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})].mode: 'production'.externals: {
    If jequery uses CDN links, jQuery will not be packaged and CDN links will be used directly
    jquery: 'jQuery'}};Copy the code
  1. Run instruction: webpack

5.10 DLL

  1. Create the webpack.dll.js file and enter
/* Use DLL technology for some libraries (third-party libraries: jquery, React, vue...) When you run webpack, the default is to look for the webpack.config.js configuration file. Requirements: need to run webpack.dll

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

module.exports = {
  entry: {
    [name] --> jquery
    // ['jquery'] --> The library is jquery
    jquery: ['jquery'],},output: {
    filename: '[name].js'.path: resolve(__dirname, 'dll'),
    library: '[name]_[hash]' // What is the name of the contents exposed in the packaged library
  },

  plugins: [
    // Package to generate a manifest.json --> provide and jquery mapping
    new webpack.DllPlugin({
      name: '[name]_[hash]'.// The exposed content name of the mapping library
      path: resolve(__dirname, 'dll/manifest.json') // Output file path})].mode: 'production'
};
Copy the code
  1. Run the command: webpack –config webpack.dlL.js
  2. Modify the configuration file webpack.config.js
const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');

module.exports = {
  entry: './src/index.js'.output: {
    filename: 'built.js'.path: resolve(__dirname, 'build')},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    // Tell Webpack which libraries are not included in the package, and change their names when used
    new webpack.DllReferencePlugin({
      manifest: resolve(__dirname, 'dll/manifest.json')}),// Package a file and import the resource automatically in HTML
    new AddAssetHtmlWebpackPlugin({
      filepath: resolve(__dirname, 'dll/jquery.js')})],mode: 'production'
};

/* The webpack plugin should be introduced in webpack.dll. Write the library we need to package in the webpack.dll. Js file and the name of the output of the packaged library. As long as the name of the jquery library stays the same after the first packaging, the next time you don't need to repackage it, you can use it directly to speed up the construction. Json file generated in plugin represents jquery mapping. 3. DllReferencePlugin is used in webpack.config.js to tell Webpack which files do not need to be repackaged. Webpack. Config. Used in js AddAssetHtmlWebpackPlugin will ebpack. DLL. Packaged in js automatically introduce * / resources in HTML
Copy the code
  1. Run instruction: webpack

Vi. Webpack configuration details

6.1 entry

const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

String --> './ SRC /index.js' (often used) Single entry package to form a chunk. Output a bundle file. The default chunk name is main 2. array -> ['./ SRC /index.js', './ SRC /add.js']. --> Hot HTML updates are available only in the HMR function. The chunk name is key --> special usage {// All the import files will end up as a chunk, and only one bundle will be exported. Index: ['./ SRC /index.js', './ SRC /count.js'], // form a chunk and output a bundle file. add: './src/add.js' } */

module.exports = {
  entry: {
    index: ['./src/index.js'.'./src/count.js'].add: './src/add.js'
  },
  output: {
    filename: '[name].js'.path: resolve(__dirname, 'build')},plugins: [new HtmlWebpackPlugin()],
  mode: 'development'
};
Copy the code

6.2 the output

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js'.output: {
    // File name (specify name + directory)
    filename: 'js/[name].js'.// Output file directory (public directory for future output of all resources)
    path: resolve(__dirname, 'build'),
    / / all resources into public path prefix -- > 'imgs/a. pg' - > '/ imgs/a. pg'
    publicPath: '/'.chunkFilename: 'js/[name]_chunk.js'.// The name of the non-entry chunk
    // library: '[name]', // the name of the variable exposed throughout the library
    // libraryTarget: 'window' // To which browser the variable name is added
    // libraryTarget: 'global' // to which node the variable name is added
    // libraryTarget: 'commonjs'
  },
  plugins: [new HtmlWebpackPlugin()],
  mode: 'development'
};

Copy the code

6.3 the module

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js'.output: {
    filename: 'js/[name].js'.path: resolve(__dirname, 'build')},module: {
    rules: [
      // Loader configuration
      {
        test: /\.css$/.// Multiple loaders use use
        use: ['style-loader'.'css-loader'] {},test: /\.js$/.// Exclude js files under node_modules
        exclude: /node_modules/.// Check only js files under SRC
        include: resolve(__dirname, 'src'),
        // Priority execution
        enforce: 'pre'.// The execution is delayed
        // enforce: 'post',
        // Single loader uses loader
        loader: 'eslint-loader'.options: {}}, {// Only one of the following configurations takes effect
        oneOf: []}]},plugins: [new HtmlWebpackPlugin()],
  mode: 'development'
};
Copy the code

6.4 resolve

const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js'.output: {
    filename: 'js/[name].js'.path: resolve(__dirname, 'build')},module: {
    rules: [{
      test: /\.css$/,
      use: ['style-loader'.'css-loader']]}},plugins: [new HtmlWebpackPlugin()],
  mode: 'development'.// Parse the module's rules
  resolve: {
    // Configure the path alias of the resolution module: advantage short path Fault path is not displayed
    alias: {
      $css: resolve(__dirname, 'src/css')},// Omit the file path suffix
    extensions: ['.js'.'.json'.'.jsx'.'.css'].// Tell WebPack which directory the parsing module is looking for (otherwise, it will go up a layer until it finds the location)
    modules: [resolve(__dirname, '.. /.. /node_modules'), 'node_modules']}};Copy the code

6.5 devserver

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/js/index.js'.output: {
    filename: 'js/[name].js'.path: resolve(__dirname, 'build')},module: {
    rules: [{test: /\.css$/,
        use: ['style-loader'.'css-loader']]}},plugins: [new HtmlWebpackPlugin()],
  mode: 'development'.resolve: {
    alias: {
      $css: resolve(__dirname, 'src/css')},extensions: ['.js'.'.json'.'.jsx'.'.css'].modules: [resolve(__dirname, '.. /.. /node_modules'), 'node_modules']},devServer: {
    // Directory to run the code
    contentBase: resolve(__dirname, 'build'),
    // Monitor all files in the contentBase directory and reload them if they change
    watchContentBase: true.watchOptions: {
      // Ignore files while monitoring
      ignored: /node_modules/
    },
    // Start gzip compression, small size
    compress: true./ / the port number
    port: 5000./ / domain name
    host: 'localhost'.// Automatically open the browser
    open: true.// Enable HMR
    hot: true.// Do not display startup server logs
    clientLogLevel: 'none'.// Do not display anything except some basic startup information
    quiet: true.// If there is an error, do not display a full-screen message ~, just print it in the log
    overlay: false.// Server proxy --> Resolve cross-domain issues in the development environment
    proxy: {
      // Once devServer(5000) receives a request for/API/XXX, it forwards the request to another server (3000).
      '/api': {
        target: 'http://localhost:3000'.// the request path is rewritten: / API/XXX --> / XXX (/ API)
        pathRewrite: {
          '^/api': ' '}}}}};Copy the code

6.6 optimization

const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin')

module.exports = {
  entry: './src/js/index.js'.output: {
    filename: 'js/[name].[contenthash:10].js'.path: resolve(__dirname, 'build'),
    chunkFilename: 'js/[name].[contenthash:10]_chunk.js'
  },
  module: {
    rules: [{
      test: /\.css$/,
      use: ['style-loader'.'css-loader']]}},plugins: [new HtmlWebpackPlugin()],
  mode: 'production'.resolve: {
    alias: {
      $css: resolve(__dirname, 'src/css')},extensions: ['.js'.'.json'.'.jsx'.'.css'].modules: [resolve(__dirname, '.. /.. /node_modules'), 'node_modules']},optimization: {
    splitChunks: {
      chunks: 'all'
        // Default value, can not write, basically not change ~
        /* minSize: 30 * 1024, // Chunks that are smaller than 30KB are not divided, and chunks that are larger than 30KB are not divided maxSiza: 0, // Maximum minChunks are not limited: MaxAsyncRequests: 3, // maxAsyncRequests: 4, // maxInitialRequests: AutomaticNameDelimiter: '~', // name connector name: true, // you can use the naming rule cacheGroups: {// Groups that split chunks // node_modules files are packaged into vendors group chunks. --> vendors~xxx.js // Satisfy the common rules written above, e.g., be cited at least once if the size is greater than 30KB. Vendors: {test: /[\\/]node_modules[\\/]/, // Priority: -10}, default: {// Chunks to be extracted are referenced minChunks at least 2 times: 2, // Priority: -20, // If the current module to be packaged is the same module that has already been extracted, it will be reused instead of reuseExistingChunk: true}}*/
    },
    // Package the hash of the current module into a single file runtime
    // Resolve: Modifying file A causes file B's contenthash to change
    runtimeChunk: {
      name: entrypoint= > `runtime-${entrypoint.name}`
    },
    minimizer: [
      // Configure the compression scheme for the production environment: JS and CSS
      new TerserWebpackPlugin({
        // Enable caching
        cache: true.// Enable multi-process packaging
        parallel: true./ / start the source - the map
        sourceMap: true}}})];Copy the code

7. Use webPack5

webpack5

This release focuses on the following:

  • Improve build performance with persistent caching.
  • Use better algorithms and defaults to improve long-term caching.
  • Improved bundle size with better tree shaking and code generation.
  • Clean up weird internal constructs while implementing functionality in V4 without introducing any major changes.
  • Prepare for future functionality by introducing significant changes that will allow us to use V5 for as long as possible.

download

  • npm i webpack@next webpack-cli -D

Automatically remove Node.js Polyfills

Early on, The goal of WebPack was to allow most Node.js modules to run in the browser, but the module landscape has changed and many module uses are now written primarily for front-end purposes. Webpack <= 4 comes with polyfills for many Node.js core modules, which are automatically applied once a module uses any core modules (i.e., crypto modules).

Although this makes it easy to use modules written for Node.js, it adds these huge polyfills to packages. In many cases, these polyfills are unnecessary.

Webpack 5 automatically stops populating these core modules and focuses on modules that are compatible with the front end.

The migration:

  • Try to use front-end compatible modules whenever possible.
  • You can manually add a polyfill for the Node.js core module. The error message will indicate how to achieve this goal.

Chunk and module ID

New algorithms for long-term caching have been added. These are enabled by default in production mode.

chunkIds: "deterministic", moduleIds: "deterministic"

Chunk ID

You don’t have to use import(/* webpackChunkName: “name” */ “module”) to name chunks in the development environment, but production is still necessary

Webpack has a chunk naming convention that is no longer named after id(0, 1, 2)

Tree Shaking

  1. Webpack can now handle tree shaking for nested modules
// inner.js
export const a = 1;
export const b = 2;

// module.js
import * as inner from './inner';
export { inner };

// user.js
import * as module from './module';
console.log(module.inner.a);
Copy the code

In a production environment, the b exposed by the inner module is removed

  1. Webpack is now capable of multiple module previous relationships
import { something } from './something';

function usingSomething() {
  return something;
}

export function test() {
  return usingSomething();
}
Copy the code

When “sideEffects”: false is set, if the test method is not used, not only test will be removed, but also “./something” will be removed.

  1. Webpack can now handle tree shaking for Commonjs

Output

Webpack 4 can only output ES5 code by default

Webpack 5 starts with a new property output.ecmaVersion, which generates ES5 and ES6 / ES2015 code.

Such as: the output ecmaVersion: 2015

SplitChunk

// webpack4
minSize: 30000;
Copy the code
// webpack5
minSize: {
  javascript: 30000.style: 50000,}Copy the code

Caching

// Configure the cache
cache: {
  // Disk storage
  type: "filesystem".buildDependencies: {
    // The cache is invalid when the configuration is changed
    config: [__filename]
  }
}
Copy the code

The cache is stored in node_modules/.cache/webpack

Monitor output file

Previously, WebPack always exported all files on the first build, but only modified files were updated when monitoring a rebuild.

This update will find the output file on the first build to see if it has changed, so it can decide whether to output the entire file.

The default value

  • entry: "./src/index.js
  • output.path: path.resolve(__dirname, "dist")
  • output.filename: "[name].js"

More content

Github.com/webpack/cha…

References:

  1. Silicon Valley Video

Thanks to Silicon Valley Video for this video

  1. The great spirit of notes