Said in the previous
This article is not posted webpack source code, more as a small summary of their own learning, welcome retract (✿, retract,). Hope to give meng new people a little help (=•ω < =)☆. Also hope that they can be more in-depth source code, every step of the key source really understand (ง •_•)ง! Let’s get down to business!! To understand the overall workflow, you must first understand some of the core concepts in WebPack.
The core concept
module
The module. A Module is the core entity in WebPack. Everything to load and all dependencies are modules.
entry
Entrance, starting point. Webpack compiles the code we write and looks for dependencies. Entry is the first file to be compiled during compilation. As the main. Js
Webpack supports multiple entries and packages out multiple HTML files.
loader
Module converter. Convert code that cannot be run directly in the browser into code that can be run directly in the browser. For example, if we are developing with the new ES6 feature syntax, we need WebPack to use the Babel-Loader in the packaging process to convert ES6 syntax that the browser does not understand into ES5 syntax that the browser does understand. In general, we do not need to write loader ourselves for daily business development, but directly use third-party libraries such as Babel-Loader.
Common loader
- Babel-loader converts ES6 to ES5
- Ts-loader converts typescript to JS
- Less-loader converts the less to the CSS
- Css-loader processes CSS styles
- Style-loader inserts the packaged style into the HTML structure
plugin
If you compare the process of a WebPack build to a production line, then a plug-in is like a feature that is inserted into the production line to work on the resources in the production line at a specific time. Webpack broadcasts events as they run, and plugins can be added to the production line simply by listening for the events they care about. Webpack uses Tapable to organize this complex production line. The event flow mechanism of WebPack guarantees the order of plug-ins and makes the whole system extensibility very good.
Chunk, bundle, and Moudle
Modules, chunks, and bundles can all be understood as files. The difference is that we write modules directly, webPack processes chunks, and finally the bundle that the browser can run directly. Module, chunk, and bundle are just three names for the same piece of logical code in different scenarios.
Use a specific example to show the relationship between Modules, chunks, and bundles
- SRC directory structure
SRC ├── index.css ├─ index.html ├─ index.js ├─ common.js ├─ utils.jsCopy the code
- code
// mian.js
import "./example.js";
import "./index.css";
// example.js
console.log("a module file for example");
// util.js
export function square(a) {
return a * a;
}
Copy the code
/* index.css */
body {
background-color: green;
}
Copy the code
/ / webpack configuration
moudle.exports={
entry: {
index: ".. /src/main.js".utils: '.. /src/utils.js',},output: {
filename: "[name].bundle.js".// The two bundle filenames correspond to the two entries
},
module: {
rules: [{test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, MiniCssExtractPlugin creates a link tag
'css-loader'.// Css-loader is responsible for parsing CSS code and handling dependencies in CSS],},]}plugins: [
new MiniCssExtractPlugin({ // MiniCssExtractPlugin pulls out the CSS file and introduces the style file in the form of a link tag
filename: 'index.bundle.css' // The output CSS file is named index.bundle.css]}}),Copy the code
- The diagram
With the important consumer-facing concepts mentioned above, here are the important concepts in webPack builds (in WebPack source code).
The compiler, complication,
- The compiler can be understood as the scheduling center for WebPack compilation. It is a compiler instance that records the complete WebPack environment information in the compiler object. In each webPack process, the compiler is generated only once. (For example, NPM run dev has only one compiler at a time)
- It is a core object during the lifetime of the compiler that contains all the data (modules, chunks, and assets) during a build. That means there is one instance only of a build process. (For example, during hot updates, WebPack will listen for local file changes and recreate a complication)
Compiler has several important hooks:
- Make 🛠 : There is logic in the callback of the hook to start reading the WebPack configuration file
- Emit 🏹 : Execute the logic for generating the file (i.e., the bundle) in the hook callback
- Done 🔚 : Fires this hook after the file has been written to the file system
AST
Abstract syntax tree. Through it to extract the dependencies of each module, and then form a dependency tree 🎄.
Main story
Webpack is like a production line, going through a series of processes to turn source files into output. Each process in this production line is a “single responsibility,” with dependencies between multiple processes that can only be handed over to the next process after the current process has been completed. The Webpack source code is so complex that it is difficult to fully understand the source code. For those who use it, the main story is all they need to understand. The main story starts with reading the entries in the configuration file and ends with exporting the bundle.
What questions do you want to solve?
- What exactly does WebPack do to compile our source code? (Through sections 1-4)
- In which process does loader come into play? (Section 2)
- How is a dependency tree formed? (Section 2)
- How is chunk divided? (Sections 2-3)
- How does the bundle end up being formed? (Section 4)
1. Preparation phase
- Initialize the Compiler object and register the built-in plug-ins and plug-ins in the configuration file.
- Run compiler.run()–>compiler.compile() to start the build process.
- Compiler.compile creates an object on the compiler, triggering the make hook on the compiler.
- The make hook on compiler does two things. . One is to perform the compiler. The hooks. Make callAsync () responsible for the access to the plugin and then apply them all (perform subscribed to make hook plugin callback function). The second is the execution of extravase.addentry () into the main storyline.
2. The generation phase of modules
(In this case, modules refer to webPack modularized JS objects that are not written source files)
-
AddEntry The addEntry method starts parsing the first module, the entry file we configured (such as main.js). AddEntry mainly executes _addModuleChain(), and calls addModule in _addModuleChain
-
AddModule generates an empty WebPack modularized object using the corresponding factory NormalModuleFactory (specifically, create). Modules, and because it is currently an entry file, it will also be stored on extravestation. entries. We then execute buildModule->doBuild.
The compiler object also instantiates two core factory objects, NormalModuleFactory and ContextModuleFactory, when creating extravocation.
-
DoBuild reads module content and processes it. Use the corresponding loaders to convert our source module into a standard JS module object. Then Parse ()
-
Parse parses JS into an AST. And then we go through the AST.
-
Walk through the AST to find all the dependent modules in the entry and add them to the Dependencies array. Again, in turn, depends on the module of dependencies processModuleDependencies – > 2 – > 3 – > 4 – > 5, the process of this is a recursive traversal process, All the original Module source code is aggregated into a single object (hereafter called the “Chunk initializer”). If dynamic imports such as import() are found, then a new round of _addModuleChain is opened. Execute seal() until each round of recursion is complete. As many times as _addModuleChain is called, there are as many dependency trees as there are objects in the chunk initialstate.
summary
According to the entry in the configuration, find all entry files. From the entry, use to loader to complete module conversion, and then parse to form the AST, and then traverse the AST to find all require to form the dependency tree. Recursively traversing the file corresponding to the node of the dependency tree, doing the same module conversion, forming the dependency tree processing, until the end of the recursion. This forms a chunk initial-state object. If you encounter dynamic imports, you end up with one or more separate chunk initialstate objects, just as you did with entries above.
3. Chunks is generated
The following images contain chunks and bundles generation processes.
- Seal perform createChunkAssets ()
- createChunkAssets
The main call is mainTemplate.render () or chunktemplate.render (). MainTemplate. Render processes the chunk objects formed by the entry, and ChunkTemplate. Render processes the chunk objects formed by the dynamic introduction. After processing, the object can be understood as a string with a fixed structure. Then performModuleTemplate.render()
In fact, the xxxTemplate is initialized at the same time as the xxxTemplate.
- Moduletemplate-render holds the JS code string that will eventually be output to the file. Then execute emitAsset().
- EmitAsset saves the generated string to extravest.assetes. Assets is the final list of files to generate.
summary
The extravestational. Seal method is used to generate chunks, which are optimized through a series of operations, resulting in the chunk being preserved in extravestational.
Actually the division of the chunk in addition to the entrance to the dynamic import entry (), and optimization of webpack. Splitchunk. CacheGroup configuration. See this article for details.
4. Generate the bundle file
- When assets are ready, work on the extravestational instance ends. The Emit hook of the compiler is then fired.
- Emit hooks do two main things. Is a compiler. Hooks. Emit. CallAsync () to access the plugin (execution subscribed to emit hook callback function of the plugin, this is we modify the final documents of the last chance.) The second is the traverse extravocation. Assets that generates bundles when they are written to the file system, which triggers the done hook of the compiler.
- At the done hook, the build process ends.
reference
Github · Aasailan – WebPack run process
Github · Lihongxun945 -Webpack source code parsing
Webpack website, https://webpack.docschina.org/