1.plugin自定义
webpack在编译代码过程中 ⽣命周期概念 对应不同的打包阶段
不同打包阶段
- module
- Assets plugin本质上是⼀个类
它是如何注册到webpack的对应阶段的
2.webpack的打包流程
- 拿到配置,初始化⼯作 最终配置
- 实例化⼀个compiler类,注册插件,对应的⽣命周期绑定相应的时间
- 执⾏编译,compiler.run //各阶段
- compiler(构建阶段)->compilation(第七个阶段,bundle资源被加⼯成什么样⼦了)
- 递归处理所有的依赖模块 ⽣成chunk
- 把chunk输出到output指定的位置
3.生命周期钩子
//示例1
const pluginName = 'ConsoleLogOnBuildWebpackPlugin';
//compiler hook 的 tap 方法的第一个参数,应该是驼峰式命名的插件名称。建议为此使用一个常量,以便它可以在所有 hook 中复用。
class ConsoleLogOnBuildWebpackPlugin {
apply(compiler) {
compiler.hooks.run.tap(pluginName, compilation => {
console.log('webpack 构建过程开始!');
});
}
}
//示例2 触发所有hooks 对应的自定义事件test
const webpack = require("webpack");
const webpackConfig = require("./webpack.config.js");
const compiler = webpack(webpackConfig);
Object.keys(compiler.hooks).forEach((hookName) => {//拿到所有钩子的名字
compiler.hooks[hookName].tap("test", () => {//添加对应的tap事件,test为定义的事件名,可以多次订阅
console.log(`run ------ > ${hookName}`);
});
});
compiler.run();//运行webpack
// run ------ > beforeRun
// run ------ > run
// run ------ > normalModuleFactory
// run ------ > contextModuleFactory
// run ------ > beforeCompile
// ...
// run ------ > compile
// run ------ > thisCompilation
// run ------ > compilation
// run ------ > make
// run ------ > normalModuleFactory
// run ------ > contextModu
// run ------ > assetEmitted
// run ------ > assetEmitted
// run ------ > afterEmit
// run ------ > done
compiler.hooks[hookName].tap的实现,订阅发布
class SyncHook {
construct
or(options) {
this.options = options
this.hooks = [] //存放监听函数的数组
}
tap(name, callback) {
this.hooks.push(callback)
}
call(...args) {
for (let i = 0; i < this.hooks.length; i++) {
this.hooks[i](...args)
}
}
}
const synchook = new SyncHook('name')
// 注册监听函数
synchook.tap('name', (data) => {
console.log('name', data)
})
synchook.tap('age', (data) => {
console.log('age', data)
})
//发布事件
synchook.call('test')
4.自定义打包文本plugin
//myPlugins/txt-webpack-plugin.js
class TxtWebpackPlugin {
// apply函数 帮助插件注册,接收complier类
constructor(options) {
console.log(options);
}
apply(complier) {
//这是一个异步的钩子
complier.hooks.emit.tapAsync("TxtWebpackPlugin", (compilation, cb) => {
// console.log(compilation.assets);
compilation.assets["xxx.txt"] = {
source: function () {
// 定义文件的内容
return "输出内容XXXXXXXX!!!!!";
},
size: function () {
// 定义文件的体积
return 1024;
},
};
cb();//记得要调用回调cb才能往下进入下一个钩子
});
//这是一个同步的钩子
complier.hooks.compile.tap("TxtWebpackPlugin", (compilation) => {
console.log("哈哈 我是一个同步的钩子");
});
}
}
module.exports = TxtWebpackPlugin;
//webpack.config.js
const txtWebpackPlugin = require("./myPlugins/txt-webpack-plugin.js");
module.exports = {
...
plugins: [
new txtWebpackPlugin({
name: "参数11",
}),
...
]
}