阅读 400

webpack运行过程(webpack菜鸟教程)

异步执行AsyncQueue下的_ensureProcessing()方法执行时

首先会遍历this._queued,但此时this._queued.length = 0

其次会遍历this.children,此时this.children.length = 3

this._children为三个AsyncQueue

  1. _name为addModule的AsyncQueue, 开始它的_queued.length=0

  2. _name为factorize的AsyncQueue, 开始它的_queued.length=入口个数

  3. _name为build的AsyncQueue, 开始它的_queued.length=0

this.children的每一个AsyncQueue下面有一个_queued,即this.children[0]._queued

首先会处理_name是factorize的AsyncQueue

this.children[1]._queued.length=2

this.children[1]._queued是两个AsyncQueueEntry

所以执行_ensureProcessing()方法,首先会遍历 this.children[1]._queued,执行_startProcessing方法

由于AsyncQueued的this._parallelism默认是1;所以并不会两个都执行 而是执行一个入口的factorize,再执行该入口的addModule; 接着执行下一个入口的factorize,在执行addModule

factorize是分解的意思

_startProcessing()调用this.Processor,此时的Processor的name是 'bound _factorizeModule'

_ensureProcessing(entry){     this.processor(entry.item) } 复制代码

其次会处理_name是addModule的AsyncQueue

factorize和addModule的默认处理顺序是处理完一个入口的factorize和addModule,再处理下一个入口的factorize和addModule; 所有入口的factorize和addModule都处理完成后,再处理build

最后处理_name是build的AsyncQueue,_name是addModule的AsyncQueue处理完后,它的_queued.length=入口的个数

此时的Processor的name是 'bound _addModule'

name为factorize的异步队列的执行过程

  • Compilation类 的_factorizeModule()方法内部调用了NormalModuleFactory的create方法

function _factorizeModule(){     factory.create() } 复制代码

  • NormalModuleFactory类 的create()方法中触发了自己的beforeResolve钩子

  • NormalModuleFactory类 的beforeResolve钩子执行完成后触发了自己的factorize钩子

function create(){     this.hooks.beforeResolve.callAsync(resolveData, (err, result) => {         this.hooks.factorize.callAsync(resloveData, (err, module))     }) } 复制代码

ExternalModuleFactoryPlugin 插件注册了normalModuleFactory的factorize钩子

function apply(normalModuleFactory){     normalModuleFactory.hooks.factorize.tapAsync("ExternalModuleFactoryPlugin",(data,callback)=>{         fuction handleExternal(){             callback()         }         handleExternal()     }) } 复制代码

NormalModuleFactory自己注册了自己的factorize钩子 NormalModuleFactory的factorize钩子执行完成后触发自己的reslove钩子

this.hooks.factorize.tapAsync({}, ()=>{     this.hooks.reslove.callAsync() }) 复制代码

  • NormalModuleFactory自己注册了自己的reslove钩子

  • reslove钩子内部调用了defaultResolve()方法

  • defaultResolve()方法调用了resolveResource()方

  • resolveResource()方法调用了Resolver类的resolve()方法

  • resolve()方法调用了doResolve()方法

  • Resolver的doResolve()方法内部触发了自己的resolve钩子

  • ResolverCachePlugin插件注册了Resolver的resolve钩子

  • DescriptionFileFlugin插件注册了Resolver的resolve钩子

       用来处理描述文件即package.json文件 复制代码

  • NextPlugin插件注册了Resolver的resolve钩子

  • AliasFieldPlugin插件注册了Resolver的resolve钩子

    先读取package.json文件中的browser的配置 browser配置:定义npm包在browser环境下的入口文件 复制代码

  • ConditionalPlugin插件注册了Resolver的resolve钩子

  • RootsPlugin插件注册了Resolver的resolve钩子

  • FileExistsPlugin插件注册了Resolver的resolve钩子

const file = requet.path fs.stat(file, ) // CachedInputFileSystem文件 class CacheBackend {     provide(path, options, callback){         let cacheEntry = this._data.get(paeh)         if(cacheEntry !== undefined){         }         this._provider.call(this._providerContext, path, (err, path) => {               this._storeResult(path, err, result)         })     } } //graceful-fs/polyfills.js function statFix(){ } // <node_internal>/fs.js function stat(path, options = {bigit:false}, callback){ } 复制代码

newStack = [     "resolve: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "parsedResolve: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "describedResolve: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "normalResolve: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "relative: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "describedRelative: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "rawFile: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "file: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "finalFile: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "existingFile: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js",     "resolved: (D:\\code\\web_learn\\webpack\\demo) ./src/app.js" ] 复制代码

将入口文件及其相关联文件和路径加入到AsyncQueue._queued中,然后遍历AsyncQueue._queued

AsyncQueue._queued = [     "D:\\code\\web_learn\\webpack\\demo\\src\\app.js",     "D:\\code\\web_learn\\webpack\\demo\\src",     "D:\\code\\web_learn\\webpack\\demo",     "D:\\code\\web_learn\\webpack",     "D:\\code\\web_learn",     "D:\\code",     "D:\\",     "D:\\code\\web_learn\\webpack\\demo\\package.json",     "D:\\code\\web_learn\\webpack\\demo\\src\\search.js", ] 复制代码

name为addModule的异步队列的执行过程

_startProcessing(entry){     this._processor(entry.item, (e,r) => {         this._handleResult(entry, e, r)     }) } 复制代码

调用Compilation的_addModule()

// module大致的样子 module = {     rawRequest: './src/app.js',     request: 'D:\\code\\web_learn\\webpack\\demo\\src\\app.js',     resource: 'D:\\code\\web_learn\\webpack\\demo\\src\\app.js',     userRequest: 'D:\\code\\web_learn\\webpack\\demo\\src\\app.js',     type: 'javascript/auto' } function _addModule(module, callback) {     const identifier = module.identifier     //判断是否已经添加     const alreadyAddedModule = this._modules.get(identifier)     if(alreadyAddedModule){         return callback(null, alreadyAddedModule)     }     // 从缓存中读取     this.modulesCache.get(identifier, null, (err, cacheModule) => {         if(cacheModule) {             cacheModule.updateCacheModule(module)             module = cacheModule         }         this._modules.set(identifier, module)         this.modules.add(module)         callback(null,module) // 执行_handleResult     }) } 复制代码

执行AsyncQueue类中的_handleResult()

执行Compilation下面的handleModuleCreation下面的this.factorizeModule下面的 addModule(newModule)

执行Compilation下面的_handleModuleBuildAndDependencies 下面的 this.buildModule

Compilation的buildQueue新增newModule:this.buildQueue.add(module, callback)

接着将其他的module添加到buildQueue中

所有module加入到buildQueue后,name为build的AsyncQueued的_queued.length = 2

所以接着遍历这个_name为build的AsyncQueue的_queued

name为build 的异步队列的执行过程

此时_this.processer为 bound _buildModule

执行Compilation类下的_buildModule()

  1. 首先判断该module是否需要build

_buildModule(module, callback) {     module.needBuild({}, (err, needBuild) => {          if(needBuild){              this.hooks.buildModule.call(module)              this.buildModules.add(module)              module.build()          }              })     } 复制代码

  1. 开始构建module

// NormalModule.js function build(){     this._doBuild() } _doBuild(){ }


作者:yanessa_yu
链接:https://juejin.cn/post/7034797921027489829

文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