关于webpack hooks.invalid触发时机的源码逻辑咨询
核心问题
当出现监听变更失效的场景时,webpack的hooks.invalid钩子是否会被调用?
现有认知与疑问
根据webpack官方文档说明,hooks.invalid的执行时机为「监听编译失效时」。
官方文档对该钩子的描述:
invalid是 Compiler 实例上的一个同步钩子,会在监听模式下编译失效时执行。
但结合源码梳理后仍存在逻辑疑惑,相关源码参考如下:
相关源码片段
hooks.invalid 调用位置
watch(files, dirs, missing) { this.pausedWatcher = null; this.watcher = this.compiler.watchFileSystem.watch( files, dirs, missing, this.startTime, this.watchOptions, // 主回调:处理编译触发逻辑 (err, fileTimeInfoEntries, contextTimeInfoEntries, changedFiles, removedFiles) => { this.pausedWatcher = this.watcher; this.watcher = null; if (err) { this.compiler.modifiedFiles = undefined; this.compiler.removedFiles = undefined; this.compiler.fileTimestamps = undefined; this.compiler.contextTimestamps = undefined; return this.handler(err); } this.compiler.fileTimestamps = fileTimeInfoEntries; this.compiler.contextTimestamps = contextTimeInfoEntries; this.compiler.removedFiles = removedFiles; this.compiler.modifiedFiles = changedFiles; if (!this.suspended) { this._invalidate(); } }, // 回调:触发 hooks.invalid (fileName, changeTime) => { this.compiler.hooks.invalid.call(fileName, changeTime); } ); }
源码位置:lib/Watching.js 第252行附近
watchFileSystem.watch 第7个参数的处理逻辑
watch(files, dirs, missing, startTime, options, callback, callbackUndelayed) { // 入参校验逻辑省略 const oldWatcher = this.watcher; this.watcher = new Watchpack(options); if (callbackUndelayed) { // 将传入的 undelayed 回调绑定到 Watchpack 的 change 事件 this.watcher.once("change", callbackUndelayed); } // 其余初始化逻辑省略 }
源码位置:lib/node/NodeWatchFileSystem.js 第45行附近
触发规则梳理
- 真实触发链路
hooks.invalid的回调会作为watchFileSystem.watch的第7个参数(即callbackUndelayed)传入,最终被绑定到底层文件监听库Watchpack的change事件上- 只要文件监听器正常捕获到被监听文件的修改、新增、删除动作,在正式启动新一轮编译流程之前,就会立刻触发
hooks.invalid,回调会传入发生变更的文件路径、变更时间两个参数
- 文档语义澄清
- 官方提到的「监听编译失效时」,指的是上一轮生成的编译产物因为文件变更,不再处于有效状态的时机,不是指“监听机制本身故障失效”的场景
- 关键边界规则
- 如果监听器因为系统inotify配额超限、文件系统权限不足、跨挂载盘不支持监听等原因完全失效、根本捕获不到文件变更,不会触发
hooks.invalid——因为从根源上就走不到change事件的触发分支 - 监听器捕获变更后的后续流程,即收集文件时间戳、触发重新编译、执行全量编译逻辑,是通过
watch方法的第6个主回调实现的,这个流程里不会重复触发hooks.invalid - 监听报错、编译失败的异常场景走独立的错误回调通道,也不会触发
hooks.invalid
- 如果监听器因为系统inotify配额超限、文件系统权限不足、跨挂载盘不支持监听等原因完全失效、根本捕获不到文件变更,不会触发
内容的提问来源于stack exchange,提问作者Wilkin Wendy
相关产品推荐
相关产品推荐

