webpack learning notes

webpack function: handle code compression confusion, browser js compatibility and performance optimization

webpack installation process in the project

1,

NPM I webpack webpack cli - g / / global installation of webpack (required)

npm i Webpack@5.42.1 Webpack- cli@4.7.2 -D / / partially install Webpack to the project (required)

2,

webpack.config.js configuration

/* 
webpack.config.js:Indicates what the webpack does (the contents will be loaded when you run the webpack instruction)
        Note: all construction tools are modularized based on node.js platform, and commonjs is adopted
 */
const { resolve } = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin"); //New template skeleton plug-in
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //Introduce a plug-in to extract css from js
const WorkboxWebpackPlugin=require("workbox-webpack-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); //Compression css plug-in
​
//If the browserlist wants to develop the pattern, you need to set the environment variable of nodejs
process.env.NODE_ENV = "development";
​
/* 
Cache:
  babel Cache:
    Set cacheDirectory:true,    Function: enable caching mechanism. Make the second packing faster
  File resource cache:
    hash Each webpack build generates a unique hash value
      Problem: because css and js use the same hash value, repackaging will invalidate all caches
            But I may have changed only one file
      Solution: Chunkhash generates the hash value according to the packaging entry. The entrance is the same as the chunk
      Problem: css and js still have the same hash value, because css is introduced in js and all belong to the same chunk
      Final solution: use contenthash: generate hash value according to the file content. The hash value must be different if the file content is different (hash collision is not considered)
      Function: make code run online and cache better
*/
​
​
/* 
tree shaking(Tree shaking: remove the code that is not applied in the application to make the code smaller
 Prerequisites: 1. You must use es6 modularization. 2. Start the production environment
​
  Configure "sideeffects" in package.json: false means that all code can be "tree shaken" without side effects, which may shake css or js files by mistake
  Example: if you don't want to shake the css file, configure "sideeffects" in package.json: ["*. css"]
*/
​
/* 
PWA(Offline access technology): workbox webpack plugin
​
*/
/* Reuse css */
const commonCssLoader = [
  //Create a style tag in the page, insert the 'style string' in js into the tag and add it to the head
  // "style-loader",
  /*
  Instead of style loader, css in js is extracted as a separate file, and html is automatically introduced
  Turn the CSS file into a commonjs module and load it into js, where the content is style string 
  */
  MiniCssExtractPlugin.loader,
  "css-loader",
​
  /* 
  Solve CSS compatibility problem: postcss loader -- > postcss preset env 
  Help postcss find the configuration in the browser list in package JSON and load the specified compatibility through the configuration
  */
​
  //Modify the configuration as an object      Browserlist defaults to production mode, which is independent of mode
​
  {
    loader: "postcss-loader",
    options: {
      ident: "postcss",
      plugins: () => [
        //postcss plug-in
        require("postcss-preset-env")(),
      ],
    },
  },
],;
​
​
​
module.export = {
  entry: "./src/index.js",    //Single page single entry
/* 
  entry: {
    index:"./src/index.js",
    text:"./src/text.js"          //Multiple pages, multiple entries, one entry generates a bundle.js file kv form
  },
*/
  output: {
    //[name] used in case of multiple entries of file name     1 strong 2
    filename: "js/[name].[Contenthash:10].js", //Output file name
    path: resolve(__dirname, "build"), //_ dirname is the absolute directory path of the current file (i.e. Webpack)
  },
  //Configuration of loader
  //Different loader s should be configured for different files
  module: {
    rules: [
      {
        /* Syntax check of js eslint loader eslint 
          Note: only check the source code written by yourself, and the third-party library does not need to be checked
          Check rules are set in package.json and eslintConfig
          "eslintConfig":{
            "extends":"airbnb-base"     Inherit the rules in the downloaded airbnb base library
          }
​
          airbnb The rule requires three plug-ins: eslint config airbnb base, eslint, and eslint plugin import
        */
        test: /\.js$/,
        exclude: /node_modules/, //Troubleshooting check for errors in third-party libraries
        loader: "eslint-loader",
        enforce:'pre',     //Generally, one loader executes one file. If enforce is set to pre, it means that the loader executes first
        options: {
          //Automatically fix syntax errors in js
          fix: true,
        },
      },
      /* 
      oneOf Only one loader can be used to process files of one type, and two configurations cannot process files of the same type. If two are needed, extract them outside oneOf
      Prevent a file from being repeatedly executed by multiple loader s. Optimize packaging speed for production environments
      */
    ],
      oneOf:[
        {
          //Match files with CSS suffix
          test: /\.css$/,
          //The order of loader execution in the use array: right to left, bottom to top
          use: [
            ...commonCssLoader
          ],
        },
        {
          test: /\.less$/,
          //use multiple loader s
          use: [
             ...commonCssLoader,          //... commonCssLoader to expand commonCssLoader
            "less-loader", //Less loader converts less files into css files
          ],
        },
  
        {
          test: /\.(png|jpg|gif)$/,
          loader: "url-loader", //Process img pictures in style files
          //Use a loader to download a file loader, usually use
          options: {
            //If the image size is less than 8kb, it will be processed by base64
            //The advantage of base processing is to reduce the number of requests and reduce the pressure on the server. The disadvantage is that the picture size becomes larger and the picture request speed becomes slower
            limit: 8 * 1024,
            /* 
            Because the URL loader uses es6 parsing by default, and the picture introduced by HTML loader is commonjs, there will be conflicts during parsing
            All es6 parsing of URL loader is closed and common JS parsing is adopted
            */
            esModule: false,
            //The picture name is too long. Use name to rename
            name: "[hash:10].[ext]",
            outputPath: "imgs",
          },
        },
        {
          test: /\.html$/, //Process img pictures in HTML
          loader: "html-loader",
          outputPath: "imgs",
        },
        {
          //Packaging other resources and excluding common resources are other resources
          exclude: /\.(html|css|js)$/,
          loader: "file-loader",
          options: {
            limit: 8 * 1024,
            esModule: false,
            name: "[hash:10].[ext]",
          },
          outputPath: "media",
        },
        {
          /*
          js Compatibility handling: 
          babel-loader  @babel/core
           1.@babel/preset-env Simple js syntax es6 such as promise can be solved, but presets compatible with options cannot be solved
          2.@babel/polyfill    Directly import '@babel/polyfill' in the required js file, but the file size is large
          3.core-js   On demand allocation (best scheme 1 + 3) use the third one, but not the second one
          */
          text: /\.js$/,
          exclude: /node_modules/, //Exclude checking third-party libraries
          loader: ": babel-loader",
          options: {
            //Presets: indicates how babel is js compatible
            presets: [
              "@babel/preset-env",
              //On demand distribution
              {
                useBuiltIns: "usage",
                //Specify the core JS version
                corejs: {
                  version: "3",
                },
                //Specify which version of browser to use
                target: {
                  chrome: "60",
                  firefox: "60",
                  ie: "9",
                  safari: "10",
                },
              },
            ],
            //Enable the babel cache, and the second build will read the cache first to improve the speed
            cacheDirectory:true,
          },
        },
​
      ]
  },
  //plugins is introduced one step more than loader
  plugins: [
    new HtmlWebpackPlugin({
      option:{
        title:'I'm a web page title'
      },
      template: "./src/index.html", //Create an HTML template with index.html and introduce all resources for packaged output
      minify: {
        //Compress html code
        //Remove spaces
        collapseWhitespace: true,
        //Remove comment
        removeComments: true,
      },
    }),
    new MiniCssExtractPlugin({
      //Rename packaged css
      filename: "/css/main.[Contenthash:10].css",
    }),
    new OptimizeCssAssetsWebpackPlugin(), //Compress css files
​
    new WorkboxWebpackPlugin.GenerateSW({
      /* 1,Help service worker start quickly
        2,Delete old serviceworker
        Generate a serviceworker configuration file    
      */       
      clientsClaim:true,      
      skipWaiting:true
    })
  ],
  /*
  For js files
   Single entry node_ The code in module is separately packaged into a chunk + entry chunk output          Realize parallel loading and improve running speed
   Multi entry automatically analyzes whether there are public files in the multi entry chunk. If yes, it will be packaged into a single chunk
    optimization Only meaningful in the production environment, except chunk:'all' is the default configuration
   */
  optimization:{
    splitChunks:{
      chunk:'all',
      miniSize:'30*1024',    //Greater than the minimum will be split
      maxSize:'0',        //Unlimited size
      miniChunk:'1',      //The chunk to be extracted is referenced at least once
      maxAsyncRequests:'5',  //When loading on demand, the maximum number of parallel loads is 5
      maxInitialRequests:'3',   //Entry js Max and behavior 3
      autoMaticNameDelimiter:'~',  //The name connector is~
      name:true,           //You can use naming rules
      cacheGroups:{
        //Split chunk s
          /* 
          >............<Omit configuration
          */
      }
    },
    runtimeChunk:{
      //The current module records the hash es of other modules and packs them into a file separately. The runtime solves the change of the content chat of the b file caused by the change of the a file
      name:entrypoint=>`runtime-${entrypoint.name}`
    }
  },
  mode: "development",
  resolve:{
    alias:{
      $css:resolve(__dirname,'src/css'),   //Set the path alias to $css to optimize the short path
    },
    extensions:['.js','.json','css'],    //The suffix of the configuration file path is omitted, and what is omitted is added
    modules:[resolve(__dirname,'../Webpack/node_modules'),'node_modules'],           //Specifies the directory of the webpack resolution module
  },
  externals:"jquery",      //The final bundle does not package jquery
​
  /* 
  Development server devServer: automatically compile, open the browser, and refresh the browser
  Features: only compile and package in memory, no output
  The instruction to start devServer is: npx webpack dev server (because the download is local, you need to start the dev server with npx)
  The normal packaging instruction is: webpack -- mode = development
          Note: the webpack configuration has been modified and will not take effect until the service is restarted
  */
  devServer: {
    //Directory path after construction
    contentBase: resolve(__dirname, "build"),
    //Monitor the built directory and automatically reload once the file changes
    watchContentBase:true,
    //Ignore file change options
    watchOptions:{
      ignored:/node_module/,
    },
    //Starting gzip compression makes your code run faster
    compress: true,
    //Port number of the development server
    port: 5000,
    //Automatically open default browser
    open: true,
    // HMR: hot module replacement function: when a module changes, only one module will be repackaged instead of all modules. Improve construction speed
    hot:true,
    //Turn off server startup log
    clientLogLevel:'none',    
    //Do not display any information except the basic startup information    It is generally used in conjunction with clientLogLevel:'none'
    quiet:true,
    //If an error occurs, do not prompt full screen
    overlay:false, 
    //Server agent (solve the cross domain problem). Once devsevery receives the request starting with. / api, forward it to ' http://localhost:3000 'processing on server
    proxy:{
      './api':{
        target:'http://localhost:3000',
        pathRewrite:{
          '^/api':'',    //Remove the api when rewriting path forwarding
        }
      }      
    }              
  },
​
  devtool:'source-map'   //Optimized debugging
  /* 
  What is the difference between inline and external:external

3. Add dev and bulid commands under the script node of package JSON to package

  
  "scripts": {
    "dev": "webpack serve",
    "build": "webpack --mode production"
  },

4. Output the package file according to the entry file, and then import the package file < script SRC = "/ bundle. JS" > < / script > where needed. It can be recognized that webpack helps us deal with compatibility problems. It is faster to modify the package file in memory

Default conventions in webpack

1. The default packaging entry is SRC - > index.js

2. The default output file path is dist - > main.js

View webpack and webpack cli versions

node_modules/.bin/webpack -v

node_modules/.bin/webpack-cli -v

Various plug-ins of webpack

#After installing dev server and modifying the source code, it will be automatically packaged without manual packaging, but the page will not be refreshed in real time

npm i webpack-dev-server -D

#Package html plug-in (require import)

npm i html-webpack-plugin -D

#html compression

minify setting in HtmlWebpackPlugin

When a webpack encounters a non. js file, it needs to be parsed by the corresponding loader plug-in

#The style loader plug-in uses base64 format pictures to prevent redundant picture loading requests, but the picture size will become larger

#Packaging picture resources in scripts

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

#Picture resources in packaging styles

npm i file-loader url-loader -D

#Pack pictures in skeleton

npm i html-loader -D

#Automatically clear old files in dist directory (plug-ins need to be imported)

npm i clean-webpack-plugin -D

#Extract css from js (plug-ins need to be imported)

npm i mini-css-extract-plugin -D

#Compressed css (plug-in to be introduced)

npm i optimize-css-assets-webpack-plugin -D

#css compatibility issues

NPM I postcss loader postcss preset env - D configure browserlist in packjson

#js syntax specification check

NPM I eslint loader eslint config airbnb base, eslint, eslint plugin import - D configure eslintConfig in packjson at the same time

#js compatibility issues

npm i babel-loader @babel/core @babel/plugin-proposal-decorators -D

The third plug-in replaceable scheme

(@ Babel / preset env solves the basic js compatibility problem) (@ babel/polyfill solves the compatibility problem of all es6 syntax) (core js solves the required js compatibility problem)

#js compression

js code is automatically compressed in production mode

#Multi process packaging (generally js)

npm i thread-loader -D

#Package a resource for output and introduce it into html

npm i add-asset-html-webpack=plugin -D

webpack optimization

1. Development environment performance optimization

(1) Optimize packaging and build speed: HMR hot module replacement. / / if only one module changes, it will only be rebuilt. Other modules use the previous cache (2) optimize code debugging: devtool: 'Eval source map' / (store the position (line number) before conversion corresponding to the compressed mixed code, and you can see the source code) for the development environment

Devtool: 'nosources source map' / / visible location invisible source code for production environment

2. Production environment performance optimization

(1) Optimize packing speed:

1, oneOf 2. babel cache / / cache the running results and open them faster for the second time. 3. Multi process packaging. 4. externals: prevent some packages from being finally packaged into the bundle (direct cdn link is required if they are not packaged at all). 5. dll: (dynamic connection Library). Package some libraries separately and package multiple libraries into a chunk (first, package it separately, tell webpack not to package it to improve efficiency, and introduce the package into html)

(2) Optimize code performance:

1, Cache (contenthash) / / cache the file. The second time, the cache speed is faster. 2. Tree shaking (the concept is not a plug-in or needs to be set) 1. es6 modularization must be used. 2. A plug-in in the production environment automatically starts tree shaking to remove the code that is not applied in the application and make the code volume smaller. 3. Single entry: only one chunk is introduced and only one bundle is output

optimization:{
    splitChunks:{
       chunk:'all'      //Generally, the node_module is split and packaged into a single bundle, generating two bundles in total
          } },              Then you can pass dll yes node_module The third-party libraries in are packaged again to be more detailed
​
   import("./text")
      .then((result) => {
         console.log('File loaded successfully'+result);      //Or split the specified js code through import
                  })
      .catch(() => {
           console.log("File loading failed");
                  });

4, Lazy loading / preloading v. NPM I workbox webpack plugin - D / / PWA (progressive network development application): content can be accessed offline ↑ serviceworker: to deal with compatibility problems, register a serviceworker in js

6, Package.json error file - preferences - Settings - applications - proxy Authorization modify or add "http.proxyAuthorization": "false"

Small tip: the module file operated during packaging is called chunk,

Many notes are personal understanding. If there is anything wrong, please give me more advice.

Keywords: Javascript Front-end Webpack

Added by oeb on Thu, 18 Nov 2021 14:51:51 +0200