webpack原理篇(五十四):Tapable是如何和webpack进行关联起来的?

Posted 凯小默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack原理篇(五十四):Tapable是如何和webpack进行关联起来的?相关的知识,希望对你有一定的参考价值。

说明

玩转 webpack 学习笔记

Tapable 是如何和 webpack 联系起来的?

可以看下面这段代码

if (Array.isArray(options)) 
	compiler = new MultiCompiler(options.map(options => webpack(options)));
 else if (typeof options === "object") 
	options = new WebpackOptionsDefaulter().process(options);
	compiler = new Compiler(options.context);
	compiler.options = options;
	new NodeEnvironmentPlugin().apply(compiler);
	if (options.plugins && Array.isArray(options.plugins)) 
		for (const plugin of options.plugins) 
			if (typeof plugin === "function") 
				plugin.call(compiler, compiler);
			 else 
				plugin.apply(compiler);
			
		
	
	compiler.hooks.environment.call();
	compiler.hooks.afterEnvironment.call();
	compiler.options = new WebpackOptionsApply().process(options, compiler);

  • 插件需要一个 apply 方法,接收一个 compiler 参数
  • 插件上做一些 hooks 的监听,触发了插件做一些操作

模拟 Compiler.js

const 
    SyncHook,
    AsyncSeriesHook
 = require('tapable');

module.exports = class Compiler 
    constructor() 
        this.hooks = 
            accelerate: new SyncHook(["newspeed"]),
            brake: new SyncHook(),
            calculateRoutes: new AsyncSeriesHook(["source", "target", "routesList"]),
        ;
    
    run() 
        this.accelerate(10);
        this.break();
        this.calculateRoutes("Async", "hook", "kaimo demo");
    
    accelerate(speed) 
        this.hooks.accelerate.call(speed);
    
    break() 
        this.hooks.brake.call();
    
    calculateRoutes() 
        this.hooks.calculateRoutes.promise(...arguments).then(
            () =>  ,
            (err) => 
                console.error(err);
            
        );
    
;

插件 my-plugin.js

const Compiler = require('./Compiler')
class MyPlugin 
    constructor() 
    
    apply(compiler) 
        compiler.hooks.brake.tap("WarningLampPlugin", () => console.log('WarningLampPlugin'));
        compiler.hooks.accelerate.tap("LoggerPlugin", newSpeed => console.log(`Accelerating to $newSpeed`));
        compiler.hooks.calculateRoutes.tapPromise("calculateRoutes tapAsync", (source, target, routesList) => 
            return new Promise((resolve, reject) => 
                setTimeout(() => 
                    console.log(`tapPromise to $source $target $routesList`)
                    resolve();
                , 1000)
            );
        );
    

模拟插件执行

const myPlugin = new MyPlugin();
const options = 
    plugins: [myPlugin]

const compiler = new Compiler();
for (const plugin of options.plugins) 
    if (typeof plugin === "function") 
        plugin.call(compiler, compiler);
     else 
        plugin.apply(compiler);
    

compiler.run();

实战运行测试

我们根据上面的代码新建两个文件,添加上面代码


执行 node my-plugin.js,结果如下

以上是关于webpack原理篇(五十四):Tapable是如何和webpack进行关联起来的?的主要内容,如果未能解决你的问题,请参考以下文章

webpack4.0各个击破—— tapable篇

webpack原理篇(五十七):webpack流程:文件生成

webpack原理篇(五十五):webpack流程:准备阶段

webpack原理:Tapable源码分析及钩子函数作用分析

webpack原理篇(五十一):webpack启动过程分析

webpack原理篇(五十六):webpack流程:模块构建和chunk生成阶段