There are many hooks in Webpack, each of which subscribes to the registered plugin. When this plugin is triggered, the subscribed plugin method of the current hook is executed. Note that webPack hooks execute each registered plugin in a particular order. What does WebPack do with our registered plug-ins? Let’s do a simple analysis
Hey, guys, I’m making a fool of myself
A simple plugin
// /plugins/LogStartBuildtips.js
const pluginName = 'LogStartBuildtips';
class LogStartBuildtips{
apply(compiler) {
compiler.hooks.run.tap(pluginName, compiltion => {
console.log('webpack build starting!!! '); }}})module.exports = LogStartBuildtips;
Copy the code
Register in the WebPack configuration file
const LogStartBuildtips = require('./plugins/LogStartBuildtips')
module.exports = {
/ /...
plugins:[
new LogStartBuildtips()
]
}
Copy the code
LogStartBuildtips is a plugin that tells you to pack (ahem, I’m not blind) in a WebPack package. Execute packing, you can see the printed information, which is skipped here,
We care about this process, what does Webpack do?
A brief analysis of the plugin mechanism
Take a look at webpack.js
// ./node_modules/webpack/lib/webpack.js
const webpack = (options, callback) = > {
let compiler;
compiler = new Compiler(options.context);
compiler.options = options;
if (options.plugins && Array.isArray(options.plugins)) {
for (const plugin of options.plugins) {
if (typeof plugin === "function") {
plugin.call(compiler, compiler);
} else { // new a constructor returns an object
plugin.apply(compiler); // Register the plug-in with apply and add the plug-in to the corresponding hook}}}console.log(compiler.hooks.run); // <== print here
return compiler;
};
Copy the code
Deleted a lot, mainly to see the processing of plug-ins. There are two types of plugins, objects or functions. For plugins that we often use, they are usually instances of plugins, so they are usually objects, else.
The plugin. Apply (compiler), what? Look at the source of the plugin, it is not difficult to find many plug-ins, there is a method apply, want it to do what?
The apply implementation is used to register the plugin to the corresponding hook. The apply parameter compiler is the complete configuration information of Webpack, which also contains our hand-written plugin-logStartBuildTips. The plugin we implemented registers the run hook. There are? Printing, seeing is believing
As you can see from the TAPS array in the Run hook, there are two plugins registered for the hook: CachePlugin, which is used inside WebPack, and the plugin we wrote.
Webpack has many hooks:
// ./node_modules/webpack/lib/Compiler.js
const {
Tapable,
SyncHook,
SyncBailHook,
AsyncParallelHook,
AsyncSeriesHook
} = require("tapable");
class Compiler extends Tapable {
constructor(context) {
super(a);this.hooks = {
shouldEmit: new SyncBailHook(["compilation"]),
done: new AsyncSeriesHook(["stats"]),
additionalPass: new AsyncSeriesHook([]),
beforeRun: new AsyncSeriesHook(["compiler"]),
run: new AsyncSeriesHook(["compiler"]), // <== our run hook
/ /...
afterPlugins: new SyncHook(["compiler"]),
afterResolvers: new SyncHook(["compiler"]),
entryOption: new SyncBailHook(["context"."entry"])};/ /...
}
/ /...
}
Copy the code
These hooks are initialized in the Compiler instance creation phase. Compiler inherits from Tapable, and each subsequent hook creates a new constructor derived from Tapable. What are these constructors for? Let’s talk about tapable
tapable
What is tapable? Webpack is a stream of events. This stream of events is made up of plugins, and tapable is responsible for ensuring that these plugins run in order. It adopts the publish and subscribe architecture model. Tapable has a number of hook methods for collecting registered plugins. Tapable is simply a library that WebPack uses to create hooks.
Webpack has many hooks, which are triggered in different life cycles. In a popular metaphor, the whole execution process of Webpack is like an assembly line of a factory. Tapable hook method is one worker on this assembly line, and each worker is assigned to different processing sites (Webpack hooks) when the project is created. Workers arrive at the site and start to prepare (New Tapable hook method), then workers get the tools to process the products (Plugin), and use these tools to process the products in a specific order (Plugin executes according to rules) when the products come, and then put them back to the assembly line after processing. Continue processing to the next worker (webpack hook) until all products come out of the assembly line (packaged).
Looking at these worker processing rules, Tapable provides nine hook methods
Writing in the middle
- Sync*
- SyncHook –> Synchronize serial hooks, regardless of the return value
- SyncBailHook –> Synchronizes the serial hook and skips subsequent functions if the return value is not null
- SyncLoopHook –> sync loop, continue if true, and break out if false
- SyncWaterfallHook –> SyncWaterfallHook. The value returned by the previous function is passed to the next listener
- Async*
- AsyncParallel* : asynchronous concurrency
- AsyncParallelBailHook – > asynchronous concurrent, as long as the monitoring function of the return value is not null, will ignore the back of the monitor function performs, jump directly to trigger the function such as callAsync bind callback function, and then perform the bind callback function
- AsyncParallelHook –> AsyncParallelHook –> AsyncParallelHook –> AsyncParallelHook –> AsyncParallelHook –> AsyncParallelHook –> AsyncParallelHook
- AsyncSeries* : asynchronous serial
- AsyncSeriesHook –> AsyncSeriesHook, does not care about arguments to callback()
- AsyncSeriesBailHook –> AsyncSeriesBailHook, callback() is not null, the subsequent function is ignored, directly execute the callAsync binding callback function
- AsyncSeriesWaterfallHook –> AsyncSeriesWaterfallHook. The second argument to the callback(err, data) of the previous function is passed to the next listener
- AsyncParallel* : asynchronous concurrency
www.programmersought.com/article/145… This site describes each hook method in more detail
Webpack plug-in registration: Sync plug-in generally use TAP; Asynchronous plug-ins come in three types: TAP, tapAsync, and tapSync
conclusion
So what does Webpack do with our registered plug-in?
Webpack first creates compiler, initializes all hooks within it, and then iterates through the plugins we configured in the WebPack configuration file, and executes apply to register the plugins we wrote with the tapable hook method to the corresponding WebPack hook. When the hook is fired at compile time, execute the plug-in’s method according to tapable’s hook method rules.
The plug-in mechanism for WebPack can be summarized in three steps:
- Create: WebPack creates various hooks on its internal objects;
- Registration: Plugins register their methods with the corresponding WebPack hooks via tapable hook methods and hand them to WebPack.
- Call: During webPack compilation, the appropriate hooks are triggered, and therefore the plugin’s methods are triggered.