About Webpack scattered summary for a long time, today to comb out written, which mainly contains the following knowledge points:

  • How to configure Webpack (distinguish packaging environment, start hot update, dynamic import, module parsing, etc.)
  • What does the Source Map contain? How to choose between a development environment and a production environment?
  • How to configure tree-shaking
  • Setting the cache mechanism
  • Differences between webpack4 and webpack5
  • HRM Principle of thermal renewal
  • Webpack build process
  • Webpack file details

Other relevant pages:

  1. Loader and Plugin (juejin. Cn)
  • The difference between plugin and Loader;
  • How to write plugin? Its principle;
  • How to write loader? Its principle;
  • Common plugins and loaders;
  1. Front-end optimization from webpack perspective (Juejin. Cn)

Hope to help you, at the same time found error welcome correction, thank you!!

First, webpack advanced configuration

Details can refer to the website, here are some important points extracted concept | webpack Chinese website (webpackjs.com)

Resource Modules (Asset Modules, new to webpack5)

Function:

  • Is a module type that allows resource files to be used without the need to configure additional loaders.
  • Resource files: fonts, images, ICONS, HTML…
  • Images and fonts can be loaded without file-loader or url-loader.

Webpack4 operation:

  • Raw-loader: imports a file as a string
  • File-loader: sends files to the output directory
  • Url-loader: sends files to the output directory or inlines them to the bundle as Data URIs (base64)

Webpack5 operation:

  • Asset/Resource: Send a single file and export the URL (previously achieved by using file-loader)
  • Asset /inline: Exports a resource’s data URI (previously implemented using urL-loader)
  • Asset /source: Export source code for the resource (previously implemented using raw-loader)
  • Asset: automatically selects between exporting a data URI and sending a separate file (url-loader)

Webpack Dev Serve

Purpose: To publish Web services and improve development efficiency

Webpack4: webpack – dev – server… Webpack5: webpack server…

Webpack4 Hot Update:

hot:true
Copy the code

Webpack5 hot update:

Webpack5 newliveReload:true(Can no longer use hot)target: 'web'(Hot updates only apply to Web-related targets)Copy the code

Proxy Configures the interface proxy

changeOrigin:true
Copy the code

Differentiate packaging environment

  1. Distinguished by environment variables
  • webpack –env.production
  • Check env in webpack.config.js
  1. Distinguish by configuration file
  • webpack.dev.conf.js
  • webpack.prod.conf.js
  • Webpack.base.conf.js (common configuration)

Webpack-merge merges multiple configurations together

Set environment variables on the command line

  • Webpack4: webpack — env. Production
  • Webpack5: Webpack — Env Production

webpack.config.js

  • Read the environment variable env.production
  • Specify different configurations based on environment variables
webpack.config.js 

module.exports = (env, argv) = > {
    cosnt config = {mode:'development'}
    if(env production){
        config.mode = 'production'. }return config
}
Copy the code

Extract common modules

optimization: {
    splitChunks: {
        chunks:'all'}}Copy the code

Dynamic import

Lazy loading: It is not loaded by default and is loaded only after an event is triggered.

WebpackChunkName: ‘Load name’

