以下是Webpack核心生命周期钩子的详细解析及示例说明:
一、初始化阶段
-
**
entryOption**
处理entry配置验证,可修改入口配置compiler.hooks.entryOption.tap('MyPlugin', (context, entry) => { return { main: './new-entry.js' }; // 动态修改入口 }); -
**
afterPlugins**
所有插件注册完成后触发,适合初始化全局变量compiler.hooks.afterPlugins.tap('MyPlugin', () => { global.__DEV__ = process.env.NODE_ENV === 'development'; });
二、编译阶段
-
**
compile**
开始编译前触发,可注入自定义参数8compiler.hooks.compile.tap('MyPlugin', (params) => { params.compilationDependencies.add('custom-dep'); }); -
**
compilation**
创建compilation对象时触发,常用于修改模块处理逻辑compiler.hooks.compilation.tap('MyPlugin', (compilation) => { compilation.hooks.optimize.tap('MyPlugin', () => { // 模块优化逻辑 }); });
三、模块处理阶段
-
**
make**
分析模块依赖图的起点,可拦截模块解析compiler.hooks.make.tapAsync('MyPlugin', (compilation, callback) => { compilation.addEntry(__dirname, 'custom-module.js', callback); }); -
**
afterCompile**
模块编译完成后触发,适合收集编译元数据compiler.hooks.afterCompile.tap('MyPlugin', (compilation) => { console.log(compilation.fileDependencies); });
四、输出阶段
-
**
emit**
生成资源到output目录前触发,可修改最终输出compiler.hooks.emit.tap('MyPlugin', (compilation) => { compilation.assets['license.txt'] = { source: () => 'MIT License', size: () => 10 }; }); -
**
afterEmit**
资源已写入磁盘后触发,适合执行清理操作compiler.hooks.afterEmit.tapPromise('MyPlugin', async () => { await fs.promises.unlink('temp-file.js'); }); -
**
done**
整个构建流程结束时触发,用于统计构建信息compiler.hooks.done.tap('MyPlugin', (stats) => { console.log(`构建耗时:${stats.toJson().time}ms`); });
典型应用场景
- 性能监控:通过
done钩子统计构建时间 - 动态入口:利用
entryOption实现多页面自动配置 - 资源注入:在
emit阶段添加LICENSE文件