webpack plugin

webpack plugin

webpack完成的复杂炫酷的功能依赖于插件机制,webpack的插件机制依赖于核心的库, tapable
tapable是一个类似于nodejs的eventEmitter的库, 主要是控制钩子函数的发布喝定于,当时,tapable提供您的hook机制比较全面,分为同步和异步两个大类, 根据事件执行的终止条件的不同

const {SyncHook}= require('tapable')
const hook = new SyncHook(['arg1', 'arg2'])
hook.tap('a', function(arg1, arg2) {
	console.log('ar')
})
hook.tap('b',function(arg1, arg2) {
	console.log('b')
})
hook.call(1, 2)

BasicHook: 执行每一个,不关心函数的返回值,有SyncHook, AsyncParallelHook, AsyncSeriesHook
BailHook: 顺序执行hook,遇到第一个结果result!=undefined则返回,不在执行
SyncBailHook, AsyncSeriesBailHook, AsyncParallelBailHook

tapable => sync => SyncHook
				=> SyncBailHook
				=> SyncWaterfallHook
				=> SyncLoopHook
		=> Async => AsyncParallel => AsyncParallelHook 
								  => AsyncParallelBailHook
				 => AsyncSeries   => AsyncSeriesHook
				 				  => AsyncParallelBailHook
				 				  => AsyncSeriesLoopHook
				 				  => AsyncSeriesWaterfallHook

每个Hook的用法
Basic: 不关心回调函数返回值,[SyncHook, AsyncParallelHook, AsyncSeriesHook]
Bail: 只要其中一个监听函数的返回值,不为undefined,则终止执行。 [SyncBailHook, AsyncParallelHook, AsyncSeriesBailHook]
waterfall: 前一个监听函数的返回值部位undefined,则作为下一个监听函数的第一个参数
[SyncWaterfallHook, AsyncSeriesWaterfallHook]
Loop: 如果有一个监听函数的返回值不为undefined, 则终止向下执行,从头开始执行,直到所有监听函数的返回值为undefined。[SyncLoopHook, AsyncSeriesLoopHook]~

