前言webpack初始化完成后,会通过传入的options.watch判断是否开启手表。如果watch被打开,watch进程就会被执行。如果是run的话,就是执行run的过程,本系列只关注主线,所以我们直接从run开始,对watch感兴趣的同学可以研究一下compiler.run(),直接看core代码construn=()=>{this.hooks.beforeRun。callAsync(this,err=>{if(err)returnfinalCallback(err);this.hooks.run.callAsync(this,err=>{if(err)returnfinalCallback(err);this.readRecords(err=>{如果(错误)返回finalCallback(错误);this.compile(onCompiled);});});});};触发beforeRun的回调触发run的回调,然后调用this.readRecords,在readRecords的回调中调用this.compile(onCompiled)开始编译。一步一步来看,beforeRun会触发之前在NodeEnvironmentPlugin中注册的beforeRunhook。本插件会判断inputFileSystem是否为Configuration,如果没有配置则执行purge清理方法。readRecords会读取一些统计信息。由于没有配置recordsInputPath,这里this.records会被初始化为{}。创建编译实例,然后执行compiler.compiler()方法。compiler.compiler方法贯穿整个编译过程。首先,编译器实例化一个编译。编译(回调){constparams=this.newCompilationParams();this.hooks.beforeCompile.callAsync(params,err=>{if(err)returncallback(err);this.hooks.compile.call(params);constcompilation=this.newCompilation(params);//做点什么}}getparametersnewCompilationParams(){constparams={normalModuleFactory:this.createNormalModuleFactory(),contextModuleFactory:this.createContextModuleFactory()};returnparams;}有两个参数,一个是NormalModuleFactory的实例,一个是实例ContextModuleFactory的,在编译的时候没有找到参数ContextModuleFactory,所以先跳过,后面打个断点看看会不会进来。这里主要看NormalModuleFactory。NormalModuleFactory先看实例化NormalModuleFactory的参数constnormalModuleFactory=newNormalModuleFactory({context:this.options.context,fs:this.inputFileSystem,resolverFactory:this.resolverFactory,options:this.options.module,associatedObjectForCache:this.root,图层:this.options.experiments.layers});注意这里的resolverFactory,后面会用到。接下来看下面newNormalModuleFactory的时候生成了啥constructor({context,fs,resolverFactory,options,associatedObjectForCache,layers=false}){super();this.hooks=定义了很多hooksthis.resolverFactory=resolverFactory;this.ruleSet=ruleSetCompiler.compile([{rules:options.defaultRules},{rules:options.rules}]);this.context=上下文||"";这个.fs=fs;this._globalParserOptions=options.parser;this._globalGeneratorOptions=options.generator;/**@type{Map
