{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}},{"type":"strong","attrs":{}}],"text":"*","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":" The full text 2500 word , Read for about 30 minute . If you think the article is useful , Welcome to like your attention , But writing is not easy , Without the consent of the author , It is forbidden to reprint in any form !!!","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"*","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":" background ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":"Dependency Graph The concept comes from the official website ","attrs":{}},{"type":"link","attrs":{"href":"https://webpack.js.org/concepts/dependency-graph/","title":null,"type":null},"content":[{"type":"text","text":"Dependency Graph | webpack","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}]},{"type":"text","text":" One article , The original explanation is like this :","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}},{"type":"strong","attrs":{}}],"text":"*","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"Any time one file depends on another, webpack treats this as a ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"color","attrs":{"color":"#3594F7","name":"user"}},{"type":"strong","attrs":{}}],"text":"dependency","attrs":{}},{"type":"text","text":". This allows webpack to take non-code assets, such as images or web fonts, and also provide them as ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"color","attrs":{"color":"#3594F7","name":"user"}},{"type":"strong","attrs":{}}],"text":"dependencies","attrs":{}},{"type":"text","text":" for your application.","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"When webpack processes your application, it starts from a list of modules defined on the command line or in its configuration file. Starting from these ","attrs":{}},{"type":"link","attrs":{"href":"https://webpack.js.org/concepts/entry-points/","title":null,"type":null},"content":[{"type":"text","text":"entry points","attrs":{}}],"marks":[{"type":"italic"},{"type":"color","attrs":{"color":"#40B8FA","name":"user"}},{"type":"strong"}]},{"type":"text","text":", webpack recursively builds a ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"color","attrs":{"color":"#3594F7","name":"user"}},{"type":"strong","attrs":{}}],"text":"dependency graph","attrs":{}},{"type":"text","text":" that includes every module your application needs, then bundles all of those modules into a small number of ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"color","attrs":{"color":"#3594F7","name":"user"}},{"type":"strong","attrs":{}}],"text":"bundles","attrs":{}},{"type":"text","text":" - often, just one - to be loaded by the browser.","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"*","attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" The core meaning of translation is :webpack When dealing with application code , It'll come from the developers entry Start to recursively build the... That contains all the modules ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"color","attrs":{"color":"#3594F7","name":"user"}},{"type":"strong","attrs":{}}],"text":"「dependency graph」","attrs":{}},{"type":"text","text":" _,_ And then I'll put these module Packaging for bundles .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" However, the fact is far more than the description on the official website ,Dependency Graph through webpack The whole running cycle , from make Module analysis of phase , To seal Stage chunk Generate , as well as tree-shaking Functions are highly dependent on Dependency Graph , yes webpack Resource construction is a very core data structure .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" This article will focus on
[email protected] Of Dependency Graph Realization , There are three aspects to discuss :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"Dependency Graph stay webpack What kind of data structure is used in the implementation ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"Webpack How to collect dependencies between modules during operation , And then build Dependency Graph","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"Dependency Graph So once you've built it , How is it consumed ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" Study this article , You will learn more about webpack Processing details of module parsing , Combined with the above ","attrs":{}},{"type":"link","attrs":{"href":"https://zhuanlan.zhihu.com/p/363928061","title":null,"type":null},"content":[{"type":"text","text":"[ Ten thousand word summary ] I have a thorough understanding of it Webpack The core principle ","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}]},{"type":"text","text":" , You can learn more about webpack The core mechanism of .","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":"Dependency Graph","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" This section goes into webpack Source code , Reading Dependency Graph The internal data structure and dependency collection process of . Before the official launch , It's necessary to review a few webpack Important concepts :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":": Resources in webpack Internal mapping objects , Contains the path of the resource 、 Context 、 rely on 、 Content and other information ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Dependency","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" : Reference other modules in a module , for example ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"import \"a.js\"","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" sentence ,webpack We will first express the reference relationship as Dependency Subclass and associate module object , Until now module After all the contents are parsed , Starting the next cycle will start Dependency Object to the appropriate Module Subclass .","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Chunk","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" : Objects used to organize output structures ,webpack After analyzing the contents of all module resources , Build a complete Dependency Graph after , According to user configuration and Dependency Graph Content builds one or more chunk example , Every chunk And the final output file is roughly one-to-one correspondence .","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":" data structure ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":"Webpack 4.x Of Dependency Graph Simple implementation , Mainly by Dependence/Module Built in series property record reference 、 The cited relationship .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" and Webpack 5.0 After that, we implemented a relatively complex class structure to record the dependencies between modules , Take module dependency related logic from Dependence/Module Decoupling into a set of independent type structures , The main types are :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"ModuleGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" : Record Dependency Graph The container of information , On the one hand, it saves all the information involved in the construction process ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" 、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dependency","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" object , And these objects refer to each other ; On the other hand, it provides various tools and methods , It is convenient for users to read out quickly ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" or ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"dependency","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Additional information ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"ModuleGraphConnection","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" : Data structure that records the reference relationship between modules , Through internal ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"originModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Property records refer to the parent module in the relationship , adopt ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Attribute record submodule . In addition, a series of function tools are provided to judge the validity of the corresponding reference relationship ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"ModuleGraphModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" :","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The object is Dependency Graph Supplementary information under the system , That contains module objects ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"incomingConnections","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" —— To the module itself ModuleGraphConnection aggregate , Who refers to the module itself ;","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"outgoingConnections","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" —— The external dependence of the module , That is, the module refers to other modules .","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" The relationship between classes is roughly :","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ee/ee39ebfcf4f5274dbd20113f8f5da810.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" The above class diagram needs extra attention :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"ModuleGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Object passing ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"_dependencyMap","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Property record ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Dependency","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Object and the ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ModuleGraphConnection","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The mapping between connected objects , In the subsequent processing, we can quickly find... Based on this layer mapping ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Dependency","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The reference corresponding to the instance and the referenced ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"ModuleGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Object passing ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"_moduleMap","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" stay ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" On the basis of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ModuleGraphModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Information , and ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ModuleGraphModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The biggest function is to record the reference and referenced relationship of the module , Subsequent processing can be found based on this attribute ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" All dependencies and dependents of an instance ","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":" Rely on the collection process ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"ModuleGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ModuleGraphConnection","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ModuleGraphModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The three work together , stay webpack The build process (make Stage ) Step by step collect dependencies between modules in , Looking back ","attrs":{}},{"type":"link","attrs":{"href":"https://zhuanlan.zhihu.com/p/363928061","title":null,"type":null},"content":[{"type":"text","text":"[ Ten thousand word summary ] I have a thorough understanding of it Webpack The core principle ","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}]},{"type":"text","text":" The construction flow chart mentioned :","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/86/86836f19526963148ced041e2cbb583e.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" The build process itself is complex , Readers are advised to read in contrast ","attrs":{}},{"type":"link","attrs":{"href":"https://zhuanlan.zhihu.com/p/363928061","title":null,"type":null},"content":[{"type":"text","text":"[ Ten thousand word summary ] I have a thorough understanding of it Webpack The core principle ","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}]},{"type":"text","text":" One article , Deepen the understanding . The dependency collection process mainly takes place in two nodes :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"addDependency","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" :webpack After resolving the reference relationship from the module content , Create the right ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Dependency","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Subclass and call the method to record to ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" example ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"handleModuleCreation","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" : After the module is parsed ,webpack Traverse the dependency set of the parent module , Call this method to create ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Dependency","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Corresponding submodule object , Then call ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"compilation.moduleGraph.setResolvedModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Method to record the parent-child reference information to ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"moduleGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" On the object ","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"setResolvedModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The logic of the method is roughly :","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"class ModuleGraph {\n constructor() {\n /** @type {Map
} */\n this._dependencyMap = new Map();\n /** @type {Map} */\n this._moduleMap = new Map();\n }\n\n /**\n * @param {Module} originModule the referencing module\n * @param {Dependency} dependency the referencing dependency\n * @param {Module} module the referenced module\n * @returns {void}\n */\n setResolvedModule(originModule, dependency, module) {\n const connection = new ModuleGraphConnection(\n originModule,\n dependency,\n module,\n undefined,\n dependency.weak,\n dependency.getCondition(this)\n );\n this._dependencyMap.set(dependency, connection);\n const connections = this._getModuleGraphModule(module).incomingConnections;\n connections.add(connection);\n const mgm = this._getModuleGraphModule(originModule);\n if (mgm.outgoingConnections === undefined) {\n mgm.outgoingConnections = new Set();\n }\n mgm.outgoingConnections.add(connection);\n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" The code in the above example is mainly changed ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"_dependencyMap","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" And ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"moduleGraphModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" In and out of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"connections","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" attribute , To collect the upstream and downstream dependencies of the current module .","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":" Instance analysis ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" Take a simple example , For the following dependencies :","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b4/b4c1ca87fb1cbf65e951bc02677bb653.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":"Webpack After starting , Call recursively during the build phase ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"compilation.handleModuleCreation","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" function , Gradually complete Dependency Graph structure , Finally, the following data results may be generated :","attrs":{}}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"\nModuleGraph: {\n _dependencyMap: Map(3){\n { \n EntryDependency{request: \"./src/index.js\"} => ModuleGraphConnection{\n module: NormalModule{request: \"./src/index.js\"}, \n // The entry module has no references , Therefore, it is set as null\n originModule: null\n } \n },\n { \n HarmonyImportSideEffectDependency{request: \"./src/a.js\"} => ModuleGraphConnection{\n module: NormalModule{request: \"./src/a.js\"}, \n originModule: NormalModule{request: \"./src/index.js\"}\n } \n },\n { \n HarmonyImportSideEffectDependency{request: \"./src/a.js\"} => ModuleGraphConnection{\n module: NormalModule{request: \"./src/b.js\"}, \n originModule: NormalModule{request: \"./src/index.js\"}\n } \n }\n },\n\n _moduleMap: Map(3){\n NormalModule{request: \"./src/index.js\"} => ModuleGraphModule{\n incomingConnections: Set(1) [\n // entry modular , Corresponding originModule by null\n ModuleGraphConnection{ module: NormalModule{request: \"./src/index.js\"}, originModule:null }\n ],\n outgoingConnections: Set(2) [\n // from index Point to a modular \n ModuleGraphConnection{ module: NormalModule{request: \"./src/a.js\"}, originModule: NormalModule{request: \"./src/index.js\"} },\n // from index Point to b modular \n ModuleGraphConnection{ module: NormalModule{request: \"./src/b.js\"}, originModule: NormalModule{request: \"./src/index.js\"} }\n ]\n },\n NormalModule{request: \"./src/a.js\"} => ModuleGraphModule{\n incomingConnections: Set(1) [\n ModuleGraphConnection{ module: NormalModule{request: \"./src/a.js\"}, originModule: NormalModule{request: \"./src/index.js\"} }\n ],\n // a The module has no other dependencies , so outgoingConnections The property value is undefined\n outgoingConnections: undefined\n },\n NormalModule{request: \"./src/b.js\"} => ModuleGraphModule{\n incomingConnections: Set(1) [\n ModuleGraphConnection{ module: NormalModule{request: \"./src/b.js\"}, originModule: NormalModule{request: \"./src/index.js\"} }\n ],\n // b The module has no other dependencies , so outgoingConnections The property value is undefined\n outgoingConnections: undefined\n }\n }\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" From the above Dependency Graph It can be seen that , Essentially ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ModuleGraph._moduleMap","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" A directed acyclic graph structure has been formed , Among them, the dictionary ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"_moduleMap","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Of key Is the node of the graph , Corresponding value ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ModuleGraphModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The structure of the ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"outgoingConnections","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The attribute is the edge of the graph , In the above example, from the starting point ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"index.js","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Starting edge ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"outgoingConnections","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" All the vertices of the graph can be traversed forward .","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":" effect ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" With [email protected] For example , keyword ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"moduleGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" There is 1277 Time , It's almost covered ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"webpack/lib","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" All the files under the folder , Its function can be seen . Although the frequency is very high , But on the whole, it can be seen that there are two main functions : Information index 、 Turn into ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ChunkGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" To determine the output structure .","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":" Information index ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"ModuleGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Types provide many implementations module / dependency Information query tool function , for example :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"getModule(dep: Dependency)","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" : according to dep Find the corresponding ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" example ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"getOutgoingConnections(module: Module)","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" : lookup ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" All dependencies of the instance ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"getIssuer(module: Module)","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" : lookup ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"module","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Where to be quoted ( About issuer More about the mechanism , Please refer to another article of mine : ","attrs":{}},{"type":"link","attrs":{"href":"https://zhuanlan.zhihu.com/p/368391369","title":null,"type":null},"content":[{"type":"text","text":" Ten minutes Webpack:module.issuer Properties, ","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}]},{"type":"text","text":" )","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" wait .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":"[email protected] Many plug-ins inside 、Dependency Subclass 、Module Subclass implementation needs to use these tool functions to find specific modules 、 Dependent information , for example :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"SplitChunksPlugin","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Optimizing chunks In processing , Need to use ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"moduleGraph.getExportsInfo","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Query each module's ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"exportsInfo","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" ( A collection of information exported by a module , And tree-shaking Strong correlation , There will be a single article to explain ) Information to determine how to separate ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"chunk","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":".","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":" stay ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"compilation.seal","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Function , Need to traverse entry Corresponding dep And call ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"moduleGraph.getModule","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Get the complete module Definition ","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"...","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" that , When you write plug-ins , Consider a moderate reference ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"webpack/lib/ModuleGraph.js","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Method provided in , Confirm that you can get the information you need by using those functions .","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":" structure ChunkGraph","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":"Webpack In the main process ,make At the end of the build phase, you go to ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"seal","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Stage , Start sorting out how to organize the output content . stay [email protected] when ,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"seal","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" The stage mainly revolves around ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Chunk","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" And ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ChunkGroup","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Two types expand , And by the 5.0 after , And Dependency Graph Similarly, a new system based on ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ChunkGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Graph structure to achieve resource generation algorithm .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" stay compilation.seal Function , First, according to the default rules —— Every entry The corresponding organization is a chunk , Then call ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"webpack/lib/buildChunkGraph.js","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" File defined ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"buildChunkGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Method , Traverse ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"make","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" stage-generated ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"moduleGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" Object so that module Dependency is transformed into ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"chunkGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" object .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" The logic of this part is also very complicated , Not here , Next time, I will write a separate article to explain ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"chunk/chunkGroup/chunkGraph","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#3594F7","name":"user"}}],"attrs":{}},{"type":"text","text":" And so on .","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40B8FA","name":"user"}}],"text":" summary ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" This article discusses the Dependency Graph Concept in webpack The interior is heavily used , So understanding this concept is important for us to understand webpack Source code , Or learn how to write plug-ins 、loader Will be of great help . In fact, many new knowledge blind spots have been found in the process of analysis :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"Chunk What's the complete mechanism of ?","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"Dependency How to realize the complete system of , What's the use ?","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#595959","name":"user"}}],"text":"Module Of exportsInfo How to collect ? stay tree-shaking How to be used in the process ?","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#2b2b2b","name":"user"}}],"text":" If you are also interested in the above questions , Welcome to like your attention , The follow-up will focus on webpack Output more useful articles .","attrs":{}}]}]}