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:
- 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;
- 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
- Distinguished by environment variables
- webpack –env.production
- Check env in webpack.config.js
- 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:
- usedExports
- 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:
- Name Indicates the name of the current application. The value must be globally unique
- Remotes maps the names of other projects to the current project
- An exposes represents an exported module, and only the module declared here can be used as a remote dependency
- 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
- 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
- The source map mode is written differently
13 common patterns for webpack4
26 common patterns for webpack5
Check the official website for details.
- 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)
- 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 diskMemoryCachePlugin
: Persist to memory
Webpack5’s built-in caching scheme is better than cache-loader in terms of performance and security:
On the performance
Since all modules processed by WebPack are cached, cache coverage is much higherOn 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.
-
Webpack5 adds module federation
-
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:
- 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
- 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 module
The 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?
-
VSCode has a plug-in import cost that helps us monitor the size of imported modules in real time
-
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:
- Initialization: start build, read and merge configuration parameters, load Plugin, instantiate Compiler
- 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
- 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
- Many of the requirements involve time, but because time is compatible, a plugin was written to handle the date format uniformly.
- 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
- 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)