plugin:插件,webpack的核心之一,对webpack能力的扩展,他能做的事情很多,如:打包优化,资源管理,注入环境变量这些。
借用深入浅出 Webpack来解释先webpack中的plugin:
webpack 就像一条生产线,要经过一系列处理流程后才能将源文件转换成输出结果。 这条生产线上的每个处理流程的职责都是单一的,多个流程之间有存在依赖关系,只有完成当前处理后才能交给下一个流程去处理。 插件就像是一个插入到生产线中的一个功能,在特定的时机对生产线上的资源做处理。webpack 通过 Tapable 来组织这条复杂的生产线。 webpack 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条生产线中,去改变生产线的运作。 webpack 的事件流机制保证了插件的有序性,使得整个系统扩展性很好。
也就是webpack 在编译代码过程中,会触发一系列 Tapable 钩子事件,插件所做的,就是找到相应的钩子,往上面挂上自己的任务,也就是注册事件,这样,当 webpack 构建的时候,插件注册的事件就会随着钩子的触发而执行了。
Tapable 还统一暴露了三个方法给插件,用于注入不同类型的自定义构建行为:
tap:可以注册同步钩子和异步钩子。tapAsync:回调方式注册异步钩子。tapPromise:Promise 方式注册异步钩子
插件的基本构成:
首先一个 Plugin 应该是一个 class,当然也可以是一个函数。
其次 Plugin 的原型对象上应该存在一个 apply 方法,当 webpack 创建 compiler 对象时会调用各个插件实例上的 apply 方法并且传入 compiler 对象作为参数。
同时需要指定一个绑定在 compiler 对象上的 Hook , 比如 compiler.hooks.done.tap 在传入的 compiler 对象上监听 done 事件。
在 Hook 的回调中处理插件自身的逻辑,
根据 Hook 的种类,在完成逻辑后通知 webpack 继续进行
一个简单的插件demo
//异步钩子
使用的话在webpack.config.js文件中引入,然后调用就行,
plugins: [
new TestPlugin()
],
运行看一下
plugin的构建对象,核心
compiler 对象中保存着完整的 Webpack 环境配置,每次启动 webpack 构建时它都是一个独一无二,仅仅会创建一次的对象。
这个对象会在首次启动 Webpack 时创建,我们可以通过 compiler 对象上访问到 Webapck 的主环境配置,比如 loader 、 plugin 等等配置信息。
compiler.hooks 可以注册 tapable 的不同种类 Hook,从而可以在 compiler 生命周期中植入不同的逻辑。
compilation 对象代表一次资源的构建,compilation 实例能够访问所有的模块和它们的依赖。
一个 compilation 对象会对构建依赖图中所有模块,进行编译。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)
compilation.hooks 可以注册 tapable 的不同种类 Hook,用于在 compilation 编译模块阶段进行逻辑添加以及修改
主要属性:modules,chunks(由多个modules组成的代码块),assets(本次打包所生成文件的所有结果),hooks(tapable提供的一系列钩子)
具体的属性可以去查看官方的文档。
实现一个简单的注释插件,
class MyPlugin {
constructor(options = {}) {
this.options = options;
}
apply(compiler) {
// 需要处理文件
compiler.hooks.emit.tapAsync("MyPlugin", (compilation, callback) => {
console.log('给所有的打包文件添加注释');
Object.keys(compilation.assets).forEach((assetPath) => {
const asset = compilation.assets[assetPath];
const source =
`/*
* 当前的文件: ${assetPath}
*/\n${asset.source()}`;// 生成新的资源内容
// 覆盖资源
compilation.assets[assetPath] = {
// 资源内容
source() {
return source;
},
// 资源大小
size() {
return source.length;
},
};
});
callback();
});
}
}
module.exports = MyPlugin;

共有 0 条评论