• tapable事件流插件


    tapable

    Webpack本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是Tapable,webpack中最核心的负责编译的Compiler和负责创建bundle的Compilation都是Tapable的实例

    image

    const {
        SyncHook,
        SyncBailHook,
        SyncWaterfallHook,
        SyncLoopHook,
        AsyncParallelHook,
        AsyncParallelBailHook,
        AsyncSeriesHook,
        AsyncSeriesBailHook,
        AsyncSeriesWaterfallHook
     } = require("tapable");
    

    SyncHook

    串行同步执行,不关心返回值

    //钩子可以在stage和其他钩子之间穿插钩子
    const hook = new SyncHook()
    const calls = [];
    
    hook.tap("A",() => calls.push("A"))
    hook.tap({
    	name:"B",
    	before:"A"
    },() => calls.push("B"))
    
    calls.length = 0
    hook.call()
    
    
    hook.tap({
    	name:"C",
    	before:["A","B"]
    },() => calls.push("C"))
    
    calls.length = 0
    hook.call()
    
    
    hook.tap({
    	name:"D",
    	before:"B"
    },() => calls.push("D"))
    
    calls.length = 0;
    hook.call()
    
    hook.tap({
    	name:"E",
    	stage:3
    },() => calls.push("E"))
    
    hook.tap({
    	name:"F",
    	stage:1
    },() => calls.push("F"))
    
    calls.length = 0;
    hook.call()
    
    
    console.log(calls)
    
    
    //创建同步钩子
    const h0 = new SyncHook(["arg1"]);
    
    h0.tap("A",(name) => {
    	console.log(name)
    })
    
    h0.tap("B",(name) => {
    	console.log(name)
    })
    
    h0.call('plus',24)
    
    
    

    SyncBailHook

    串行同步执行,有一个返回值不为null则跳过剩下的逻辑

    const h1 = new SyncBailHook(["a"]);
    
    h1.tap("A",a => {console.log(a) ;return a})
    h1.tap("B",a => console.log(a))
    h1.call(1)
    

    SyncWaterfallHook

    const h1 = new SyncWaterfallHook(['name'])
    
    h1.tap("A",(name) => {
    	console.log(name,1)
    })
    h1.tap("B",(data) => {
    	console.log(data,2)
    	return 2
    })
    h1.tap("C",(data) => {
    	console.log(data,3)
    	return 3
    })
    
    h1.call('plus',24)
    

    SyncLoopHook

    监听函数返回true表示继续循环,返回undefine表示结束循环

    const h1 = new SyncLoopHook(['name'])
    
    let count = 0
    h1.tap('A',name => (
    	count < 3 ?
    	(count++,console.log(name),true)
    	:undefined
    ))
    
    h1.call(
    	'plus'
    )
    

    AsyncParallelHook

    异步并行钩子

    const h1 = new AsyncParallelHook(['name'])
    
    h1.tap('A',() => console.log(1))
    h1.tap('B',() => console.log(2))
    h1.tap('C',() => console.log(3))
    
    h1.callAsync('test',err => {
    	console.log(err)
    })
    
    const h1 = new AsyncParallelHook(['name'])
    
    console.time('count')
    h1.tapAsync('A',(name,callback) => {
    	setTimeout(() => (console.log(1),callback()),2000)
    })
    h1.tapAsync('B',(name,callback) => {
    	setTimeout(() => (console.log(2),callback()),1000)
    })
    h1.tapAsync('C',(name,callback) => {
    	setTimeout(() => (console.log(3),callback()),3000)
    })
    
    h1.callAsync('test',err => {
    	console.log(err)
    	console.timeEnd('count')
    })
    
    const h1 = new AsyncParallelHook(['name'])
    
    console.time('count')
    h1.tapPromise('A',(name,callback) => (
    	 new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(1),resolve()),2000)
    	})
    ))
    
    h1.tapPromise('B',(name,callback) => (
    	new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(2),resolve()),1000)
    	})
    ))
    
    h1.tapPromise('C',(name,callback) => (
    	new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(3),resolve()),3000)
    	})
    ))
    
    h1.callAsync('test',err => {
    	console.log(err)
    	console.timeEnd('count')
    })
    

    AsyncParallelBailHook

    带保险带异步执行钩子

    let h1=new AsyncParallelBailHook(['name']);
    console.time('count');
    h1.tap('A',function(name){
        console.log(1);
        return "Wrong";
    });
    h1.tap('B',function(name){
        console.log(2);
    });
    h1.tap('C',function(name){
        console.log(3);
    });
    h1.callAsync('test',err=>{
        console.log(err);
        console.timeEnd('count');
    });
    
    let h1=new AsyncParallelBailHook(['name']);
    console.time('count');
    h1.tapAsync('A',function(name,callback){
        console.log(1);
        return "Wrong";
    });
    h1.tapAsync('B',function(name,callback){
        console.log(2);
    });
    h1.tapAsync('C',function(name.callback){
        console.log(3);
    });
    h1.callAsync('test',err=>{
        console.log(err);
        console.timeEnd('count');
    });
    
    const h1 = new AsyncParallelBailHook(['name'])
    
    console.time('count')
    h1.tapPromise('A',(name,callback) => (
    	 new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(1),resolve()),2000)
    	})
    ))
    
    h1.tapPromise('B',(name,callback) => (
    	new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(2),resolve()),1000)
    	})
    ))
    
    h1.tapPromise('C',(name,callback) => (
    	new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(3),resolve()),3000)
    	})
    ))
    
    h1.callAsync('test',err => {
    	console.log(err)
    	console.timeEnd('count')
    })
    

    AsyncSeriesHook

    异步串行钩子

    let h1 = new AsyncSeriesHook(['name']);
    console.time('cost');
    h1.tap('A',function(name){
        console.log(1);
    });
    h1.tap('B',function(name){
        console.log(2);
    });
    h1.tap('C',function(name){
        console.log(3);
    });
    h1.callAsync('test',err=>{
        console.log(err);
        console.timeEnd('cost');
    });
    
    let h1 = new AsyncSeriesHook(['name']);
    console.time('cost');
    h1.tapAsync('A',function(name,callback){
        setTimeout(function(){
    	   console.log(1);
    	   callback()
       },1000)
    });
    h1.tapAsync('B',function(name,callback){
        setTimeout(function(){
    	   console.log(2);
    	   callback()
       },2000)
    });
    h1.tapAsync('C',function(name,callback){
        setTimeout(function(){
    	   console.log(3);
    	   callback()
       },3000)
    });
    h1.callAsync('test',err=>{
        console.log(err);
        console.timeEnd('cost');
    });
    
    let h1=new AsyncSeriesHook(['name']);
    console.time('cost');
    h1.tapPromise('A',function(name){
       return new Promise(function(resolve){
           setTimeout(function(){
               console.log(1);
               resolve();
           },1000)
       });
    });
    h1.tapPromise('B',function(name,callback){
        return new Promise(function(resolve){
            setTimeout(function(){
                console.log(2);
                resolve();
            },2000)
        });
    });
    h1.tapPromise('C',function(name,callback){
        return new Promise(function(resolve){
            setTimeout(function(){
                console.log(3);
                resolve();
            },3000)
        });
    });
    h1.promise('test').then(data=>{
        console.log(data);
        console.timeEnd('cost');
    });
    

    AsyncSeriesBailHook

    let h1 = new AsyncSeriesBailHook(['name']);
    console.time('cost');
    h1.tap('A',function(name){
        console.log(1);
        return "Wrong";
    });
    h1.tap('B',function(name){
        console.log(2);
    });
    h1.tap('C',function(name){
        console.log(3);
    });
    h1.callAsync('test',err=>{
        console.log(err);
        console.timeEnd('cost');
    });
    
    let h1 = new AsyncSeriesBailHook(['name']);
    console.time('cost');
    h1.tapAsync('A',function(name,callback){
        setTimeout(function(){
    	   console.log(1);
    	   callback('wrong')
       },1000)
    });
    h1.tapAsync('B',function(name,callback){
        setTimeout(function(){
    	   console.log(2);
    	   callback()
       },2000)
    });
    h1.tapAsync('C',function(name,callback){
        setTimeout(function(){
    	   console.log(3);
    	   callback()
       },3000)
    });
    h1.callAsync('test',err=>{
        console.log(err);
        console.timeEnd('cost');
    });
    
    const h1 = new AsyncSeriesBailHook(['name'])
    
    console.time('count')
    h1.tapPromise('A',(name,callback) => (
    	 new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(1),reject()),2000)
    	})
    ))
    
    h1.tapPromise('B',(name,callback) => (
    	new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(2),resolve()),1000)
    	})
    ))
    
    h1.tapPromise('C',(name,callback) => (
    	new Promise((resolve,reject) => {
    		setTimeout(() => (console.log(3),resolve()),3000)
    	})
    ))
    
    h1.promise('test',err => {
    	console.log(err)
    	console.timeEnd('count')
    },err => {
       console.log(err);
        console.timeEnd('cost');
    })
    

    AsyncSeriesWaterfallHook

    let {AsyncSeriesWaterfallHook} = require('tapable');
    let h1 = new AsyncSeriesWaterfallHook(['name']);
    console.time('cost');
    h1.tap('1',function(name,callback){
        console.log(1);
    });
    h1.tap('2',function(data){
        console.log(2,data);
    });
    h1.tap('3',function(data){
        console.log(3,data);
    });
    queue.callAsync('test',err=>{
        console.log(err);
        console.timeEnd('cost');
    });
    
    let h1 = new AsyncSeriesWaterfallHook(['name']);
    console.time('cost');
    h1.tapAsync('1',function(name,callback){
       setTimeout(function(){
           console.log(1);
           callback(null,1);
       },1000)
    });
    h1.tapAsync('2',function(data,callback){
        setTimeout(function(){
            console.log(2);
            callback(null,2);
        },2000)
    });
    h1.tapAsync('3',function(data,callback){
        setTimeout(function(){
            console.log(3);
            callback(null,3);
        },3000)
    });
    h1.callAsync('test',(err,data)=>{
        console.log(err,data);
        console.timeEnd('cost');
    });
    
    let h1 = new AsyncSeriesWaterfallHook(['name']);
    console.time('cost');
    h1.tapPromise('1', function (name) {
        return new Promise(function (resolve) {
            setTimeout(function () {
                console.log(name, 1);
                resolve(1);
            }, 1000);
        });
    });
    h1.tapPromise('2', function (data) {
        return new Promise(function (resolve) {
            setTimeout(function () {
                console.log(data, 2);
                resolve(2);
            }, 2000);
        });
    });
    h1.tapPromise('3', function (data) {
        return new Promise(function (resolve) {
            setTimeout(function () {
                console.log(data, 3);
                resolve(3);
            }, 3000);
        });
    });
    h1.promise('test').then(err => {
        console.timeEnd('cost');
    });
    

    tapable

    class MyPlugin {
    	constructor(){
    		this.hooks = {
    			add:new SyncHook(['name'])
    		}
    	}
    }
    const myPlugin = new MyPlugin()
    
    myPlugin.hooks.add.tap('add',(name) => {
    	console.log(name)
    })
    
    myPlugin.hooks.add.tap('minus',(name) => {
    	console.log(name)
    })
    myPlugin.hooks.add.call('plus')
    
  • 相关阅读:
    我最讨厌画图,这辈子我都不想再画图
    bzoj1218[HNOI2003]激光炸弹
    bzoj1196[HNOI2006]公路修建问题
    bzoj1588[HNOI2002]营业额统计
    bzoj2039[2009国家集训队]employ人员雇佣
    bzoj3874[Ahoi2014]宅男计划
    bzoj2282[Sdoi2011]消防
    bzoj1798[Ahoi2009]Seq 维护序列seq
    bzoj4003[JLOI2015]城池攻占
    bzoj2809[Apio2012]dispatching
  • 原文地址:https://www.cnblogs.com/pluslius/p/10219685.html
Copyright © 2020-2023  润新知