webpack 在打包的各个不同的生命周期阶段(钩子函数),添加一些逻辑处理
class HuangbiaoWebpackPlugin {
// 构造函数,获取传递的参数
constructor (options) {
console.log("获取传递的参数")
debugger
console.log("options", options);
}
// Compiler 模块是 webpack 的支柱引擎,它通过 CLI 或 Node API 传递的所有选项,创建出一个 compilation 实例。
// 它扩展(extend)自 Tapable 类,以便注册和调用插件。大多数面向用户的插件首,会先在 Compiler 上注册。
apply (compiler) {
console.log("我在apply 方法里面")
debugger
/**
* emit 生成资源到 output 目录之前
* tapAsync 注册的事件
* CopyrightWebpackPlugin 字符串表示插件的名字,就是根据它来决定插件注册和触发
* callback 是回调方法,异步方法,一定要执行
*/
compiler.hooks.emit.tapAsync("CopyrightWebpackPlugin", (compilation, callback) => {
console.log("开始插件的表演")
debugger
// 异步,一定要执行最后这个方法,否则会卡死在这里不会继续往下运行
callback()
})
}
}
module.exports = CopyrightWebpackPlugin
一个 JavaScript 命名函数。
constructor 是构造方法,初始化传递的参数,可以通过该方法接收
plugin类一定要有一个 apply 方法,参数 compiler 是webpack 相关的配置信息
在插件函数的 prototype 上定义一个 apply 方法
指定一个绑定到 webpack 自身的事件钩子,
处理 webpack 内部实例的特定数据
这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。
当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。
这两个组件是任何 webpack 插件不可或缺的部分(特别是 compilation),因此,开发者在阅读源码,并熟悉它们之后,会感到获益匪浅:
// vue.config.js
const webpack = require("webpack");
const HuangbiaoWebpackPlugin = require('./webpack/huangbiao-webpack-plugin.js')
module.exports = {
configureWebpack: {
//支持jquery
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"windows.jQuery": "jquery"
}),
new HuangbiaoWebpackPlugin({
name: "黄彪"
})
]
}
};
有一些编译插件中的步骤是异步的,这样就需要额外传入一个 callback 回调函数,并且在插件运行结束时,_必须_调用这个回调函数。
webpack 插件可以按照它所注册的事件分成不同的类型。每一个事件钩子决定了它该如何应用插件的注册。
applyPlugins(name: string, args: any...)
applyPluginsBailResult(name: string, args: any...)
这意味着每个插件回调,都会被特定的 args 一个接一个地调用。 这是插件的最基本形式。许多有用的事件(例如 “compile”, “this-compilation”),预期插件会同步执行。
applyPluginsWaterfall(name: string, init: any, args: any...)
这种类型,每个插件都在其他插件依次调用之后调用,前一个插件调用的返回值,作为参数传入后一个插件。这类插件必须考虑其执行顺序。 必须等前一个插件执行后,才能接收参数。第一个插件的值是初始值(init)。这个模式用在与 webpack 模板相关的 Tapable 实例中(例如 ModuleTemplate, ChunkTemplate 等)。
applyPluginsAsync(name: string, args: any..., callback: (err?: Error) -> void)
这种类型,插件处理函数在调用时,会传入所有的参数和一个签名为 (err?: Error) -> void 的回调函数。处理函数按注册时的顺序调用。在调用完所有处理程序后,才会调用 callback。 这也是 “emit”, “run” 等事件的常用模式。
applyPluginsAsyncWaterfall(name: string, init: any, callback: (err: Error, result: any) -> void)
这种类型,插件处理函数在调用时,会传入当前值(current value)和一个带有签名为 (err: Error, nextValue: any) -> void. 的回调函数。当调用的 nextValue 是下一个处理函数的当前值(current value)时,第一个处理程序的当前值是 init。在调用完所有处理函数之后,才会调用 callback,并将最后一个值传入。如果其中任何一个处理函数传入一个 err 值,则会调用此 callback 并将此 error 对象传入,并且不再调用其他处理函数。 这种插件模式适用于像 “before-resolve” 和 “after-resolve” 这样的事件。
applyPluginsAsyncSeries(name: string, args: any..., callback: (err: Error, result: any) -> void)
applyPluginsParallel(name: string, args: any..., callback: (err?: Error) -> void)
applyPluginsParallelBailResult(name: string, args: any..., callback: (err: Error, result: any) -> void)