```javascript
const {SyncHook} = require('tapable')
let hook = new SyncHook(['name'])
hook.tap('demo', function(params) {
	console.log('demo', params)
})
hook.tap('demo2', function(params) {
	console.log('demo2', params)
	return true
})
hook.tap('demo3', function(params) {
	console.log('demo3', params)
})
hook.call('hello SyncHook')
class SyncHook {
	constructor(args = []) {
		this._args = args
		this.tasks = []
	}
	tap(name, task) {
		this.tasks.push(task)
	}
	call(...args) {
		const params = args.slice(0, this._args.length)
		this.tasks.forEash(task => task(...params))
	}
}
const {SyncBailHook} = require('tapable')
let hook = new SyncBailHook(['name'])
hook.tap('demo', function(params) {
	console.log('demo', params)
})
hook.tap('demo2', function(params) {
	console.log('demo2', params)
	return true
})
hook.tap('demo3', function(params) {
	console.log('demo3', params)
})
hook.call('hello SyncBailHook')

SyncBailHook钩子遇到回调函数中返回结果不为undefined的时候,则跳过下面所有的逻辑

class SyncBailHook {
	constructor(args) {
		this._args = _args
		this.tasks = []
	}
	tap(name, task) {
		this.tasks.push(task)
	}
	call() {
		const args = Array.from(arguments).slice(0, this._args.length)
		for(let i = 0; i < this.tasks.length; i++) {
			if(result !== undefiend) {
				break
			}
		}
	}
}

SyncWaterfallHook

const {SyncWaterfallHook} = require('tapable')
const hook = new SyncWaterfallHook(['author', 'age'])
hook.tap('测试1', (params1, params2) => {
	console.log('测试1接受的参数', params1, params2)
})
hook.tap('测试2', (params1, params2) => {
	console.log('测试2接受的参数', params1, params2)
})
hook.tap('测试3',(params1, params2) => {
	console.log('测试3接受的参数', params1, params2)
})
hook.call('嘎嘎嘎', '99')

syncWaterfallHook是一个同步的,瀑布类型的hook,瀑布类型的钩子就是如果前一个事件的函数结果部位undefined,则result会作为后一个事件函数的第一个参数,也就是上一个函数的执行结果会成为下一个函数的参数

const {SyncLoopHook} = require('tapable')
const hook = new SyncLoopHook([])
let count = 5
hook.tap('测试1', () => {
	console.log("测试1里面的count", count)
	if([1, 2, 3].includes(count) {
		return undefiend
	} else {
		count--
		return "123"
	})
}) 
hook.tap('测试2', () => {
	console.log("测试2里面的count", count)
	if([1, 2].includes(count) {
		return undefiend
	} else {
		count--
		return "123"
	})
})
hook.tap("测试3", () => {
	console.log("测试3里面的count",count)
	if([1].includes(count) {
		return undefiend
	} else {
		count--
		return "123"
	})
})
hook.call()

syncLoophook=>asyncparallelHook是一个异步并行,基本类型的Hook, 与同步不同的地方在于

  • 会同时开启多个异步任务,而且需要通过tapSaync
const {AsyncParallelHook} = require("tapable")
const hook = new AsyncParallelHook(['author', 'age'])
console.log('time')
hook.tapAsync('测试1', (params1, params2) {
	setTimeout(() => {
		console.log('测试1接受的参数', params1, params2)
		callback()
	}, 2000)
})
hook.tapAsync('测试2', (params1, params2, callback) {
	console.log("测试2接受的参数", params1, params2)
	callback()
})
hook.tapAsync('测试3',(params1, params2,callback) => {
	console.log("测试3接受的参数", params1, params2)
	callback()
})
hook.callAsync('嘎嘎嘎', "99",(err, result) => {
	console.log("这个是成功的回调",err, result)
	console.timeEnd("time")
})

AsyncParallelBailHook是一个异步并行,保险类型的hook,只要其中一个有返回值, 就会执行callAsync中的回调

const {AsyncParallelHook} = require('tapable')
const hook = new AsyncParallelBailHook(['author', 'age'])
console.time('time')
hook.tapAsync('测试1', (params1, params2, callback) => {
	console.log('测试1接受的参数',params1, params2)
	setTimeout(() => {
		callback()
	},1000)
})
hook.tapAsync("测试2", (params1,params2,callback) => {
	console.log('测试2接受的参数',params1, params2) 
	setTimeout(() => {
		callback(null, '测试2有返回值')
	}, 2000)
})
hook.tapAsync('测试3', (params1, params2, callback) => {
	console.log('测试3接受的参数',params1, params2)
	setTimeout(()=> {
		callback(null, '测试3有返回值')
	}, 3000)
})
hook.callAsync("嘎嘎嘎", "99", (err, result) => {
  //等全部都完成了才会走到这里来
  console.log("这是成功后的回调", result);
  console.timeEnd("time");
});

AsyncSeriesHook是一个异步的,串行的类型的hook,只有前面的执行完成了,后面的才会执行

const {AsyncSeriesHook} = require('tapable')
const hook = new AsyncSeriesHook(['author', 'age'])
console.time('time')
hook.tapAsync('测试1' (params1, params2, callback) => {
	console.log('测试1接受的参数', params1, params2)
	setTimeout(() => {
		callback()
	}, 1000)
})
hook.tapAsync('测试2' (params1, params2, callback) => {
	console.log('测试2接受的参数', params1, params2)
	setTimeout(() => {
		callback()
	}, 2000)
})
hook.tapAsync('测试3' (params1, params2, callback) => {
	console.log('测试3接受的参数', params1, params2)
	setTimeout(() => {
		callback()
	}, 3000)
})
console.timeEnd()

AsyncSeriesBailHook 是一个异步串行,保险类型的hook,在串行的执行过程中,只要其中一个有返回值,后面就不会执行

const {AsyncSeriesBailHook} = require('tapable')
const hook = new AsyncParallelHook(['author', 'age'])
hook.tapAsync('测试1',(params1, params2, callback) => {
	console.log('测试1接受的参数',params1, params2)
	setTimeout(() => {
		callback()
	}, 1000)
})
hook.tapAsync('测试2',(params1, params2,callback) {
		console.log('测试2接受的参数',params1, params2)
	setTimeout(() => {
		callback()
	}, 2000)
}) 
hook.tapAsync('测试3',(params1, params2,callback) {
		console.log('测试3接受的参数',params1, params2)
	setTimeout(() => {
		callback()
	}, 3000)
}) 
hook.callAsync("嘎嘎嘎", "99", (err, result) => {
  //等全部都完成了才会走到这里来
  console.log("这是成功后的回调", result);
  console.timeEnd("time");
});

AsyncSeriesWaterfallHook是一个异步串行,瀑布类型的hook, 如果前一个事件函数的结果result!==undefined,则result会作为后一个事件函数的第一个参数,也就是上一个函数的执行结果会称为下一个函数的参数

const {AsyncSeriesWaterfallHook} = require('tapable')
const hook = new AsyncSeriesWaterfallHook(['author', 'age'])
console.time('time')
hook.tapAsync("测试1", (params1, params2, callback) => {
	console.log('测试1接受的参数', params1, params2)
	setTimeout(() => {
		callback(() => {
			callback(null, '2')
		}, 1000)
	})
})
hook.tapAsync("测试2", (params1, params2, callback) => {
	console.log('测试2接受的参数', params1, params2)
	setTimeout(() => {
		callback(null, '3')
	},2000)
})
hook.tapAsync("测试3", (param1, param2, callback) => {
  console.log("测试3接收的参数:", param1, param2);
  setTimeout(() => {
    callback(null, "4");
  }, 3000);
});


hook.callAsync("嘎嘎嘎", "99", (err, result) => {
  //等全部都完成了才会走到这里来
  console.log("这是成功后的回调", err, result);
  console.timeEnd("time");
});

Tapable拦截器
Tapable提供的所有的hook都支持注入Interception,它和Axios的拦截器的效果非常类似,可以通过拦截器对整个Tapable发布/订阅流程进行监听,从而触发对应的逻辑

const hook = new SyncHook(['arg1', 'arg2', 'arg3'])
hook.intercept({
	// 每次调用hook实例的tap,方法注册回调函数的时候,就会调用该方法
	// 并且接受tap作为参数,还可以对tap进行修改
	register: (tapInfo) => {
		console.log(`${tapInfo.name} is doing its job`)
		return tapInfo
	},
	// 通过hook实例对象上的call方法时候触发拦截器
	call: (arg1, arg2, arg3) => {
	console.log('starting to calculate routes')
	}
	// 在调用被注册的每一个事件函数之前执行
	tap: (tap) => {
		console.log(tap, 'tap'))
	}
	// loop类型钩子中,每个事件函数被调用前触发拦截器方法 
	loop:(...args) => {
		console.log(args, 'loop')
	}
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值