document.getElementId('btn').onclick = function(){
//import starts lazy loading
//webpackChunkName: 'desc' specifies the lazy file name
//webpackPrefetch: true starts preloading
    import(/*webpackChunkName: 'desc', webpackPrefetch: true */'test').then(() = >{
        console.lo('I'm only loading the test file here so I can call something in that file.')})}Copy the code

Preloading: Wait for other resources to load and then load webpackPrefetch when the browser is idle: true Disadvantages: Compatibility problems on mobile devices

Source Map

Mapping mode (devtool value)

  • Different mapping modes have different error locating effect and packaging execution speed
  • In webpack4, there are 13 different mapping modes
  • In webpack5, there are 26 different mapping modes

Naming updates in webpack5 are strict

^(inline-|hidden-|eval-)? (nosources-)? (cheap-(module-)?) ? source-map$

model describe
cheap Locate only the error column, not the error column
hidden Generate.map file, but the end of.js is not associated with.map, after the error report, you need to manually associate, and then locate the error report
inline Instead of generating a.map file, the mapping is added to the end of the.js as base64-VLqs
eval Instead of generating a. Map file, the mapping information is appended to the end of the eval function to correlate the relationship before and after processing
module Not only mapping engineers write their own code, but also support the mapping of Loader and third-party modules
nosources SourceContent is not included in the.map, the source cannot be seen when locating errors (safer)

13 common patterns for webpack4

Webpack5 has 26 modes although more rich, but the key words remain the same, more than a few permutations and combinations, although there are many modes, but many modes are not effective now, webpack5 updated content, is to pave the way for the future.

How to choose the appropriate mapping pattern (this is personal advice, but not absolute)

  • Development environment: eval-cheap-module-source-map
  • Production: none | nosources – source – the map

If you want to see error location in the build environment, you can also use cheap-module-source-map in the build environment

Reasons for this choice:

  • Eval is quickly rebuilt, so you can add eval properties to the local environment.
  • Using eval-source-map makes packaged files too large to be used in production environments

tree-shaking

Tree-shaking was earlier implemented by Rich_Harris rollup, and later, Webpack2 introduced tree-shaking functionality, essentially removing useless JavaScript code. I don’t think so, CSS is not the ES Modules specification.

The tree – shaking principle:

Package all code into a scope, then iterate over all scopes, removing unused scopes (Webpack principle: iterate over all imported modules, package them into a file, in the process, know which export modules are used)

Based on static references to ES6, Treeshaking scans all ES6 exports to find what is being imported and adds it to the final code.

Note:

  • Tree-shaking is performed using Modules with the ES Modules specification. Because tree-shaking relies on static parsing in ES Modules
  • Cannot delete execute now functions to avoid using IFEE
  • If you are using a third-party module, try using it directly from the file path

Tree shaking ES6

Because of ES6 modules, ES6 module dependencies are deterministic, independent of the state of the runtime, and can be reliably analyzed statically, making it easy to get rid of duplicate code. This is the foundation for Tree Shaking.

How to use:

  • Production mode: tree-shaking is enabled automatically
  • Development mode:
  1. usedExports
  2. sideEffects

1. usedExports

optimization: {
    /*unused harmony export XXXX */
    usedExports:true.// Delete the unused Harmony export XXXX flag
    minimize:true.Terser-webpack-plugin: WebPack4 needs to be installed separately, while WebPack5 needs to be imported
    minimizer: [new TerserPlugin()]
}
Copy the code

Optimization.usedexports (marks unused code), unused code packaged with a comment /*unused Harmony export XXXX */

Optimization. Minimize: true (delete unused harmony export XXXX tag code)

Terser-webpack-plugin (remove the extra debuger in the project) Webpack4 needs to be installed separately.

Tree Shaking is incompatible with Source Map:

Tree Shaking support only devtool: source – the map | inline – source – the map | hidden – source – the map | nosources – source – the map;

Tree Shaking is invalid because of eval mode, which outputs JS as a string (not the ES Module specification)

2. There are sideEffects

No side effects: if a module simply imports and exports variables, it has no side effects

Side effects: There are side effects if a module also modifies other modules or something global

  • Modifying global variables
  • Extend the method on the prototype
  • Introduction of CSS (e.g. for HTML)

SideEffects removes unused modules that have no sideEffects

For modules with no side effects, unused code is not packaged (equivalent to compressed output)

Turn on side effects:

optimization: {
    sideEffects:true
}
Copy the code

Identify if the code has sideEffects (set sideEffects in package.json) :

  • True: All code has side effects
  • False: All code has no side effects (tells Webpack it can safely remove unused exports)
  • Array :(tells webpack which modules have side effects and does not remove them)
// For example, true
  sideEffects:true
// For example, array
   sideEffects: ['.src/test.js'.'*.css']
Copy the code

Webpack Tree shaking

Caching mechanisms

Babel cache:

  • CacheDirectory :true On a second build, the previous cache is read

File resource cache:

  • If the code is in the cache, the code will not be updated in real time
  • Solution: Set the name of the code file to a hash name, and load the latest content when the name changes

Webpack hash:

  • Hash Hash value generated each time webpack is packaged
  • Chunkhash The hash value of different chunks varies. Different chunks may be generated in the same package
  • Contenthash Different contents have different hash values. Different contents may exist in the same chunk
//8 indicates the hash number
[name].[contenthash:8].js
[name].[contenthash:8].css
Copy the code

Resolve resolve

  • Configure rules for module resolution
  • Alias: indicates the alias of the loading path of the module
alias:{The '@':resolve('src')}
Copy the code
  • Extensions: Which suffixes can be omitted when introducing modules
Extensions:'js'.'json']
Copy the code

There are others, please see the official website

Exclude externals

  • Exclude packaging dependencies to prevent packaging of a dependency
  • In general, some mature third-party libraries, such as jquery, do not need to be packaged and can be directly imported into the CDN

Module federal

Webpack5 module federation enables Webpack to achieve the effect of online Runtime, so that code can be directly shared between projects using CDN, and there is no need to install Npm package locally, build and publish.

const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  // other webpack configs...
  plugins: [
    new ModuleFederationPlugin({
      name: "app_one_remote".remotes: {
        app_two: "app_two_remote".app_three: "app_three_remote"
      },
      exposes: {
        AppContainer: "./src/App"
      },
      shared: ["react"."react-dom"."react-router-dom"]}),new HtmlWebpackPlugin({
      template: "./public/index.html".chunks: ["main"]]}});Copy the code
Call import {Search} from "app_two/Search";Copy the code

The ModuleFederationPlugin has several important parameters:

  1. Name Indicates the name of the current application. The value must be globally unique
  2. Remotes maps the names of other projects to the current project
  3. An exposes represents an exported module, and only the module declared here can be used as a remote dependency
  4. Shared is an important parameter that allows remotely loaded modules to change their dependencies to use the React or ReactDOM of the local project

Two, webpack advanced detailed knowledge

Differences between webpack4 and webpack5

  1. Hot update

Webpack4: webpack – dev – server… Webpack5: webpack server…

Webpack4 Hot Update:

hot:true
Copy the code

Webpack5 hot update:

Webpack5 newliveReload:true(Can no longer use hot)target: 'web'(Hot updates only apply to Web-related targets)Copy the code
  1. The source map mode is written differently

13 common patterns for webpack4

26 common patterns for webpack5

Check the official website for details.

  1. Use sideEffects usedExports
optimization: {
    /*unused harmony export XXXX */
    usedExports:true.// Delete the unused Harmony export XXXX flag
    minimize:true.Terser-webpack-plugin: WebPack4 needs to be installed separately, while WebPack5 needs to be imported
    minimizer: [new TerserPlugin()]
}
Copy the code

Terser-webpack-plugin needs to be installed separately for WebPack4 (Webpack5 does not need to be installed, but needs to be introduced to use)

  1. Webpack5 provides built-in caching

Webpack5 built-in cache solution exploration _ Chase, blog -CSDN blog _webpack5 cache

Webpack4 cache scheme: cache-loader, DLL Webpack5 cache scheme:

  • IdleFileCachePlugin: Persistent to the local disk
  • MemoryCachePlugin: Persist to memory

Webpack5’s built-in caching scheme is better than cache-loader in terms of performance and security:

  • On the performanceSince all modules processed by WebPack are cached, cache coverage is much higher
  • On the security: Because cache-loader uses mtime-based cache validation mechanism, the cache is often invalid in CI environment. However, Webpack5 uses eTAG based cache validation mechanism to solve this problem. The Webpack5 configuration is available on the official website.
  1. Webpack5 adds module federation

  2. Disable the default ES Modules specification of urL-loader and force url-loader to use the CommonJS specification for packaging

In Webpack4, only the URl-loader configuration esModule:false is required

Webpack5 requires esModule:false for both html-loader and url-loader

The Thermal renewal (HRM) principle

Webpack HMR Principle Analysis – Zhihu (zhihu.com)

Summarize the main points:

  1. A websocket long connection is established between the browser and the server, and the status information of each stage of Webpack compilation and packaging is informed to the browser
  2. Through JsonpMainTemplate. Runtime sends an Ajax request to the server end, the server returns a json, the json contains all the hash value to update the module, access to the updated list, the moduleThe latest module code is obtained through the JSONP request again

Optimize Webpack build speed?

Webpack5 Performance Optimization – Optimize build Speed – Cloud + Community – Tencent Cloud (Tencent.com)

How can bundle volumes be monitored and analyzed?

  1. VSCode has a plug-in import cost that helps us monitor the size of imported modules in real time

  2. Webpack-bundle-analyzer generates a diagram of the bundle’s module composition, showing its volume

Webpack Build Process (Packaging Principles Final edition)

The resulting webpack file is an immediate self-executing function whose input parameter is an array that contains all modules wrapped in the function.

Webpack essentially creates an environment where each module can be exported and imported, without changing the logic of the code’s execution, and in exactly the same order as the module loads.

Build the AST syntax tree by parsing the files from the entry file configured in the WebPack configuration file, finding out which files each file depends on, recursively, and finally packaging them into a single file.

Simple WebPack packaging principle:

  1. Initialization: start build, read and merge configuration parameters, load Plugin, instantiate Compiler
  2. Compilation: Starting from Entry, the corresponding Loader is successively called for each Module to translate the content of the file, and then the Module that the Module depends on is found and compiled recursively
  3. Output: Combine compiled modules into chunks, convert chunks into files, and output them to the file system
/** * Initialization preparation, obtain module contents, analyze module, collect dependencies, convert ES6 to ES5 via Babel to form more AST, recursively obtain all dependencies ** initialization preparation, obtain module contents * analyze module: The obtained module contents are parsed into an AST syntax tree (@babel/ Parser). The AST is a reference path collection dependency: it collects file paths imported with import statements. We put the collected paths into the DEPS, and put the file directory paths with the obtained values into the dePS (@babel/traverse) * ES6 into ES5 (AST) : (@babel/ core@babel /preset-env) * Recursively get all dependencies: this object includes the module's path (file), the module's dependencies (DEPS), the module is converted to ES5 code; Bundle code: The purpose is to generate a bundle.js file, which is a packaged file. The idea is simply to integrate the contents of index.js with its dependencies. The code is then written to a new JS file. Initialize parameters: Read and merge parameters from configuration files and Shell statements to get the final parameters and start compiling: Initialize the Compiler object with the parameters obtained in the previous step, load all the configured plug-ins, and execute the object's run method to start compiling. Starting from the entry file, call all configured Loader to translate the module, find out the module that the module depends on, and then recurse this step until all the entry dependent files have gone through the processing of this step and complete module compilation: After using Loader to translate all modules in Step 4, the final translated content of each module and the output resources of their dependencies are obtained: According to the dependency between the entry and the modules, the chunks containing multiple modules are assembled one by one, and then each Chunk is converted into a separate file and added to the output list. This step is the last chance to modify the output content. After determining the output content, determine the output path and file name according to the configuration, and write the file content to the file system. The running process of Webpack is a serial process, from start to finish, the following processes will be executed successively: initialize parameters according to the configuration file, load all configured plug-ins, execute the run method of the object to start compiling; * At the same time, according to the configuration to determine the entry file, starting from the entry file, call all configured Loader to translate the module (including CSS into JS, ES6 into ES5), and find out the module dependent module, recursive processing; * According to the output source code, file dependencies, and finally packaged into a file */Copy the code

Webpack file details

If the Module is ES6, the ES Module is loaded with __esModule = true CommonJS in the exported object

__webpack_require__ is an export object that imports the input module and returns the module.

Is an immediate function that takes a dependent file as an argument

Chunks that are loaded asynchronously end up being loaded synchronously, and it’s added to modules objects, Modules [moduleId]. Call (module.exports, module, module.exports, webpack_require) This is the first then execution in foo.bundle.js (a module loaded asynchronously), passed to the module’s path, and loaded synchronously using webpack_require.

Lazy loading blocks: The principle of using script tags Return Promise. All (Promises), then use it in then

Asynchrony is when only an import is loaded

ES6 modules: block identified as ES Module and hang function content definition in default

Package the resulting file: The final package is a self-executing function;

The self-executing function input parameter is an object modules, whose key is the path of the packaged module file, and the corresponding value is a function whose internal content is defined by the module file.

The self-executing function body returns the code __webpack_require__(__webpack_require__.s = “./ SRC /index.js”), which is the exported object that loads the entry module and returns the module.

function __webpack_require__(moduleId) {}Copy the code

This includes a caching mechanism

var module = installedModules[moduleId] = {
  i: moduleId,
  l: false,
  exports: {}
};
Copy the code

How does Webpack pack intermodule references

  • CommonJS load CommonJS
 ({
  "./src/foo.js":
  (function(module.exports) {
    module.exports = 'foo';
  }),
  "./src/index.js":
  (function(module.exports, __webpack_require__) {
    const foo = __webpack_require__("./src/foo.js");
    console.log(foo)
  })
})
Copy the code
  • CommonJS loads ES Module
({
  "./src/foo.js":
  (function(module, __webpack_exports__, __webpack_require__) {
    __webpack_require__.r(__webpack_exports__); // Label the passed object __esModule=true, indicating that the module is an ES6 module
    __webpack_exports__["default"] = ('foo'); // Hang the contents of the module on the default attribute of __webpack_exports__
  }),
  "./src/index.js":
  (function(module.exports, __webpack_require__) {
    const foo = __webpack_require__("./src/foo.js");
    console.log(foo)
  })
})
Copy the code
  • ES Module Loads ES Module
({
  "./src/foo.js":
  (function(module, __webpack_exports__, __webpack_require__) {
    __webpack_require__.r(__webpack_exports__);
    __webpack_exports__["default"] = ('foo');         
  }),
  "./src/index.js":
  (function(module, __webpack_exports__, __webpack_require__) {
    __webpack_require__.r(__webpack_exports__);
    var _foo_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/foo.js");
    console.log(_foo_js__WEBPACK_IMPORTED_MODULE_0__["default"])
    //_foo_js__WEBPACK_IMPORTED_MODULE_0__ receives the imported file and obtains the default exported content of the file through the default attribute})})Copy the code

Webpack_require. n is the default export object used to obtain modules. It is compatible with both CommonJS and ES Module.

  • ES Module loads CommonJS
({
  "./src/foo.js":
  (function(module, exports) {
    module.exports = 'foo';
  }),
  "./src/index.js":
  (function(module, __webpack_exports__, __webpack_require__) {
    __webpack_require__.r(__webpack_exports__);
    var _foo_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/foo.js");
    var _foo_js__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(_foo_js__WEBPACK_IMPORTED_MODULE_0__);
    console.log(_foo_js__WEBPACK_IMPORTED_MODULE_0___default.a)
  })
})
Copy the code

When the entry file index.js loads foo.js conforming to the CommonJS specification as an es module, loads the module passed through __webpack_require__, The resulting module _foo_js__WEBPACK_IMPORTED_MODULE_0__ is passed to the __webpack_require__.n method to obtain the default exported object of the module. Because the content in foo.js is exported via export, not export default. So Foo is hung on an A property of default.

Asynchronous load on demand

Lazy loading blocks: The principle of using script tags Return Promise. All (Promises), then use it in then

Asynchrony is when only an import is loaded

/** * This object is used to store chunks that have been loaded and are being loaded * undefined: chunks are not loaded * NULL: chunks are preloaded/prefetched * Promise: chunks are being loaded * 0: // installedChunks = {"index": 0, // installedChunks have been loaded.Copy the code

Webpack file analysis (part 1)

Webpack file analysis (ii) (juejin.cn)

AST

From Babel to AST (juejin.cn)

AST Abstract Syntax tree (juejin. Cn)

Key to generating AST from code: lexical analysis and syntax analysis

Github.com/CodeLittleP… Github.com/jamiebuilds…

Plugin I developed

  1. Many of the requirements involve time, but because time is compatible, a plugin was written to handle the date format uniformly.
  2. Unified processing of image resource path: Upload local pictures to Aliyun after testing (because local pictures are convenient for debugging and modification), replace local pictures with CDN linked pictures, and delete them after uploading to prevent too many project files and reduce the total volume of the project.

Get the local file, get the file path, read the file stream, upload it to oss, get the link, and replace it

Please refer to loader and Plugin (juejin. Cn)

I developed the loader

  1. Compatible with the previous adaptive mode, changed the previous calculation mode

The end of the I

Webpack is a module packaging tool

Depending on your business needs, this configuration can be optimized to reduce package size, speed up packaging, reduce code duplication, and analyze file size (wait for the interviewer to ask, right?).

The final expression of the Webpack build process:

The running process of Webpack is a serial process, from start to finish, the following processes will be executed successively: initialize parameters according to the configuration file, load all configured plug-ins, execute the run method of the object to start compiling; At the same time, according to the configuration to determine the entry file, from the entry file, call all configured Loader to translate the module (including CSS to JS, ES6 to ES5), and find the module dependent module, recursive processing; Then according to the output source code, file dependencies, and finally packaged into a file.

Juejin. Im/post / 684490…

Juejin. Im/post / 684490… (webpack)

Juejin. Im/entry / 68449… (WebPack configuration)

www.cnblogs.com/HYZhou2018/… (optimization)

Juejin. Im/post / 685457… (Source code analysis)

Juejin. Im/post / 685457… (Source code analysis)

www.yuque.com/yijiangxili… (Interview summary)

Webpack from Beginner to Master – Advanced (juejin. Cn)

Still silicon valley front-end Webpack5 tutorial (advanced) _bilibili bilibili

The Plugins | webpack Chinese website (webpackjs.com)