webpack plugin解析及自定义plugin

弓泰
2023-12-01

自定义webpack 插件及相关API释义

plugin 介绍

  plugin插件可以在项目构建的过程中,额外处理一些工作;不同于loader的是,它可以针对整个webpack编译流程中的所有文件。

插件定义:

  • 导出为一个函数模块,其原型链上定义一个apply方法。接收一个compiler参数。
  • 通过compilerplugin方法监听各个阶段的事件,回调获取到这个时间段的compilation对象实例,从而处理当前特定的数据。
  • 如果是异步处理时,则需要在处理完之后调用提供的回调函数callback

Tapable

webpack的核心实现工具,用于提供插件接口。

暴露了三个方法taptapAsynctapPromise

  • tap 触发绑定同步的钩子事件。
  • tapSync/tapPromise 触发处理异步的钩子事件。

还可以通过tapable提供的钩子类给插件添加一个新的钩子。然后在你需要的时候调用。

tapable githun项目地址

webpack中的所用,compilercompilation继承并扩展tapable

可供使用的钩子

sync 同步;async异步;

钩子类型释义
SyncHook触发所有函数,同步调用
SyncBailHook只要存在函数执行结果返回,则不会调用其他函数
SyncWaterfallHook连续调用执行,之前的函数结果作为下一次函数的参数
SyncLoopHook
AsyncParallelHook触发所有函数,异步执行,并行调用
AsyncParallelBailHook
AsyncSeriesHook触发所有函数,异步执行,连续调用
AsyncSeriesBailHook
AsyncSeriesWaterfallHook

单独使用测试:

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

// 声明同步钩子函数
// 指定参数,数组类型
let hook = new SyncHook(["name"]);

// 新增一个钩子事件
hook.tap("AddUser",name=>console.log(`接收到的名称参数:${name}`))
// 触发调用
hook.call("admin");

compiler

  在webpack启动后,compiler对象包含webpack所有可操作的配置,包括:options、loader、plugin。插件在实例化调用时,接收compiler作为参数。

compiler提供关键时间段的事件监听。

  当webpack 初次启动时,compiler执行一次new MyPlugin() 调用apply方法,将其中通过compiler绑定的事件回调加入钩子函数的依赖数组中。如果重新编译则触发钩子事件,从而执行回调函数。

触发调用的钩子事件

通过compiler.hooks.somehook.tap()触发钩子事件。

钩子名称释义所属钩子类型
entryOptionentry配置项处理过后SyncBailHook
afterPlugins初始完插件后,SyncHook
afterResolversresolver安装完成之后SyncHook
environmentenvironment 准备好之后SyncHook
afterEnvironmentenvironment 安装完成之后SyncHook
beforeRuncompiler.run()执行之前AsyncSeriesHook
run开始读取records之前,AsyncSeriesHook
beforeCompile编译参数创建之后AsyncSeriesHook
compile新的编译创建之后SyncHook
emit生成资源到output目录之前AsyncSeriesHook
afterEmit生成资源到output目录之后AsyncSeriesHook
done编译(compliation)完成SyncHook
failed编译(compliation)失败之后SyncHook
invalid监听模式下,编译无效时SyncHook
watchClose监听模式停止后SyncHook

compilation

  compilation标识webpack运行时构建的当前对象,每一次文件的改动重新编译都会生成新的compilation。它包含了当前的模块资源、编译生成资源、变化的文件、依赖状态信息等。

compilation提供关键时间段的回调,可自定义处理数据。

compilation扩展自tapable,在创建新的构建时可已出发一些事件钩子函数。

钩子名称释义钩子类型
buildModule在模块构建前触发SyncHook
rebuildModule在模块重新构建前触发SyncHook
failedModule在模块构建失败时触发SyncHook
succeedModule在模块构建成功时触发SyncHook
finishModules在所有模块构建完成时触发SyncHook
finishRebuildingModule在某一个模块完成重新构建时触发SyncHook
seal编译(compilation)停止接收新模块时触发SyncHook
unseal编译(compilation)开始接收新模块时触发SyncHook
optimizeDependencies依赖优化开始时触发SyncBailHook
optimize优化阶段开始时触发SyncHook
optimizeChunks优化chunk时触发SyncBailHook
afterOptimizeChunks优化chunk完成时触发SyncHook
optimizeTree异步优化依赖树AsyncSeriesHook
reviveModulesrecords中恢复模块信息SyncHook
optimizeModuleOrder按优先级优化模块排序SyncHook
optimizeChunkOrder按优先级优化chunk排序SyncHook
beforeOptimizeChunkIds优化某个chunk id前触发SyncHook
optimizeChunkIds优化每个chunk idSyncHook
afterOptimizeChunkIds每个chunk id优化完成之后SyncHook
recordModules将模块信息存入recordsSyncHook
recordChunkschunk信息存入recordsSyncHook
beforeHash在编译被哈希之前SyncHook
afterHash在编译被哈希之后SyncHook
recordcompilation相关信息存入records之后SyncHook
beforeChunkAssets在创建chunk资源之前SyncHook
additionalChunkAssetschunk附加附属资源SyncHook
additionalAssets为编译compilation附加附属资源AsyncSeriesHook
optimizeChunkAssets优化所有chunk资源AsyncSeriesHook
afterOptimizeChunkAssetschunk优化完成SyncHook
optimizeAssets优化存储在compilation.assets中的所有资源AsyncSeriesHook
afterOptimizeAssets资源优化结束SyncHook
moduleAsset一个模块的一个资源被加到编译中SyncHook
chunkAsset一个chunk的一个资源被加到编译中SyncHook

实现一个plugin

plugin在webpack启动后,执行一次。传入当前的配置对象compiler

/**
 * 自定义插件 
 */

function PJWebpacakPlugin(options){
    // 接收实例化时的参数 options
}
// 原型链上必须有apply函数
PJWebpacakPlugin.prototype.apply = function(compiler){
    // webpack编译运行时调用一次 apply 方法,
    
    compiler.plugin("entryOption",function(context,entry){
        // entry 配置项完成后,可访问entry配置

        console.log(entry);
    });

    compiler.plugin("afterPlugins",function(compiler){
        // 在初始化插件plugin之后,
        console.info(compiler.records);
    })  

    compiler.plugin("done",function(stats){
        // webpack 编译完成之后出发
        console.info(compiler);
    });
}

// 模块导出
module.exports = PJWebpacakPlugin;

导入使用,

// 自定义插件应用
const CustomPlugin = require("./src/plugins/plugin/index");

module.exports = {
    plugins:[
        // ...
        new CustomPlugin()
    ]
}
 类似资料: