携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情
按照顺序提取其中一部分关键的环节。如下图:
首先要注意的是
this.hook.make.callAsync 和 this.hook.make.tapAsync 这种用法几乎涉及到webpack的各个部分,它使用钩子来串联业务的不同环节。
在上图中对于每个方法所在的文件路径都进行了标注,它的具体位置是工程根目录下的node_modules文件夹。这里所提取的环节全部都是webpack下的,需要注意的是,它在过程中还会涉及到其他的模块。比如 tapable、webpack-source、webpack-cli、style-loader、css-loader等。
在Compiler.js中可以看到 this.hooks.make 对应的是:
对于钩子的用法在前面tapable的文章中介绍过。简单理解为它是一种事件监听的消息机制。tap是订阅者,而call是监听者。监听者监听消息,发布给订阅者。所以执行到
this.hook.make.callAsync的时候,它会调用 this.hook.make.tapAsync的回调函数。这里需要强调的时,callAsync 执行的是 tapAsync的回调。所以,在 this.hook.make.callAsync 执行之前,会先执行 this.hook.make.tapAsync ,把订阅者给放到 taps 的数组中。如下:
这个方法对于掌握webpack中针对钩子的使用过程非常重要。
这里在开始的时候调用了EntryPlugin,是因为它处理的是对应于入口文件的逻辑。而这个入口文件配置与webpack.config.js 中的 entry,也就是如下内容:
...
module.exports={
entry:'./main.js',
...
}
当在Compilation.js 下的 _addEntryItem 中执行完 this.hooks.addEntry.cal(entry,options) 之后,会发现在终端中的进度信息展示如下:
10% building 0/1 entries 0/0 dependencies 0/0 modules
这就说明当前的操作正在构建入口配置的信息。
然后进入到构建阶段,构建过程中针对模块的加载,不同模块钩子的配置,构建后执行 runLoaders,这里的runLoaders会调用 loader-runner 中的 runLoaders,如下:
这其中关键的一步是 processResource,如下:
执行后回调到 NormalModule.js 下的 runLoaders 下的 processResource 中,如下:
通过 hooks.readResource.for 获取对应的钩子,读取文件,如下: