As we all know, Loader and Plugin are two important configuration items of Webpack, which are also the key to understand the packaging principle of Webpack deeply. In the previous article, loader runtime timing and principles were introduced (juejin.cn/post/700239…). This article will take a look at how the plug-in plugin works.

1. Why do you need a plugin

Plugin is mainly used to provide extension functions for Webpack (such as compress package file content, automatically generate HTML and clear package file etc.). The plug-in mechanism can make Webpack more practical and powerful.

2. What is the nature of a plugin

Let’s look at the plugin configuration as follows:

New HtmlWebpackPlugin({template: './ SRC /index.html'})]Copy the code

The configuration allows you to see that the plugin is created with new, that the plugin is essentially a class (which functions will be expanded later), and that you can pass in arguments in object format.

3. How is plugin implemented

In the first article, we analyzed the overall implementation process of Webpack, and then reviewed the whole process, as shown in the figure below:

Plugin consists of initialization, plugin registration and Plugin execution.

3.1 the initialization

As you can see, WebPack iterates through the plugins configuration to initialize and calls the plug-in’s Apply method when plugin is not a function. Initialization further reveals that plugin is essentially a function or class with apply (here apply is not JavaScript’s native Apply, but the plug-in’s method) and accepts compiler. Such as:

Class MyPlugin{constructor(options) {constructor(options) {apply(compiler){// events listen... } } module.exports = MyPlugin;Copy the code
This is the basic structure that we used to implement custom plugins, discovering that plugins are not magic and that it is entirely possible to implement them ourselves.Copy the code

3.2 the plugin is registered

Since the Plugin receives the Compiler object, it can register events through the compiler provided hook functions. Such as:

The compiler. The hooks. The stage. Event type (name, Compilation = > {/ / event handler}) / / such as automatically generated HTML HtmlWebpackPlugin plug-in compiler.hooks.com pilation. Tap (' HtmlWebpackPluginHooks', compilation => { });Copy the code

Where the event name can be defined arbitrarily, as long as it is not repeated, the event type is based on tapable, used for the hook function listening library, there are three types:

TapAsync: Registers an asynchronous callback-based hook function. The function calls a callback to indicate the end of event processing. TapPromise: Register an asynchronous, promise-based hook function that signals the end of event processing by returning a Promise to a determined stateCopy the code

You might wonder why, because the hooks of the Compiler class are instances of Tapable, so you can use tapable’s methods.

3.3 the plugin implementation

Plugin execution is triggered by call(synchronous) or callAsync (asynchronous), for example: Compiler file this.hooks.com pilation. Call (compilation, params) statements will trigger the compiler.hooks.com pilation. Tap register event.

Knowing this is also important to help track the overall flow of WebPack, using call/callAsync global search to find registration events and thus string together the entire execution.

4. To summarize

Through the above analysis, I believe that the plug-in related content has a further understanding, so only clear principle can better understand the framework, to help us achieve personalized needs.

Thanks for reading and don’t forget to like it

Attached historical article:

【 WebPack series 】 Analyze webpack packaging output and core process from the source point of view

【 Webpack series 】 How to trigger and execute loader from the perspective of source code

How does Webpack parse modules