每个hook都是一个 tapable包里对应后hook的实例
在回到创建编译器那里,这时创建一个插件的实例,并且执行apply方法,插件就会向自己关系的hook添加事件处理函数(其实还是一个事件监听) , NodeEnvironmentPlugin代码可以自行在源码中查看
new NodeEnvironmentPlugin({infrastructureLogging: options.infrastructureLogging }).apply(compiler);
一切都准备好了之后,我们再看一下编译器的run方法
/*** @param {Callback<Stats>} callback signals when the call finishes* @returns {void}*/ run(callback) {if (this.running) {return callback(new ConcurrentCompilationError());}let logger;const finalCallback = (err, stats) => {if (logger) logger.time("beginIdle");this.idle = true;this.cache.beginIdle();this.idle = true;if (logger) logger.timeEnd("beginIdle");this.running = false;if (err) {this.hooks.failed.call(err);}if (callback !== undefined) callback(err, stats);this.hooks.afterDone.call(stats);};const startTime = Date.now();this.running = true;const onCompiled = (err, compilation) => {if (err) return finalCallback(err);if (this.hooks.shouldEmit.call(compilation) === false) {compilation.startTime = startTime;compilation.endTime = Date.now();const stats = new Stats(compilation);this.hooks.done.callAsync(stats, err => {if (err) return finalCallback(err);return finalCallback(null, stats);});return;}process.nextTick(() => {logger = compilation.getLogger("webpack.Compiler");logger.time("emitAssets");this.emitAssets(compilation, err => {logger.timeEnd("emitAssets");if (err) return finalCallback(err);if (compilation.hooks.needAdditionalPass.call()) {compilation.needAdditionalPass = true;compilation.startTime = startTime;compilation.endTime = Date.now();logger.time("done hook");const stats = new Stats(compilation);this.hooks.done.callAsync(stats, err => {logger.timeEnd("done hook");if (err) return finalCallback(err);this.hooks.additionalPass.callAsync(err => {if (err) return finalCallback(err);this.compile(onCompiled);});});return;}logger.time("emitRecords");this.emitRecords(err => {logger.timeEnd("emitRecords");if (err) return finalCallback(err);compilation.startTime = startTime;compilation.endTime = Date.now();logger.time("done hook");const stats = new Stats(compilation);this.hooks.done.callAsync(stats, err => {logger.timeEnd("done hook");if (err) return finalCallback(err);this.cache.storeBuildDependencies(compilation.buildDependencies,err => {if (err) return finalCallback(err);return finalCallback(null, stats);});});});});});};const run = () => {this.hooks.beforeRun.callAsync(this, err => {if (err) return finalCallback(err);this.hooks.run.callAsync(this, err => {if (err) return finalCallback(err);this.readRecords(err => {if (err) return finalCallback(err);this.compile(onCompiled);});});});};if (this.idle) {this.cache.endIdle(err => {if (err) return finalCallback(err);this.idle = false;run();});} else {run();} }
https://github.com/webpack/webpack/blob/main/lib/Compiler.js
这里简单分析一下,主要就是执行run相关生命周期 , 以及编译 。并且编译完成后传入回调函数onCompiled
const run = () => {this.hooks.beforeRun.callAsync(this, err => {if (err) return finalCallback(err);this.hooks.run.callAsync(this, err => {if (err) return finalCallback(err);this.readRecords(err => {if (err) return finalCallback(err);this.compile(onCompiled);});});});};
整体逻辑不是很复杂,我们主要可以感受到webpack启动后对hook的一些使用方式 。整体的逻辑差不多都是一样的 。是不是很简单 。
总结
- 想了解一个框架,一定要找到入口函数,一点一点向前探索 。
- tapable 是个好东西,
- 关于webpack生命周期,有疑问的时候,除了看文档意外,还可以结合源码去理解,去感受
推荐阅读
- 1、显示发布者的名字;2、增加新UI、3、关注其他学员的 canister IC入门课第五课作业:完善 Microblog 前端
- 原神11.14最新礼包码是多少
- 固定式刚性联轴器有哪些 刚性联轴器有哪些
- 华为手机怎么截屏三种方法(华为手机怎么截短屏图)
- 微信群怎么建(微信群找不到了怎么办)
- 莫桑钻100多元买的到吗 300元能买到莫桑钻吗
- pvc胶水有毒吗弄到脸上会怎么样 pvc胶水有毒吗
- 吊带锻炼方法 训练吊带怎么用练腹肌
- 电脑打开一直蓝屏怎么办 电脑一直蓝屏怎么办 电脑蓝屏怎么解决
- 4.2货车多久换齿轮油 大型货车多久换齿轮油