The Compiler object contains the current configuration for running Webpack, including entry, output, loaders, etc. This object is instantiated when Webpack is started and is globally unique.
The Compilation object represents a resource version build
How to unpack webpack
Webpack organizes subcontracting -- Chunk objects based on the contents of the module dependency graph. The default subcontracting rules are:Copy the code
-
Modules touched by the same entry are organized into chunksCopy the code
-
Asynchronous modules are individually organized into a chunkCopy the code
-
Entry. runtime is organized separately into a chunkCopy the code
The default rules are implemented in the compiling. seal function. After the seal core logic is run, a series of Chunk, ChunkGroup, and ChunkGraph objects will be generated. Subsequently, SplitChunksPlugin plug-in will further disassemble and optimize the Chunk series objects, and finally reflect the output to show complex subcontracting results.
Way to unpack:
- Entry Sets multiple entry files
Key: The SEAL phase traverses the entry objects and generates chunk for each entry. Then, all modules that an entry touches are packaged into chunk based on the module dependency diagram.
After the initialization, Webpack will read ModuleDependencyGraph content, the content of the entry into the corresponding the chunk (in Webpack/lib/buildChunkGrap js file).
ModuleDependencyGraph will gradually add a/ B/C/D module to chunk[Main].
- According to the need to load
Important: When analyzing the ModuleDependencyGraph, a separate Chunk object will be created for each asynchronous module encountered and the asynchronous module will be packaged separately.
After Webpack 4, modules can be dynamically loaded by simply introducing them with asynchronous statements require.ensure(“./xx.js”) or import(“./xx.js”), which is essentially chunk-based.
- The runtime of the subcontract
Important: After Webpack 5, runtime code can be packaged separately based on the Entry.Runtime configuration.
After WebPack 5, runtime-based subcontracting rules are also supportedCopy the code
At compile time, Webpack outputs runtime code (based on Dependency subclasses) supporting features based on the business code, such as:
-
Functions such as __webpack_require__.f and __webpack_require__.r are required for minimal modularity supportCopy the code
-
If the dynamic loading feature is used, the __webpack_require__.e function is writtenCopy the code
-
To use the Module Federation feature, write the __webpack_require__.o functionCopy the code
-
, etc.Copy the code
module.exports = {
entry: {
index: { import: "./src/index", runtime: "solid-runtime" },
}
};
Copy the code
After executing entry and subcontracting asynchronous modules, Webpack iterates through the entry configuration to determine whether it contains the Runtime attribute. If it does, a Chunk named Runtime is created. Therefore, the preceding configuration generates two chunks: , the chunk chunk [index. Js] [solid – the runtime],
-
Bundle Splitting: Splitting a large file into more and smaller files for better caching.
This is done by setting SplitChunks in Optimization
module.exports = { entry: path.resolve(__dirname, 'src/index.js'), output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[contenthash].js' }, optimization: { splitChunks: { chunks: 'all', } } }; Copy the code
Increase of optimization. SplitChunks. Chunks = ‘all’, the reference of third-party modules (node_modules) all package to vendor. The js.
Vendor.js also suffers from the same problems as the main.js file, and making changes to part of it means redownloading the entire vendor.js.
const path = require('path'); const webpack = require('webpack'); module.exports = { entry: path.resolve(__dirname, 'src/index.js'), plugins: [ new webpack.HashedModuleIdsPlugin(), // so that file hashes don't change unexpectedly ], output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[contenthash].js', }, optimization: { runtimeChunk: 'single', splitChunks: { chunks: 'all', maxInitialRequests: Infinity, minSize: 0, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name(module) { //获取每个npm包的名称 const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]; //对npm的包名子添加前缀,并去掉@ return `npm.${packageName.replace('@', '')}`; } } } } } } Copy the code
The package result of a vue-CLI-generated project would be:
dist/npm.vue.44c71c1a.js dist/npm.vue-router.0290a1da.js dist/npm.core-js.028dc51e.js dist/npm.vuex.6946f3d5.js dist/app.e76cff0a.js dist/runtime.4e174d8a.js dist/npm.vue-loader.611518c6.js dist/about.16c4e81c.js dist/npm.webpack.034f3d3d.js dist/css/app.ab586865.css Copy the code
Let’s focus on cacheGroups
CacheGroups are the core configuration of splitChunks. SplitChunks split modules according to the cacheGroups, and the chunks and other properties mentioned earlier are configured for cacheGroups. SplitChunks has two cache groups by default, vendor-load content source node_modules and default.
2. Dynamic loading principle of Webpack
Thanks: https://zhuanlan.zhihu.com/p/159216534 https://juejin.cn/post/6952703369135800350#heading-1
Tree-shaking for Webpack
Tree-shaking is removing unreferenced module code and reducing code size to improve page performance.
Principle: The most important feature of ES Module is that it is static. At compile time, you can determine Module dependencies and input and output values. What does this mean? It means that module dependencies are deterministic, independent of the state of the runtime, and can be reliably analyzed statically. It is on this basis that tree-shaking is possible
Condition:
-
The module system must be ESmodule.Copy the code
The reason:
Esmodules are static, and dependencies are determined at compile time. Commonjs is the default module system for the Node environment and is dynamic. Webpack only does this at compile time, so only the ES module will do it
However, in real projects, we typically process the source code with a series of loaders, including the god-like Babel-Loader, before going into Webpack optimization. We use the following Babel configuration: once the same source code as above is packaged with Webpack, we can see that tree-shaking is disabled again
The problem is that modules are converted to CJS by default when preset is ENV. Let’s configure Babel as follows:
{
"presets": [
[ "env",{modules:false}]
]
}
Copy the code
For TS projects, we usually use ts-loader to process TS files. For TS, we also need to set the module in tsconfig.json to ‘esnext’ or ‘es2015’:
{
"compilerOptions": {
module:'esnext'
}
}
Copy the code
-
Identify the sideEffect field in the package.json file.Copy the code
Webpack does not tree-shaking, or even code obfuscation, for modules with side effects! .
So what other modules are considered side effects in WebPack?
1. Eval is also considered impure
2. Assign a property to a top-level scope pair twice
-
Set webPack as the production environmentCopy the code
In production, Tree-shaking is enabled for Webpack by default. The configuration for tree-shaking is as follows:
Optimization: {providedExports: false,// Identify which methods of a module during Webpack compilation are exported usedExports: True,// Identifies module methods during Webpack compilation that are exported sideEffects: true,// allows labeling of inactive files in package.json minimizer: [new TerserPlugin({// remove unnecessary code. Cache: true, parallel: true})]},Copy the code
-
Existing problems:Copy the code
Tree-shaking doesn’t work for third-party libraries
2, cannot shake a method that is not referenced in class
Thanks: https://juejin.cn/post/6956522989810614308 https://juejin.cn/post/6955383260759195678
4. Webpack performance optimization
How to write loader
How to write plugin
https://juejin.cn/post/6955421936373465118#heading-31
Webpack5 VS WebPack4
Hot replacement principle of Webpack
https://juejin.cn/post/6973825927708934174
The packaging principle of Webpack
Thanks to:
https://juejin.cn/post/6960924869307400200#heading-10
The modularity principle of Webpack
- Modularity code is stored through a Webpack_module object
Key indicates the file name. Value indicates the file codeCopy the code
- Modularization code is cached via webpack_module_cache
- Use webpack_require to read and import code from webpack_module_cache or webpack_module
Principle of Source-map
Definition: a file that holds source code mappingsCopy the code
The source Map file is about the length:
{" version ": 3," sources ": [/ / convert the file before the" webpack: / / webpack5 - the template /. / SRC/index, js "], "names" : [], "the mappings:" ";;;;; AAAA; AACA; AACA; AACA; AACA,eAAe; AACf; AACA; AACA,mB",// A string to record location information. File: "main.bundle.js", "sourcesContent": [ "console.log('Interesting!!! ')\n// Create heading node\nconst heading = document.createElement('h1')\nheading.textContent = 'Interesting! '\nconsole.log(a); N // Heading node to the DOM\nconst app = document.querySelector('#root')\napp.append(heading)"], "SourceRoot ": ""} Important fields: version, sources, mappingsCopy the code
- The source map. Generates.map files (source map files are not generated when used with eval or inline, depending on which mode)
- The eval. Use Eval to wrap block code
- Being. No column information is generated
- The inline. Embed.map as a DataURI instead of generating a separate.map file
- The module. The source map contains the loader
For development environments, eval, eval-source-map, eval-cheap-source-map, eval-cheap-module-source-map, and so on are all available. My personal recommendation is eval-cheap-module-source-map
Development environment:
Configure your server to not allow ordinary users to access the Source map file! You should not deploy the Source Map file to the Web server. Instead, use it only for error reporting tools.
General process:
- When webPack is built, upload the original JS and Source map files to our monitoring platform
- Js error stack collection, window.onerror to catch JS errors, and then reported to the server, used to collect user use of the bug
- Resolves JS errors and maps the source file stack
- Sourcemap is used to find the original error message, using source-map
- Display of monitoring platform
Webpack5 (Module Federation) implements the micro front end
12, Webpack package Babel processing
Thanks to: https://juejin.cn/post/6968027732504477726
Thank you very much to the author of the link, this article is purely for their own learning summary. Reference links:
https://juejin.cn/post/6964642182183518215
https://juejin.cn/post/6961724298243342344#heading-2