webpack的的实现是基于tapable,来看一下tabable的各个钩子函数的使用。
一、钩子类型
tapable提供了很多钩子(Hook classes)
代码语言:javascript复制const {
SyncHook, // 同步钩子 从上到下顺序执行
SyncBailHook, // 同步早退钩子 从上到下顺序执行,遇到返回值不是undefined的注册函数时停止执行
SyncWaterfallHook, // 同步瀑布钩子 从上到下执行,依次将返回值传递给下一个函数
SyncLoopHook, // 同步循环钩子 从上到下执行,某个函数可能会执行好几遍,当返回值是undefined会继续执行下个函数
AsyncParallelHook, // 异步并发钩子 异步并行
AsyncParallelBailHook, // 异步并发可早退钩子 异步并行熔断
AsyncSeriesHook, // 异步顺序钩子 异步串行
AsyncSeriesBailHook, // 异步顺序可早退钩子 异步串行熔断
AsyncSeriesWaterfallHook // 异步顺序瀑布钩子 异步串行值传递【瀑布】
} = require("tapable");
复制代码
二、钩子使用方法
3.1 同步钩子-SyncHook
代码语言:javascript复制import { SyncHook } from 'tapable';
const hook = new SyncHook(); // 创建钩子对象
hook.tap('logPlugin', () => console.log('注册了')); // tap方法注册钩子回调
hook.call(); // call方法调用钩子,打印出‘被勾了’三个字
复制代码
3.2 同步早退钩子-SyncBailHook
SyncBailHook就是根据每一步返回的值来决定要不要继续往下走,如果return了一个非undefined的值 那就不会往下走,注意 如果什么都不return 也相当于return了一个undefined。
代码语言:javascript复制import { SyncBailHook } from 'tapable';
const hook = new SyncBailHook();
hook.tap('SyncBailHook1', () => console.log(`钩子1`));
hook.tap('SyncBailHook2', () => {console.log(`钩子2`) ; return 1});
hook.tap('SyncBailHook3', () => console.log(`钩子3`));
hook.call(); // 会打印‘钩子1’‘钩子2’‘钩子3’
复制代码
3.3 同步瀑布钩子-SyncWaterfallHook
它的每一步都依赖上一步的执行结果,也就是上一步return的值就是下一步的参数。
代码语言:javascript复制import { SyncWaterfallHook } from 'tapable';
const hook = new SyncWaterfallHook(["newSpeed"]);
hook.tap('SyncWaterfallHook1', (speed) => { console.log(`增加到${speed}`); return speed 100; });
hook.tap('SyncWaterfallHook2', (speed) => { console.log(`增加到${speed}`); return speed 50; });
hook.tap('SyncWaterfallHook3', (speed) => { console.log(`增加到${speed}`); });
hook.call(50); // 打印‘增加到50’‘增加到150’‘增加到200’
复制代码
3.4 同步循环钩子 -SyncLoopHook
SyncLoopHook是同步的循环钩子,它的插件如果返回一个非undefined。就会一直执行这个插件的回调函数,直到它返回undefined。
代码语言:javascript复制import { SyncLoopHook } from 'tapable';
let index = 0;
const hook = new SyncLoopHook();
hook.tap('startPlugin1', () => {
console.log(`执行`);
if (index < 5) {
index ;
return 1;
}
});
hook.tap('startPlugin2', () => {
console.log(`执行2`);
});
hook.call(); // 打印‘执行’6次,打印‘执行2’一次。
复制代码
3.5异步并发钩子-AsyncParallelHook
当所有的异步任务执行结束后,再最终的回调中执行接下来的代码
代码语言:javascript复制import { AsyncParallelHook } from 'tapable';
const hook = new AsyncParallelHook();
hook.tapAsync('calculateRoutesPlugin1', (callback) => {
setTimeout(() => {
console.log('异步事件1');
callback();
}, 1000);
});
hook.tapAsync('calculateRoutesPlugin2', (callback) => {
setTimeout(() => {
console.log('异步事件2');
callback();
}, 2000);
});
hook.callAsync(() => { console.log('最终的回调'); }); // 会在1s的时候打印‘异步事件1’。2s的时候打印‘异步事件2’。紧接着打印‘最终的回调’
复制代码
3.6异步并发可早退钩子-AsyncParallelBailHook
代码语言:javascript复制import { AsyncParallelBailHook } from 'tapable';
const hook = new AsyncParallelBailHook();
hook.tapAsync('calculateRoutesPlugin1', (callback) => {
setTimeout(() => {
console.log('异步事件1');
callback(1);
}, 1000);
});
hook.tapAsync('calculateRoutesPlugin2', (callback) => {
setTimeout(() => {
console.log('异步事件2');
callback();
}, 2000);
});
hook.callAsync((result) => { console.log('最终的回调',result); }); // 会在1s的时候打印‘异步事件1’,紧接着打印‘最终的回调’,2s的时候打印‘异步事件2’。
复制代码
3.7 异步顺序钩子- AsyncSeriesHook
代码语言:javascript复制import { AsyncSeriesHook } from 'tapable';
const hook = new AsyncSeriesHook();
hook.tapPromise('calculateRoutesPlugin1', () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步事件1');
resolve();
}, 1000);
});
});
hook.tapPromise('calculateRoutesPlugin2', () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步事件2');
resolve();
}, 2000);
});
});
hook.then(() => { console.log('最终的回调'); });
// 1s过后,打印异步事件1,再过2s(而不是到了第2s,而是到了第3s),打印异步事件2,再立马打印最终的回调。
复制代码
3.8 异步顺序可早退钩子-AsyncSeriesBailHook
代码语言:javascript复制import { AsyncSeriesBailHook } from 'tapable';
const hook = new AsyncSeriesBailHook();
hook.tapPromise('calculateRoutesPlugin1', () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步事件1');
resolve(1);
}, 1000);
});
});
hook.tapPromise('calculateRoutesPlugin2', () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步事件2');
resolve();
}, 2000);
});
});
hook.then(() => { console.log('最终的回调'); });
// 1s过后,打印异步事件1,立马打印最终的回调,不会再执行异步事件2了。
复制代码
3.9 异步顺序瀑布钩子-AsyncSeriesWaterfallHook
代码语言:javascript复制import { AsyncSeriesWaterfallHook } from 'tapable';
const hook = new AsyncSeriesWaterfallHook(['args']);
hook.tapPromise('calculateRoutesPlugin1', (result) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步事件1', result);
resolve(result 1);
}, 1000);
});
});
hook.tapPromise('calculateRoutesPlugin2', (result) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('异步事件2', result);
resolve(result 2);
}, 2000);
});
});
hook.promise(12).then((result) => { console.log('最终的回调' result); });
// // 1s过后,打印异步事件1 12,再过2s打印异步事件2 13,然后立马打印最终的回调 15。
希望对你有所帮助
参考https://juejin.cn/post/6900095458409414669