webpack自定义plugin

2023-07-20  本文已影响0人  姜治宇

示例

class MyPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
      // Explore each chunk (build output):
      compilation.chunks.forEach((chunk) => {
        // Explore each module within the chunk (built inputs):
        chunk.getModules().forEach((module) => {
          // Explore each source file path that was included into the module:
          module.buildInfo &&
            module.buildInfo.fileDependencies &&
            module.buildInfo.fileDependencies.forEach((filepath) => {
              // we've learned a lot about the source structure now...
            });
        });

        // Explore each asset filename generated by the chunk:
        chunk.files.forEach((filename) => {
          // Get the asset source for each file generated by the chunk:
          var source = compilation.assets[filename].source();
        });
      });

      callback();
    });
  }
}
module.exports = MyPlugin;

tapable

webpack使用了tapable库,相当于node的EventEmitter。
同步:

const { SyncHook } = require("tapable");

 const prepareHook = new SyncHook(["arg1","arg2"]); // 创建钩子,定义参数

 prepareHook.tap("brushTeeth",(arg)=>{ //绑定事件,相当于on
       console.log(`开始刷牙:${arg}`) 
 })

 prepareHook.tap("washFace",(arg)=>{  //绑定事件
    console.log(`正在洗脸:${arg}`) 
 })

 prepareHook.tap("breakfast",(arg)=>{ //绑定事件
    console.log(`吃早餐:${arg}`) 
 })

 prepareHook.call("准备阶段"); //触发事件,相当于emit

异步:

const { AsyncSeriesHook } = require("tapable");

 const workHook = new AsyncSeriesHook(["arg1"]);

 workHook.tapAsync("openComputer",(arg,next)=>{ //绑定事件
    setTimeout(()=>{
        console.log(`打开电脑:${arg}`);
        next();         
    },1000)
 })

 workHook.tapAsync("todoList",(arg,next)=>{ //绑定事件
    setTimeout(()=>{
        console.log(`列出日程安排:${arg}`);
        next();         
    },1000)
 })

 workHook.tapAsync("processEmail",(arg,next)=>{ //绑定事件
    setTimeout(()=>{
        console.log(`处理邮件:${arg}`);
        next();         
    },2000)
})

 workHook.callAsync("工作阶段",()=>{ //触发事件
    console.log(`异步任务完成`)  // 所有异步任务全部执行完毕,回调函数才会触发
 });

compiler

启动webpack会创建一个compiler对象。

const webpack = require('webpack');
const options = require('./webpack.dev.js');
const compiler = webpack(options);

console.log(compiler);//生成compiler对象

compiler.run();//开始构建

compiler具有以下属性:

1、compiler.options

可以访问本次启动webpack时的配置文件,比如loaders、entry、output等。

2、compiler.inputFileSystem和compiler.outputFileSystem

相当于node的fs。

3、compiler.hooks

通过注册不同种类的钩子,从而可以在compiler生命周期中植入不同的逻辑。

Compiler {
  hooks: {
    initialize: Hook {...},
    shouldEmit: Hook {...},
    done: Hook {...},
    afterDone:Hook {...},
    additionalPass: Hook {...},
    beforeRun: Hook {...},
    run: Hook {...},
    emit: Hook {...},
    compile: Hook {...},
    make: Hook {...},
    finishMake: Hook {...},
    .....
   }
}

compilation

compilation对象代表一次资源的构建。比如多入口打包,就会有多个compilation,触发多次。

 compiler.hooks.make.tapAsync('MyPlugin',(compilation,callback)=>{
   setTimeout(()=>{
     ...
     callback();
    },1000);
  
 });
 compiler.hooks.emit.tap('MyPlugin',(compilation,callback)=>{
  console.log(compilation);
   ...
  callback();
});

具有以下属性:

1、compilation.modules

可以访问所有模块,打包的每一个文件都是一个模块。

2、compilation.chunks

chunk就是多个modules组成的一个代码块。

3、compilation.assets

可以访问本次打包生成所有文件的结果。

4、compilation.hooks

compilation也有很多钩子函数。

工作流程

1.png
上一篇 下一篇

猜你喜欢

热点阅读