plugin介绍:
通过插件可以扩展webpack,加入自定义的构建行为,使webpack可以执行更广泛的任务,有更强的构建能力
plugin工作原理:
- webpack就像一条生产线,这条生产线有很多流程,插件就像一个插入到生产线的一个功能,在特定时机对生产线上的资源做处理。webpack通过tapable来组织复杂的生产线,插件只需监听它所关心的事件,就能加入到生产线中,去改变生产线的运作。
- 通俗来讲,就是webpack在编译代码过程中,会触发一系列tapable钩子事件,插件所做的,就是找到相应钩子,往上面挂上自己的任务,也就是注册事件。这样,当webpack构建的时候,插件注册的事件就会随着钩子的触发而执行了。
理解tapable:
webpack内部的钩子
- 钩子的本质是事件,tapable为webpack提供了统一的插件接口(钩子)类型定义,它是webpack的核心功能库,webpack中目前有十种钩子
tapable统一暴露了三个方法给插件:
用于注入不同类型的自定义构建行为:
1. tap:可以注册同步钩子和异步钩子
1. tapAsync:回调方式注册异步钩子
1. tapPromise:Promise方式注册异步钩子
plugin构建对象-compiler和compilation:
- compiler的介绍:compiler对象贯穿了整个webpack生命周期的一个实例,从启动到结束都存在,它代表了完整的webpack环境配置
- compilation:该对象是在每次新的资源构建时创建的一个实例,它代表了一次单独的版本构建。比如在开发模式下,启用watch后,每次文件都会触发新的compilation,从而生成一组新的编译资源。
webpack在加载和执行插件时的核心流程:
暂时无法在飞书文档外展示此内容
怎么用node调试compiler和compilation:
- 为什么需要node调试工具:
在webpack插件开发中,直接调试compiler和compilation对象是理解其内部机制的关键
-
调试的流程:
- 在debugger行设置断点
- 启动webpack调试:node --inspect-brk ./node_modules/webpack/bin/webpack.js
- 调试后,找到需要的属性,在控制台打印测试
自定义插件:
//需求:给打包输出文件添加注释
const { compilation } = require("webpack");
//开发思路:
//触发时机:生成资源到输出目录之前 emit钩子
//如何获取打包输出的资源?compilation可以获取所有的即将输出的资源文件
class BannerWebpackPlugin{
constructor(){}
apply(compiler){
compiler.hooks.emit.tap('BannerWebpackPlugin',(compilation)=>{
debugger;
const extensions=['css','js'];
//过滤只保留这两种文件
const assets=Object.keys(compilation.assets).filter((assetpath)=>{
const splitted=assetpath.split('.');
const extension=splitted[splitted.length-1];
return extensions.includes(extension)
})
const prefix = '/* Built by BannerWebpackPlugin */\n';
assets.forEach((asset)=>{
const source=compilation.assets[asset].source();//原来内容
const content=prefix+source; //拼接上注释
//修改资源
compilation.assets[asset]={
source(){
return content; //资源内容
},
size(){
return content.length
}
}
})
})
}
}
module.exports=BannerWebpackPlugin