Compilation Object
Compilation 对象有很多可用的方法和钩子。在此页面,我们将会列举出这些可用的方法和属性。
compilation 对象方法
-
getStats
function
返回当前编译的状态对象。
-
addModule
function (module, cacheGroup)
向当前编译添加一个模块。
参数:
module- 要添加的模块cacheGroup- 模块的cacheGroup
-
getModule
function (module)
通过编译的标识符获取其模块。
参数:
module- 要获取的模块。标识符是通过编译使用module.identifier()方法从模块中提取的。
-
findModule
function (module)
尝试通过其标识符搜索模块。
参数:
module- 要搜索的模块。标识符是通过编译使用module.identifier()方法从模块中提取的。
-
waitForBuildingFinished
function (module, callback)
在构建给定模块时运行给定的
callback函数。参数:
module- 有问题的模块。callback- 要调用的函数。
-
buildModule
function (module, optional, origin, dependencies)
构建给定的模块。
参数:
module- 要构建的模块。optional- 可选标志。origin- 请求此模块构建的原始模块。dependencies- 要构建模块的可选依赖。
-
processModuleDependencies
function (module, callback)
处理给定模块依赖。
参数:
module- 要被处理依赖的模块。callback- 模块依赖处理完成时回调的函数。
-
addModuleDependencies
function (module, dependencies, bail, cacheGroup, recursive, callback)
向模块添加依赖。处理依赖之后被
processModuleDependencies自动调用。参数:
module- 要添加依赖的模块。dependencies- 要遍历添加到模块的一组已排序依赖。bail- 发生错误时是否中断进程并抛出 error。cacheGroup- 模块的cacheGroup。recursive- 是否要递归遍历。callback- 添加模块依赖之后回调的函数。
-
addEntry
function (context, entry, name, callback)
为编译添加入口。
参数:
context- 入口的上下文路径。entry- 入口依赖。name- 入口名称。callback- 添加入口完成之后回调的函数。
-
prefetch
function (context, dependency, callback)
根据给定的依赖创建一个模块。
参数:
context- 上下文路径。dependency- 被用来创建模块的依赖。callback- 向上一级发送模块的模块回调。
-
rebuildModule
function (module, thisCallback)
触发模块的重建。
参数:
module- 要被重建的模块。thisCallback- 模块重建完成之后调用的函数。
-
finish
function (callback)
完成编译并调用给定的回调。
参数:
callback- 编译完成之后调用的函数。
-
seal
function (callback)
封闭编译。
参数:
callback- 封闭编译时回调的函数。
-
unseal
function
解除封闭编译。
参数:
callback- 解除封闭编译时回调的函数。
-
reportDependencyErrorsAndWarnings
function (module, blocks)
将给定模块的错误和警告添加到编译的错误和警告中。
参数:
module- 要被报告错误与警告的模块。blocks- 一组要报告的依赖块。
-
addChunkInGroup
function (groupOptions, module, loc, request)
将模块添加到现有 chunk 组或创建一个新的组。返回一个
chunkGroup。参数:
groupOptions- chunk 组的选项。module- 引用 chunk 组的模块。loc- 引用 chunk 组的位置(模块内部)。request- 引用 chunk 组的请求。
-
addChunk
function (name)
向
compilation.chunks创建或添加一个新的 chunk。返回这个chunk.参数:
name- chunk 的名称。
-
assignDepth
function (module)
为给定的模块及其依赖块递归分配
depth。参数:
module- 要被分配 depth 的模块。
-
getDependencyReference
function (module, dependency)
返回给定模块对依赖的引用。
参数:
module- 有问题的模块。dependency- 要引用的依赖。
-
processDependenciesBlocksForChunkGroups
function (inputChunkGroups)
通过
Module图创建Chunk图。该过程分为两个阶段完成。阶段一:遍历模块图,在chunkDependencies中创建一个基础 chunk 图。阶段二:通过基本 chunk 图遍历所有可能的方法并且跟踪可用模块。遍历过程中processDependenciesBlocksForChunkGroups将 chunk 相互连接,并将Blocks与Chunks连接. 当一个 chunk 的所有模块都已经可用且未连接不需要的 chunk 时,它将停止遍历。参数:
inputChunkGroups- 被处理的 chunk 组。
-
removeReasonsOfDependencyBlock
function (module, block)
移除模块与依赖块之间的关系。
参数:
module- 要移除的模块关系。block- 依赖块。
-
patchChunksAfterReasonRemoval
function (module, chunk)
删除依赖性原因后,修补模块和 chunk 的关系。被
removeReasonsOfDependencyBlock自动调用。参数:
module- 要修复关系的模块。chunk- 要修复关系的 chunk。
-
removeChunkFromDependencies
function (block, chunk)
在除去依赖性原因后,从依赖块模块和 chunk 中移除给定的 chunk。会被
removeReasonsOfDependencyBlock自动调用。参数:
block-Chunk的块连接。chunk- 从依赖中删除的块。
-
sortItemsWithModuleIds
function
-
sortItemsWithChunkIds
function
-
summarizeDependencies
function
-
createHash
function
-
createModuleAssets
function
-
createChunkAssets
function
-
getPath
function (filename, data)
返回插值路径。
参数:
filename- 用于通过哈希获取资源路径。data- 数据对象。
-
getPathWithInfo
function (filename, data)
返回插值路径和资源信息。
参数:
filename- 用于通过哈希获取资源路径。data- 数据对象。
-
createChildCompiler
function (name, outputOptions, plugins)
允许在 webpack 中运行另一个 webpack 实例。但是,子编译器会应用不同的设置和配置。他会从父编译器(或者顶级编译器)中复制所有的钩子(hook)和插件(plugin),并且创建一个子
Compiler实例。 返回值为创建好的Compiler实例。参数:
name- 子Compiler的名称。outputOptions- 输出选项。plugins- 将被提供的 webpack 插件。
-
checkConstraints
function
-
emitAsset
function (file, source, assetInfo = {})
webpack 4.40.0 后可用。
参数:
file- 资源名称。source- 资源来源。assetInfo- 附加资源信息。
-
updateAsset
function (file, newSourceOrFunction, assetInfoUpdateOrFunction)
webpack 4.40.0 后可用。
参数:
file- 资源名称。newSourceOrFunction- 新资源来源或将旧资源转换为新资源的函数。assetInfoUpdateOrFunction- 新资源信息或将旧资源转换为新资源的函数。
-
deleteAsset
function (file)
参数:
file—— 资源的文件名
-
getAssets
function
webpack 4.40.0 后可用。
返回当前编译下所有资源的数组。
-
getAsset
function (name)
webpack 4.40.0 后可用。
参数:
name- 要返回的资源名称。
compiler 钩子
Compiler 模块是 webpack 的主要引擎,它通过 CLI 传递的所有选项, 或者 Node API,创建出一个 compilation 实例。 它扩展(extend)自 Tapable 类,用来注册和调用插件。 大多数面向用户的插件会首先在 Compiler 上注册。
此模块会暴露在 webpack.Compiler, 可以直接通过这种方式使用。 关于更多信息,请查看 这个示例。
在为 webpack 开发插件时,你可能需要知道每个钩子函数是在哪里调用的。想要了解这些内容,请在 webpack 源码中搜索 hooks.<hook name>.call。
监听(watching)
Compiler 支持可以监控文件系统的 监听(watching) 机制,并且在文件修改时重新编译。 当处于监听模式(watch mode)时, compiler 会触发诸如 watchRun, watchClose 和 invalid 等额外的事件。 通常在 开发环境 中使用, 也常常会在 webpack-dev-server 这些工具的底层调用, 由此开发人员无须每次都使用手动方式重新编译。 还可以通过 CLI 进入监听模式。
钩子
以下生命周期钩子函数,是由 compiler 暴露, 可以通过如下方式访问:
compiler.hooks.someHook.tap('MyPlugin', (params) => {
/* ... */
});
取决于不同的钩子类型,也可以在某些钩子上访问 tapAsync 和 tapPromise。
关于钩子类型的描述,请查看 Tapable 文档.
-
entryOptionSyncBailHook
在 webpack 选项中的
entry被处理过之后调用。jscompiler.hooks.entryOption.tap('MyPlugin', (context, entry) => { /* ... */ });123参数:
context,entry -
afterPluginsSyncHook
在初始化内部插件集合完成设置之后调用。
- 回调参数:
compiler
- 回调参数:
-
afterResolversSyncHook
resolver 设置完成之后触发。
- 回调参数:
compiler
- 回调参数:
-
environmentSyncHook
在初始化配置文件中的插件之后立即调用,在 compiler environment 准备时调用。
-
afterEnvironmentSyncHook
在
environment钩子之后立即调用,在 compiler environment 完成设置时调用。 -
beforeRunAsyncSeriesHook
在开始执行一次构建之前调用,compiler.run 方法开始执行后立刻进行调用。
- 回调参数:
compiler
- 回调参数:
-
additionalPassAsyncSeriesHook
This hook allows you to do a one more additional pass of the build.
-
runAsyncSeriesHook
在开始读取
records之前调用。- 回调参数:
compiler
- 回调参数:
-
watchRunAsyncSeriesHook
在监听模式下,一个新的 compilation 触发之后,但在 compilation 实际开始之前执行。
- 回调参数:
compiler
- 回调参数:
-
normalModuleFactorySyncHook
NormalModuleFactory创建之后调用。- 回调参数:
normalModuleFactory
- 回调参数:
-
contextModuleFactorySyncHook
ContextModuleFactory创建之后调用。- 回调参数:
contextModuleFactory
- 回调参数:
-
initializeSyncHook
在初始化 compiler 对象时调用。
-
beforeCompileAsyncSeriesHook
在创建 compilation parameter 之后执行。
- 回调参数:
compilationParams
初始化
compilationParams变量的示例如下:jscompilationParams = { normalModuleFactory, contextModuleFactory, };1234此钩子可用于添加/修改 compilation parameter:
jscompiler.hooks.beforeCompile.tapAsync('MyPlugin', (params, callback) => { params['MyPlugin - data'] = 'important stuff my plugin will use later'; callback(); });1234 - 回调参数:
-
compileSyncHook
beforeCompile之后立即调用,但在一个新的 compilation 创建之前。- 回调参数:
compilationParams
- 回调参数:
-
thisCompilationSyncHook
初始化 compilation 时调用,在触发
compilation事件之前调用。- 回调参数:
compilation,compilationParams
- 回调参数:
-
compilationSyncHook
compilation 创建之后执行。
- 回调参数:
compilation,compilationParams
- 回调参数:
-
makeAsyncParallelHook
compilation 结束之前执行。
- 回调参数:
compilation
- 回调参数:
-
afterCompileAsyncSeriesHook
compilation 结束和封印之后执行。
- 回调参数:
compilation
- 回调参数:
-
shouldEmitSyncBailHook
在输出 asset 之前调用。返回一个布尔值,告知是否输出。
- 回调参数:
compilation
jscompiler.hooks.shouldEmit.tap('MyPlugin', (compilation) => { // 返回 true 以输出 output 结果,否则返回 false return true; });1234 - 回调参数:
-
emitAsyncSeriesHook
输出 asset 到 output 目录之前执行。
- 回调参数:
compilation
- 回调参数:
-
afterEmitAsyncSeriesHook
输出 asset 到 output 目录之后执行。
- 回调参数:
compilation
- 回调参数:
-
assetEmittedAsyncSeriesHook
在 asset 被输出时执行。此钩子可以访问被输出的 asset 的相关信息,例如它的输出路径和字节内容。
- 回调参数:
file,info
例如,可以通过
info.content访问 asset 的内容 buffer:jscompiler.hooks.assetEmitted.tap( 'MyPlugin', (file, { content, source, outputPath, compilation, targetPath }) => { console.log(content); // <Buffer 66 6f 6f 62 61 72> } );123456 - 回调参数:
-
doneAsyncSeriesHook
在 compilation 完成时执行。
- 回调参数:
stats
- 回调参数:
-
failedSyncHook
在 compilation 失败时调用。
- 回调参数:
error
- 回调参数:
-
invalidSyncHook
在一个观察中的 compilation 无效时执行。
- 回调参数:
fileName,changeTime
- 回调参数:
-
watchCloseSyncHook
在一个观察中的 compilation 停止时执行。
-
infrastructureLogSyncBailHook
在配置中启用
infrastructureLogging选项 后,允许使用 infrastructure log(基础日志)。- 回调参数:
name,type,args
- 回调参数:
-
logSyncBailHook
启用后允许记录到 stats 对象,请参阅
stats.logging,stats.loggingDebug和stats.loggingTrace选项。- 回调参数:
origin,logEntry
- 回调参数:
compilation 钩子
Compilation 模块会被 Compiler 用来创建新的 compilation 对象(或新的 build 对象)。 compilation 实例能够访问所有的模块和它们的依赖(大部分是循环依赖)。 它会对应用程序的依赖图中所有模块, 进行字面上的编译(literal compilation)。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。
Compilation 类扩展(extend)自 Tapable,并提供了以下生命周期钩子。 可以按照 compiler 钩子的相同方式来调用 tap:
compilation.hooks.someHook.tap(/* ... */);
和 compiler 用法相同,取决于不同的钩子类型, 所以也可以在某些钩子上访问 tapAsync 和 tapPromise。
-
buildModuleSyncHook
在模块构建开始之前触发,可以用来修改模块。
- 回调参数:
module
jscompilation.hooks.buildModule.tap('SourceMapDevToolModuleOptionsPlugin', module => { module.useSourceMap = true; } );12345 - 回调参数:
-
rebuildModuleSyncHook
在重新构建一个模块之前触发。
- 回调参数:
module
- 回调参数:
-
failedModuleSyncHook
模块构建失败时执行。
- 回调参数:
moduleerror
- 回调参数:
-
succeedModuleSyncHook
模块构建成功时执行。
- 回调参数:
module
- 回调参数:
-
finishModulesAsyncSeriesHook
所有模块都完成构建并且没有错误时执行。
- 回调参数:
modules
- 回调参数:
-
finishRebuildingModuleSyncHook
一个模块完成重新构建时执行,在都成功或有错误的情况下。
- 回调参数:
module
- 回调参数:
-
sealSyncHook
compilation 对象停止接收新的模块时触发。
-
unsealSyncHook
compilation 对象开始接收新模块时触发。
-
optimizeDependenciesSyncBailHook
依赖优化开始时触发。
- 回调参数:
modules
- 回调参数:
-
afterOptimizeDependenciesSyncHook
依赖优化之后触发。
- 回调参数:
modules
- 回调参数:
-
optimizeSyncHook
优化阶段开始时触发。
-
optimizeModulesSyncBailHook
在模块优化阶段开始时调用。插件可以 tap 此钩子对模块进行优化。
- 回调参数:
modules
- 回调参数:
-
afterOptimizeModulesSyncHook
在模块优化完成之后调用。
- 回调参数:
modules
- 回调参数:
-
optimizeChunksSyncBailHook
在 chunk 优化阶段开始时调用。插件可以 tap 此钩子对 chunk 执行优化。
- 回调参数:
chunks
- 回调参数:
-
afterOptimizeChunksSyncHook
chunk 优化完成之后触发。
- 回调参数:
chunks
- 回调参数:
-
optimizeTreeAsyncSeriesHook
在优化依赖树之前调用。插件可以 tap 此钩子执行依赖树优化。
- 回调参数:
chunksmodules
- 回调参数:
-
afterOptimizeTreeSyncHook
在依赖树优化成功完成之后调用。
- 回调参数:
chunksmodules
- 回调参数:
-
optimizeChunkModulesSyncBailHook
在树优化之后,chunk 模块优化开始时调用。插件可以 tap 此钩子来执行 chunk 模块的优化。
- 回调参数:
chunksmodules
- 回调参数:
-
afterOptimizeChunkModulesSyncHook
在 chunk 模块优化成功完成之后调用。
- 回调参数:
chunksmodules
- 回调参数:
-
shouldRecordSyncBailHook
调用来决定是否存储 record。返回任何内容
!== false将阻止执行所有其他 "record" 钩子(record,recordModules,recordChunks和recordHash)。 -
reviveModulesSyncHook
从 record 中恢复模块信息。
- 回调参数:
modulesrecords
- 回调参数:
-
beforeModuleIdsSyncHook
在为每个模块分配
id之前执行。- 回调参数:
modules
- 回调参数:
-
moduleIdsSyncHook
调用来每个模块分配一个
id。- 回调参数:
modules
- 回调参数:
-
optimizeModuleIdsSyncHook
在模块
id优化开始时调用。- 回调参数:
modules
- 回调参数:
-
afterOptimizeModuleIdsSyncHook
在模块
id优化完成时调用。- 回调参数:
modules
- 回调参数:
-
reviveChunksSyncHook
从 record 中恢复 chunk 信息。
- 回调参数:
chunksrecords
- 回调参数:
-
beforeChunkIdsSyncHook
在为每个 chunk 分配
id之前执行。- 回调参数:
chunks
- 回调参数:
-
chunkIdsSyncHook
调用时,会为每个 chunk 分配一个
id。- 回调函数的参数为:
chunks
- 回调函数的参数为:
-
optimizeChunkIdsSyncHook
在 chunk
id优化阶段开始时调用。- 回调参数:
chunks
- 回调参数:
-
afterOptimizeChunkIdsSyncHook
chunk
id优化结束之后触发。- 回调参数:
chunks
- 回调参数:
-
recordModulesSyncHook
将模块信息存储到 record 中。
shouldRecord返回 truthy 值时触发。- 回调参数:
modulesrecords
- 回调参数:
-
recordChunksSyncHook
将 chunk 存储到 record 中。
shouldRecord返回 truthy 值时触发。- 回调参数:
chunksrecords
- 回调参数:
-
beforeHashSyncHook
在 compilation 添加哈希(hash)之前。
-
afterHashSyncHook
在 compilation 添加哈希(hash)之后。
-
recordHashSyncHook
将有关 record 的信息存储到
records中。仅在shouldRecord返回 truthy 值时触发。- 回调参数:
records
- 回调参数:
-
recordSyncHook
将
compilation相关信息存储到record中。仅在shouldRecord返回 truthy 值时触发。- 回调参数:
compilationrecords
- 回调参数:
-
beforeModuleAssetsSyncHook
在创建模块 asset 之前执行。
-
additionalChunkAssetsSyncHook
additionalChunkAssets已弃用(可使用 Compilation.hook.processAssets 来代替,并且可使用 Compilation.PROCESSASSETS_STAGE* 作为其选项参数。)为这些 chunk 创建其他 asset。
- 回调参数:
chunks
- 回调参数:
-
shouldGenerateChunkAssetsSyncBailHook
调用以确定是否生成 chunk asset。返回任何
!== false将允许生成 chunk asset。 -
beforeChunkAssetsSyncHook
在创建 chunk asset 之前。
-
additionalAssetsAsyncSeriesHook
为 compilation 创建额外 asset。 这个钩子可以用来下载图像,例如:
jscompilation.hooks.additionalAssets.tapAsync('MyPlugin', callback => { download('https://img.shields.io/npm/v/webpack.svg', function(resp) { if(resp.status === 200) { compilation.assets['webpack-version.svg'] = toAsset(resp); callback(); } else { callback(new Error('[webpack-example-plugin] Unable to download the image')); } }); });12345678910 -
optimizeChunkAssetsAsyncSeriesHook
optimizeChunkAssets已弃用。(可使用 Compilation.hook.processAssets 来代替,并且可使用 Compilation.PROCESSASSETS_STAGE* 作为其选项参数。优化所有 chunk asset。asset 存储在
compilation.assets中。 每个Chunk都具有一个files属性,其指向由一个 chunk 创建的所有文件。 任何额外 chunk asset 都存储在compilation.additionalChunkAssets中。- 回调参数:
chunks
Here's an example that simply adds a banner to each chunk.
jscompilation.hooks .optimizeChunkAssets .tapAsync('MyPlugin', (chunks, callback) => { chunks.forEach(chunk => { chunk.files.forEach(file => { compilation.assets[file] = new ConcatSource( '\/**Sweet Banner**\/', '\n', compilation.assets[file] ); }); }); callback(); });123456789101112131415 - 回调参数:
-
afterOptimizeChunkAssetsSyncHook
afterOptimizeChunkAssets已弃用。(可使用 Compilation.hook.processAssets 来代替,并且可使用 Compilation.PROCESSASSETS_STAGE*作为其选项参数。chunk asset 已经被优化。
- 回调参数:
chunks
这里是一个来自 @boopathi 的示例插件,详细地输出每个 chunk 里有什么。
jscompilation.hooks.afterOptimizeChunkAssets.tap('MyPlugin', chunks => { chunks.forEach(chunk => { console.log({ id: chunk.id, name: chunk.name, includes: chunk.getModules().map(module => module.request) }); }); });123456789 - 回调参数:
-
optimizeAssetsAsyncSeriesHook
优化存储在
compilation.assets中的所有 asset。- 回调参数:
assets
- 回调参数:
-
afterOptimizeAssetsSyncHook
asset 已经优化。
- 回调参数:
assets
- 回调参数:
-
processAssetsAsyncSeriesHook
Asset processing.
- Callback Parameters:
assets
Here's an example:
jscompilation.hooks.processAssets.tap( { name: 'MyPlugin', stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS, // see below for more stages }, (assets) => { // code here } );123456789In addition to
nameandstage, you can pass aadditionalAssets5.8.0+ option which accepts either a value oftrueor a function withassetsas parameter:-
true- Run callback against assets added later by plugins.jscompilation.hooks.processAssets.tap( { name: 'MyPlugin', stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING, additionalAssets: true }, (assets) => { // this callback will run against assets added later by plugins. } );12345678910 -
(assets) => {}- Run this specified callback against assets added later by plugins.jscompilation.hooks.processAssets.tap( { name: 'MyPlugin', stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING, additionalAssets: (assets) => { // this callback will run against assets added later by plugins. } }, (assets) => { // code } );123456789101112
Here's a list of stages we can use:
PROCESS_ASSETS_STAGE_ADDITIONAL- Add additional assets to the compilation.PROCESS_ASSETS_STAGE_PRE_PROCESS- Basic preprocessing of the assets.PROCESS_ASSETS_STAGE_DERIVED- Derive new assets from the existing assets.PROCESS_ASSETS_STAGE_ADDITIONS- Add additional sections to the existing assets e.g. banner or initialization code.PROCESS_ASSETS_STAGE_OPTIMIZE- Optimize existing assets in a general way.PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT- Optimize the count of existing assets, e.g. by merging them.PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY- Optimize the compatibility of existing assets, e.g. add polyfills or vendor prefixes.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE- Optimize the size of existing assets, e.g. by minimizing or omitting whitespace.PROCESS_ASSETS_STAGE_DEV_TOOLING- Add development tooling to the assets, e.g. by extracting a source map.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE5.8.0+ - Optimize the numbers of existing assets, e.g. by inlining assets into other assets.PROCESS_ASSETS_STAGE_SUMMARIZE- Summarize the list of existing assets.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH- Optimize the hashes of the assets, e.g. by generating real hashes of the asset content.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER- Optimize the transfer of existing assets, e.g. by preparing a compressed (gzip) file as separate asset.PROCESS_ASSETS_STAGE_ANALYSE- Analyze the existing assets.PROCESS_ASSETS_STAGE_REPORT- Creating assets for the reporting purposes.
- Callback Parameters:
-
afterProcessAssetsSyncHook
Called after the
processAssetshook had finished without error. -
needAdditionalSealSyncBailHook
调用来决定 compilation 是否需要解除 seal 以引入其他文件。
-
afterSealAsyncSeriesHook
在
needAdditionalSeal之后立即执行。 -
chunkHashSyncHook
触发来为每个 chunk 生成 hash。
- 回调参数:
chunkchunkHash
- 回调参数:
-
moduleAssetSyncHook
一个模块中的一个 asset 被添加到 compilation 时调用。
- 回调参数:
modulefilename
- 回调参数:
-
chunkAssetSyncHook
一个 chunk 中的一个 asset 被添加到 compilation 时调用。
- 回调参数:
chunkfilename
- 回调参数:
-
assetPathSyncWaterfallHook
调用以决定 asset 的路径。
- 回调参数:
pathoptions
- 回调参数:
-
needAdditionalPassSyncBailHook
调用以决定 asset 在输出后是否需要进一步处理。
-
childCompilerSyncHook
子 compiler 设置之后执行。
- 回调参数:
childCompilercompilerNamecompilerIndex
- 回调参数:
-
normalModuleLoader从 webpack v5 开始,
normalModuleLoader钩子已经删除。现在要访问loader 请改用NormalModule.getCompilationHooks(compilation).loader。
JavascriptParser Hooks
parser 实例,在 compiler 中被发现,是用来解析由 webpack 处理过的每个模块。parser 也是扩展自 tapable 的 webpack 类 并且提供多种 tapable 钩子,
以下示例中,parser 位于 module factories 中,因此需要调用额外钩子 来进行获取:
compiler.hooks.normalModuleFactory.tap('MyPlugin', factory => {
factory.hooks.parser.for('javascript/auto').tap('MyPlugin', (parser, options) => {
parser.hooks.someHook.tap(/* ... */);
});
});
和 compiler 用法相同,取决于不同的钩子类型, 也可以在某些钩子上访问 tapAsync 和 tapPromise。
钩子
以下生命周期钩子函数,是由 parser 暴露,可以通过 如下方式访问:
-
evaluateTypeof
SyncBailHook
Triggered when evaluating an expression consisting in a
typeofof a free variable- Hook Parameters:
identifier - Callback Parameters:
expression
jsparser.hooks.evaluateTypeof.for('myIdentifier').tap('MyPlugin', expression => { /* ... */ return expressionResult; });1234这会触发
evaluateTypeof钩子的调用:jsconst a = typeof myIdentifier;1This won't trigger:
jsconst myIdentifier = 0; const b = typeof myIdentifier;12 - Hook Parameters:
-
evaluate
SyncBailHook
Called when evaluating an expression.
- Hook parameters:
expressionType - Callback parameters:
expression
For example:
index.js
jsconst a = new String();1MyPlugin.js
jsparser.hooks.evaluate.for('NewExpression').tap('MyPlugin', expression => { /* ... */ return expressionResult; });1234Where the expressions types are:
'ArrowFunctionExpression''AssignmentExpression''AwaitExpression''BinaryExpression''CallExpression''ClassExpression''ConditionalExpression''FunctionExpression''Identifier''LogicalExpression''MemberExpression''NewExpression''ObjectExpression''SequenceExpression''SpreadElement''TaggedTemplateExpression''TemplateLiteral''ThisExpression''UnaryExpression''UpdateExpression'
- Hook parameters:
-
evaluateIdentifier
SyncBailHook
Called when evaluating an identifier that is a free variable.
- Hook Parameters:
identifier - Callback Parameters:
expression
- Hook Parameters:
-
evaluateDefinedIdentifier
SyncBailHook
Called when evaluating an identifier that is a defined variable.
- Hook Parameters:
identifier - Callback Parameters:
expression
- Hook Parameters:
-
evaluateCallExpressionMember
SyncBailHook
Called when evaluating a call to a member function of a successfully evaluated expression.
- Hook Parameters:
identifier - Callback Parameters:
expressionparam
This expression will trigger the hook:
index.js
jsconst a = expression.myFunc();1MyPlugin.js
jsparser.hooks.evaluateCallExpressionMember.for('myFunc').tap('MyPlugin', (expression, param) => { /* ... */ return expressionResult; });1234 - Hook Parameters:
-
statement
SyncBailHook
General purpose hook that is called for every parsed statement in a code fragment.
- Callback Parameters:
statement
jsparser.hooks.statement.tap('MyPlugin', statement => { /* ... */ });1Where the
statement.typecould be:'BlockStatement''VariableDeclaration''FunctionDeclaration''ReturnStatement''ClassDeclaration''ExpressionStatement''ImportDeclaration''ExportAllDeclaration''ExportDefaultDeclaration''ExportNamedDeclaration''IfStatement''SwitchStatement''ForInStatement''ForOfStatement''ForStatement''WhileStatement''DoWhileStatement''ThrowStatement''TryStatement''LabeledStatement''WithStatement'
- Callback Parameters:
-
statementIf
SyncBailHook
Called when parsing an if statement. Same as the
statementhook, but triggered only whenstatement.type == 'IfStatement'.- Callback Parameters:
statement
- Callback Parameters:
-
label
SyncBailHook
Called when parsing statements with a label. Those statements have
statement.type === 'LabeledStatement'.- Hook Parameters:
labelName - Callback Parameters:
statement
- Hook Parameters:
-
import
SyncBailHook
Called for every import statement in a code fragment. The
sourceparameter contains the name of the imported file.- Callback Parameters:
statementsource
The following import statement will trigger the hook once:
index.js
jsimport _ from 'lodash';1MyPlugin.js
jsparser.hooks.import.tap('MyPlugin', (statement, source) => { // source == 'lodash' });123 - Callback Parameters:
-
importSpecifier
SyncBailHook
Called for every specifier of every
importstatement.- Callback Parameters:
statementsourceexportNameidentifierName
The following import statement will trigger the hook twice:
index.js
jsimport _, { has } from 'lodash';1MyPlugin.js
jsparser.hooks.importSpecifier.tap('MyPlugin', (statement, source, exportName, identifierName) => { /* First call source == 'lodash' exportName == 'default' identifierName == '_' */ /* Second call source == 'lodash' exportName == 'has' identifierName == 'has' */ });123456789101112 - Callback Parameters:
-
export
SyncBailHook
Called for every
exportstatement in a code fragment.- Callback Parameters:
statement
- Callback Parameters:
-
exportImport
SyncBailHook
Called for every
export-import statement eg:export * from 'otherModule';.- Callback Parameters:
statementsource
- Callback Parameters:
-
exportDeclaration
SyncBailHook
Called for every
exportstatement exporting a declaration.- Callback Parameters:
statementdeclaration
Those exports will trigger this hook:
jsexport const myVar = 'hello'; // also var, let export function FunctionName(){} export class ClassName {}123 - Callback Parameters:
-
exportExpression
SyncBailHook
Called for every
exportstatement exporting an expression e.g.export default expression;.- Callback Parameters:
statementdeclaration
- Callback Parameters:
-
exportSpecifier
SyncBailHook
Called for every specifier of every
exportstatement.- Callback Parameters:
statementidentifierNameexportNameindex
- Callback Parameters:
-
exportImportSpecifier
SyncBailHook
Called for every specifier of every
export-import statement.- Callback Parameters:
statementsourceidentifierNameexportNameindex
- Callback Parameters:
-
varDeclaration
SyncBailHook
Called when parsing a variable declaration.
- Callback Parameters:
declaration
- Callback Parameters:
-
varDeclarationLet
SyncBailHook
Called when parsing a variable declaration defined using
let- Callback Parameters:
declaration
- Callback Parameters:
-
varDeclarationConst
SyncBailHook
Called when parsing a variable declaration defined using
const- Callback Parameters:
declaration
- Callback Parameters:
-
varDeclarationVar
SyncBailHook
Called when parsing a variable declaration defined using
var- Callback Parameters:
declaration
- Callback Parameters:
-
canRename
SyncBailHook
Triggered before renaming an identifier to determine if the renaming is allowed. This is usually used together with the
renamehook.- Hook Parameters:
identifier - Callback Parameters:
expression
jsvar a = b; parser.hooks.canRename.for('b').tap('MyPlugin', expression => { // returning true allows renaming return true; });123456 - Hook Parameters:
-
rename
SyncBailHook
Triggered when renaming to get the new identifier. This hook will be called only if
canRenamereturnstrue.- Hook Parameters:
identifier - Callback Parameters:
expression
jsvar a = b; parser.hooks.rename.for('b').tap('MyPlugin', expression => {});123 - Hook Parameters:
-
assigned
SyncBailHook
Called when parsing an
AssignmentExpressionbefore parsing the assigned expression.- Hook Parameters:
identifier - Callback Parameters:
expression
jsa += b; parser.hooks.assigned.for('a').tap('MyPlugin', expression => { // this is called before parsing b });12345 - Hook Parameters:
-
assign
SyncBailHook
Called when parsing an
AssignmentExpressionbefore parsing the assign expression.- Hook Parameters:
identifier - Callback Parameters:
expression
jsa += b; parser.hooks.assigned.for('a').tap('MyPlugin', expression => { // this is called before parsing a });12345 - Hook Parameters:
-
typeof
SyncBailHook
Triggered when parsing the
typeofof an identifier- Hook Parameters:
identifier - Callback Parameters:
expression
- Hook Parameters:
-
call
SyncBailHook
Called when parsing a function call.
- Hook Parameters:
identifier - Callback Parameters:
expression
jseval(/* something */); parser.hooks.call.for('eval').tap('MyPlugin', expression => {});123 - Hook Parameters:
-
callAnyMember
SyncBailHook
Triggered when parsing a call to a member function of an object.
- Hook Parameters:
objectIdentifier - Callback Parameters:
expression
jsmyObj.anyFunc(); parser.hooks.callAnyMember.for('myObj').tap('MyPlugin', expression => {});123 - Hook Parameters:
-
new
SyncBailHook
Invoked when parsing a
newexpression.- Hook Parameters:
identifier - Callback Parameters:
expression
jsnew MyClass(); parser.hooks.new.for('MyClass').tap('MyPlugin', expression => {});123 - Hook Parameters:
-
expression
SyncBailHook
Called when parsing an expression.
- Hook Parameters:
identifier - Callback Parameters:
expression
jsconst a = this; parser.hooks.expression.for('this').tap('MyPlugin', expression => {});123 - Hook Parameters:
-
expressionConditionalOperator
SyncBailHook
Called when parsing a
ConditionalExpressione.g.condition ? a : b- Callback Parameters:
expression
- Callback Parameters:
-
program
SyncBailHook
Get access to the abstract syntax tree (AST) of a code fragment
- Parameters:
astcomments
- Parameters:
Plugin API
插件是 webpack 生态的关键部分, 它为社区用户提供了一种强有力的方式来直接触及 webpack 的编译过程(compilation process)。 插件能够 hook 到每一个编译(compilation)中发出的关键事件中。 在编译的每个阶段中,插件都拥有对 compiler 对象的完全访问能力, 并且在合适的时机,还可以访问当前的 compilation 对象。
Tapable
这个小型库是 webpack 的一个核心工具,但也可用于其他地方, 以提供类似的插件接口。 在 webpack 中的许多对象都扩展自 Tapable 类。 它对外暴露了 tap,tapAsync 和 tapPromise 等方法, 插件可以使用这些方法向 webpack 中注入自定义构建的步骤,这些步骤将在构建过程中触发。
请查阅文档了解更多知识。 理解上面的的三种 tap 方法, 以及提供这些方法的钩子(hooks)对于编写插件来说是至关重要的。 那些扩展自 Tapable 的对象(例如:compiler), 以及其提供的钩子(hooks)和每个钩子的类型(例如:同步钩子(SyncHook))值得关注。
插件类型
根据使用不同的钩子(hooks)和 tap 方法, 插件可以以多种不同的方式运行。 这个工作方式与 Tapable 提供的钩子(hooks)密切相关。 compiler hooks 分别记录了 Tapable 内在的钩子, 并指出哪些 tap 方法可用。
所以,依赖于使用的 tap 方法的不同, 插件可能会以不同的方式运行。 例如:当你钩入到 编译(compile) 阶段时,只有同步的 tap 方法可以使用。
compiler.hooks.compile.tap('MyPlugin', params => {
console.log('以同步方式触及 compile 钩子。');
});
然而,对于可以使用 AsyncHook 的 run 阶段, 则需使用 tapAsync 或 tapPromise(以及 tap)方法。
compiler.hooks.run.tapAsync('MyPlugin', (source, target, routesList, callback) => {
console.log('以异步方式触及 run 钩子。');
callback();
});
compiler.hooks.run.tapPromise('MyPlugin', (source, target, routesList) => {
return new Promise(resolve => setTimeout(resolve, 1000)).then(() => {
console.log('以具有延迟的异步方式触及 run 钩子。');
});
});
compiler.hooks.run.tapPromise('MyPlugin', async (source, target, routesList) => {
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('以具有延迟的异步方式触及 run 钩子。');
});
这些需求(story)的含义在于, 我们可以有多种方式 hook 到 compiler 中,可以让各种插件都以合适的方式去运行。
自定义钩子
为了便于其他插件的编译过程中可以 tap 到,则需要创建一个新的 hook, 我们只需要简单的从 tapable 中 require 所需的 hook 类,并创建:
const SyncHook = require('tapable').SyncHook;
if (compiler.hooks.myCustomHook) throw new Error('已存在该钩子');
compiler.hooks.myCustomHook = new SyncHook(['a', 'b', 'c']);
// 在你想要触发钩子的位置/时机下调用……
compiler.hooks.myCustomHook.call(a, b, c);
再次声明, 查看 tapable 文档 来了解更多不同的钩子类(hook class),以及它们是如何工作的。
进度报告
插件能够通过 ProgressPlugin 这个在默认情况下将信息打印到标准错误输出(stderr)的插件来进行进度报告。如果想要使用这个功能,只需要在使用 webpack CLI 的时候传入 --progress 参数。
如果想要自定义打印输出,只需要传递不同的参数到 ProgressPlugin 的 reportProgress 方法。
如果想要报告进度,插件必须在 tap 到 hook 的时候使用 context: true 选项。
compiler.hooks.emit.tapAsync({
name: 'MyPlugin',
context: true
}, (context, compiler, callback) => {
const reportProgress = context && context.reportProgress;
if (reportProgress) reportProgress(0.95, 'Starting work');
setTimeout(() => {
if (reportProgress) reportProgress(0.95, 'Done work');
callback();
}, 1000);
});
reportProgress 方法在被调用的时候会传入以下的参数:
reportProgress(percentage, ...args);
percentage:此参数未使用。作为代替,ProgressPlugin插件会基于当前的钩子(hook)计算进度。...args:任意数量的字符串,这些字符串会传递给ProgressPlugin插件并报告给用户。
注意:只有 compiler 和 compilation 钩子的子集才支持 reportProgress 方法。请查看 ProgressPlugin 了解更多信息
日志
日志的 API 在 webpack 4.37 版本后提供支持。当 logging 在 统计配置(stats configuration)中可用和(或)当 infrastructure logging 可用的时候,插件会通过各自的记录格式(stats,infrastructure)打印信息。
- 插件可以使用
compilation.getLogger('PluginName')来做记录。这种形式的记录保存在统计数据(Stats)中并做相应的格式化。它能够被用户过滤和导出。 - 插件也可以使用
compilation.getInfrastructureLogger('PluginName')来做记录。使用infrastructure的形式并不会被保存在统计数据(Stats)中,因此也不会被格式化。它通常直接将记录载入到 console/dashboard/GUI 中。它能够被用户过滤。 - 插件也可以使用特殊的降级逻辑
compilation.getLogger ? compilation.getLogger('PluginName') : console来检测是否支持记录,以此来在不支持compilation.getLogger方法的旧版本 webpack 中提供降级方法。
解析器(Resolvers)
解析器是使用 enhanced-resolve 库创建的。Resolver 类 拓展了 tapable 类,并使用 tapable 来提供了一些钩子。 enhanced-resolve 可以直接用于创建新的解析器, 但是,任何 compiler 实例 都有一些解析器实例,可以 被 tap 进去。
在继续阅读之前,请确保你已经读过 enhanced-resolve 和 tapable 文档。
类型
在 compiler 类中,提供了三种类型的内置解析器:
normal: 通过绝对或相对路径解析模块。context: 在给定的上下文中解析模块。loader: 解析 webpack loader。
根据需要,任一个被使用在 compiler 中的内置解析器, 可以通过插件进行定制:
compiler.resolverFactory.hooks.resolver.for('[type]').tap('name', resolver => {
// you can tap into resolver.hooks now
resolver.hooks.result.tap('MyPlugin', result => {
return result;
});
});
其中,[type] 是上述三个解析器之一。
请参阅 enhanced-resolve documentation 以获得钩子的完整列表以及它们的介绍。
配置选项
上述解析器也可以 利用 resolve or resolveLoader 选项,通过配置文件进行定制。这些选项允许 用户可以通过多种选项来更改解析行为,包括 通过解析 plugins。
解析器插件,例如:DirectoryNamedPlugin,可以直接引入 在 resolve.plugins,而不是直接在 plugins configuration option 中使用。
请注意,resolve 配置会影响 normal 解析器和 context 解析器,而“ resolveLoader 用于修改 loader 解析器。
评论 (0)