loader:加载器,webpack只能打包js,json文件,而对于css、图片等无法打包,loader的主要作用就是进行文件转化,仅仅是为了打包服务,主要运行在文件打包之前。
plugin:插件,对webpack功能的拓展,针对打包过程中的某些事件节点执行自定义操作,不仅仅是为了打包服务,运行在文件的整个编译周期中。
常用的loader:
babel-loader babel-core
style-loader css-loader
file-loader url-loader
less-loader url-loader
常用的plugin
1.HtmlWebpackPlugin:创建html并引入bundle.js
2.CommonsChunkPlugin:把所有chunk中的公共代码提取成公共js
3.CleanWebpackPlugin:打包前清空上一次的打包内容
4.mini-css-extract-plugin:抽出css到一个单独的文件中
5.DefinePlugin:在编译时创建全局对象(base_url)
自定义插件
配置项
const MyPlugin = require('./plugins/MyPlugin');
//webpack.config.js配置:
module.exports = {
...
plugins: [
new MyPlugin({param: "my plugin"})
]
同步
class MyPlugin{
constructor(options){
console.log("MyPlugin constructor:", options);
}
apply(compiler){
compiler.hooks.emit.tap("MyPlugin", compilation => {
});
}
}
module.exports = MyPlugin;
异步一
class MyPlugin{
constructor(options){
console.log("MyPlugin constructor:", options);
}
apply(compiler){
compiler.hooks.emit.tapAsync("MyPlugin", (compilation,callback) => {
setTimeout(()=>{
console.log("被触发了");
callback()
},3000)
});
}
}
module.exports = MyPlugin;
异步二
class MyPlugin{
constructor(options){
console.log("MyPlugin constructor:", options);
}
apply(compiler){
compiler.hooks.emit.tapPromise("MyPlugin", compilation=> {
return new Promise((resolve,reject)=>{
setTimeout(function(){
console.log("异步执行");
resolve();
},3000)
})
});
}
}
module.exports = MyPlugin;
webpack整个操作流程上有很多钩子函数
可以分为compiler类型和compilation类型
compiler和compliation都是扩展自tapable类
Compiler
代表了整个 Webpack
从启动到关闭的生命周期,
而 Compilation
只是代表了一次新的编译,只要文件有改动,compilation
就会被重新创建。
自定义插件一般用compiler类型
compiler.hooks内部包括很多的钩子函数
钩子函数的触发方式包括同步的(tap,tapAsync,tapPromise)
done是在编译完成时触发
emit是在打包完成后,文件输出到出口位置之前触发
自定义插件过程
1.定义一个插件的类
2.constructor是构造方法,用来接收传递参数
3.在原型上定义一个apply方法,参数 compiler 是webpack 相关的配置信息
4.在compiler.hooks 找到制定的钩子函数
5.添加钩子函数的触发方式,定义插件名称及一些处理方式
compilation对象
就是构建模块和Chunk,并利用插件优化构建过程。