Webpack其实像是一条生产线,在经过一系列的处理流程后,才会将源文件转为输出结果,同时它的整个生命周期中会广播出大量的事件,以供我们通过plugin去监听,我们可以通过这些API去改变输出的结果
如果你想手写一个Plugin的话,他是这样的:
//新建MyWebpackPlugin.js
const { compilation } = require("webpack");
class myWebpackPlugin {
//option是在导入插件时,可以传入的参数
constructor(option){
}
// 这里也可以传入function
constructor(donecallback,failedcallback){
this.donecallback = donecallback;
this.failcallback = failcallback;
}
apply(compiler){
//当webpack完成构建并输出后,在退出webpack前触发
compiler.plugin('done',(state)=>{
console.log("webpack打包成功");
this.donecallback(state);
});
//当webpack完成构建异常导致失败,在退出webpack前触发
compiler.plugin('failed',(state)=>{
console.log("webpack打包失败");
this.failedcallback(state);
})
}
}
module.exports = myWebpackPlugin;
并需要在webpack.base.conf.js下增加如下配置:
const mywebpackPlugin = require('../src/commonJS/MyWebpackPlugin')
//这个是用来显示build进度条的插件
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
module.exports = {
plugins:[new mywebpackPlugin(()=>{
//成功回调,这里可以传function,也可以改成param参数
},(err)=>{
//失败回调
}),
new ProgressBarPlugin()
]
}
compiler和compilation
· Compiler包含了webpack环境中所有的上下文配置信息,它伴随着webpack的整个生命周期,并且全局唯一,在所有的插件中被共享,所以说插件与插件之间其实是可以相互影响的。
· Compilation包含了当前的模块资源(chunks),编译生成的资源等,我们通过它可以获取到当前编译模块的信息,通过大量的事件回调接口可以对其进行修改等扩展操作。
开源插件解析
1、webpack-clear-console
//发生emit事件时,所有的模块转换和代码块已经完成了,打包的资源即将输出
//因此emit是修改webpack输出资源最后的机会
compiler.plugin('emit',function(compilation,callback) => {
//这里是引申:compilation.assets是一个键值对
//key是要输出的文件名,value是内容
//所以根据这个你可以最后生成一个html,导出输出的文件清单什么的
for(let i in compilation.assets){
console.log(i);
}
//compilation.chunks是所有的代码块,对其进行遍历,chunk就代表其中的一个
compilation.chunks.forEach(function(chunk){
//对其中一个代码块进行遍历,filename是文件名
chunk.files.forEach(function(filename){
//见上文引申,compilation.assets[filename]是即将输出的资源
//使用.source()方法可以获得到资源内容
let source = compilation.assets[filename].source();
//这里console的类型没有写完,大家可以去翻一下源代码
let consoleName = ['console','window.console'];
let consoleType = ['log','info','error','warn'];
//正则表达式,略
regConsole = new RegExp(..........................);
//开始替换
source = source .replace(regConsole ,function(){
return source.replacewith || ''
});
//将替换完成的内容覆盖至compilation
compilation.assets[filename] = {
source:() => source
size:() => source.length
}
});
});
//这是一个异步事件,最后需要调用callback()来通知webpack本次处理结束
//如果没有callback()则webpack会在这里卡死,不会继续执行。
callback();
})
2、island-webpack-plugin是一个增加作者信息的插件
这个跟上边那个差不多,就不做解释了。