webpack编写插件

 我来答
大沈他次苹0B
2022-07-26 · TA获得超过7327个赞
知道大有可为答主
回答量:3059
采纳率:100%
帮助的人:178万
展开全部

查看原文 | 编辑此页

插件向第三方开发者提供了 webpack 引擎中完整的能力。使用阶段式的构建回调,开发者可以引入它们自己的行为到 webpack 构建流程中。创建插件比创建 loader 更加高级,因为你将需要理解一些 webpack 底层的内部特性来做相应的钩子,所以做好阅读一些源码的准备!

webpack 插件由以下组成:

在插件开发中最重要的两个资源就是 compiler 和 compilation 对象。理解它们的角色是扩展 webpack 引擎重要的第一步。

这两个组件是任何 webpack 插件不可或缺的部分(特别是 compilation ),因此,开发者在阅读源码,并熟悉它们之后,会感到获益匪浅:

插件是由「具有 apply 方法的 prototype 对象」所实例化出来的。这个 apply 方法在安装插件时,会被 webpack compiler 调用一次。 apply 方法可以接收一个 webpack compiler 对象的引用,从而可以在回调函数中访问到 compiler 对象。一个简单的插件结构如下:

然后,要安装这个插件,只需要在你的 webpack 配置的 plugin 数组中添加一个实例:

使用 compiler 对象时,你可以绑定提供了编译 compilation 引用的回调函数,然后拿到每次新的 compilation 对象。这些 compilation 对象提供了一些钩子函数,来钩入到构建流程的很多步骤中。

关于 compiler , compilation 的可用回调,和其它重要的对象的更多信息,请查看 插件 文档。

有一些编译插件中的步骤是异步的,这样就需要额外传入一个 callback 回调函数,并且在插件运行结束时, 必须 调用这个回调函数。

一旦能我们深入理解 webpack compiler 和每个独立的 compilation,我们依赖 webpack 引擎将有无限多的事可以做。我们可以重新格式化已有的文件,创建衍生的文件,或者制作全新的生成文件。

让我们来写一个简单的示例插件,生成一个叫做 filelist.md 的新文件;文件内容是所有构建生成的文件的列表。这个插件大概像下面这样:

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)

- 并行(parallel) -

applyPluginsParallel(name: string, args: any..., callback: (err?: Error) -> void)

applyPluginsParallelBailResult(name: string, args: any..., callback: (err: Error, result: any) -> void)

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式