Webpack插件和loader开发配置

偏向技术
/ 0 评论 / 162 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年04月01日,已超过1332天没有更新,若内容或图片失效,请留言反馈。

Compilation Object

Compilation 对象有很多可用的方法和钩子。在此页面,我们将会列举出这些可用的方法和属性。

compilation 对象方法

  1. getStats

    function

    返回当前编译的状态对象。

  2. addModule

    function (module, cacheGroup)

    向当前编译添加一个模块。

    参数:

    • module - 要添加的模块
    • cacheGroup - 模块的 cacheGroup
  3. getModule

    function (module)

    通过编译的标识符获取其模块。

    参数:

    • module - 要获取的模块。标识符是通过编译使用 module.identifier() 方法从模块中提取的。
  4. findModule

    function (module)

    尝试通过其标识符搜索模块。

    参数:

    • module - 要搜索的模块。标识符是通过编译使用 module.identifier() 方法从模块中提取的。
  5. waitForBuildingFinished

    function (module, callback)

    在构建给定模块时运行给定的 callback 函数。

    参数:

    • module - 有问题的模块。
    • callback - 要调用的函数。
  6. buildModule

    function (module, optional, origin, dependencies)

    构建给定的模块。

    参数:

    • module - 要构建的模块。
    • optional - 可选标志。
    • origin - 请求此模块构建的原始模块。
    • dependencies - 要构建模块的可选依赖。
  7. processModuleDependencies

    function (module, callback)

    处理给定模块依赖。

    参数:

    • module - 要被处理依赖的模块。
    • callback - 模块依赖处理完成时回调的函数。
  8. addModuleDependencies

    function (module, dependencies, bail, cacheGroup, recursive, callback)

    向模块添加依赖。处理依赖之后被 processModuleDependencies 自动调用。

    参数:

    • module - 要添加依赖的模块。
    • dependencies - 要遍历添加到模块的一组已排序依赖。
    • bail - 发生错误时是否中断进程并抛出 error。
    • cacheGroup - 模块的 cacheGroup
    • recursive - 是否要递归遍历。
    • callback - 添加模块依赖之后回调的函数。
  9. addEntry

    function (context, entry, name, callback)

    为编译添加入口。

    参数:

    • context - 入口的上下文路径。
    • entry - 入口依赖。
    • name - 入口名称。
    • callback - 添加入口完成之后回调的函数。
  10. prefetch

    function (context, dependency, callback)

    根据给定的依赖创建一个模块。

    参数:

    • context - 上下文路径。
    • dependency - 被用来创建模块的依赖。
    • callback - 向上一级发送模块的模块回调。
  11. rebuildModule

    function (module, thisCallback)

    触发模块的重建。

    参数:

    • module - 要被重建的模块。
    • thisCallback - 模块重建完成之后调用的函数。
  12. finish

    function (callback)

    完成编译并调用给定的回调。

    参数:

    • callback - 编译完成之后调用的函数。
  13. seal

    function (callback)

    封闭编译。

    参数:

    • callback - 封闭编译时回调的函数。
  14. unseal

    function

    解除封闭编译。

    参数:

    • callback - 解除封闭编译时回调的函数。
  15. reportDependencyErrorsAndWarnings

    function (module, blocks)

    将给定模块的错误和警告添加到编译的错误和警告中。

    参数:

    • module - 要被报告错误与警告的模块。
    • blocks - 一组要报告的依赖块。
  16. addChunkInGroup

    function (groupOptions, module, loc, request)

    将模块添加到现有 chunk 组或创建一个新的组。返回一个 chunkGroup

    参数:

    • groupOptions - chunk 组的选项。
    • module - 引用 chunk 组的模块。
    • loc - 引用 chunk 组的位置(模块内部)。
    • request - 引用 chunk 组的请求。
  17. addChunk

    function (name)

    compilation.chunks 创建或添加一个新的 chunk。返回这个 chunk.

    参数:

    • name - chunk 的名称。
  18. assignDepth

    function (module)

    为给定的模块及其依赖块递归分配 depth

    参数:

    • module - 要被分配 depth 的模块。
  19. getDependencyReference

    function (module, dependency)

    返回给定模块对依赖的引用。

    参数:

    • module - 有问题的模块。
    • dependency - 要引用的依赖。
  20. processDependenciesBlocksForChunkGroups

    function (inputChunkGroups)

    通过 Module 图创建 Chunk 图。该过程分为两个阶段完成。阶段一:遍历模块图,在 chunkDependencies 中创建一个基础 chunk 图。阶段二:通过基本 chunk 图遍历所有可能的方法并且跟踪可用模块。遍历过程中 processDependenciesBlocksForChunkGroups 将 chunk 相互连接,并将 BlocksChunks 连接. 当一个 chunk 的所有模块都已经可用且未连接不需要的 chunk 时,它将停止遍历。

    参数:

    • inputChunkGroups - 被处理的 chunk 组。
  21. removeReasonsOfDependencyBlock

    function (module, block)

    移除模块与依赖块之间的关系。

    参数:

    • module - 要移除的模块关系。
    • block - 依赖块。
  22. patchChunksAfterReasonRemoval

    function (module, chunk)

    删除依赖性原因后,修补模块和 chunk 的关系。被 removeReasonsOfDependencyBlock 自动调用。

    参数:

    • module - 要修复关系的模块。
    • chunk - 要修复关系的 chunk。
  23. removeChunkFromDependencies

    function (block, chunk)

    在除去依赖性原因后,从依赖块模块和 chunk 中移除给定的 chunk。会被 removeReasonsOfDependencyBlock 自动调用。

    参数:

    • block - Chunk 的块连接。
    • chunk - 从依赖中删除的块。
  24. sortItemsWithModuleIds

    function

  25. sortItemsWithChunkIds

    function

  26. summarizeDependencies

    function

  27. createHash

    function

  28. createModuleAssets

    function

  29. createChunkAssets

    function

  30. getPath

    function (filename, data)

    返回插值路径。

    参数:

    • filename - 用于通过哈希获取资源路径。
    • data - 数据对象。
  31. getPathWithInfo

    function (filename, data)

    返回插值路径和资源信息。

    参数:

    • filename - 用于通过哈希获取资源路径。
    • data - 数据对象。
  32. createChildCompiler

    function (name, outputOptions, plugins)

    允许在 webpack 中运行另一个 webpack 实例。但是,子编译器会应用不同的设置和配置。他会从父编译器(或者顶级编译器)中复制所有的钩子(hook)和插件(plugin),并且创建一个子 Compiler 实例。 返回值为创建好的 Compiler 实例。

    参数:

    • name - 子 Compiler 的名称。
    • outputOptions - 输出选项。
    • plugins - 将被提供的 webpack 插件。
  33. checkConstraints

    function

  34. emitAsset

    function (file, source, assetInfo = {})

    webpack 4.40.0 后可用。

    参数:

    • file - 资源名称。
    • source - 资源来源。
    • assetInfo - 附加资源信息。
  35. updateAsset

    function (file, newSourceOrFunction, assetInfoUpdateOrFunction)

    webpack 4.40.0 后可用。

    参数:

    • file - 资源名称。
    • newSourceOrFunction - 新资源来源或将旧资源转换为新资源的函数。
    • assetInfoUpdateOrFunction - 新资源信息或将旧资源转换为新资源的函数。
  36. deleteAsset

    function (file)

    参数:

    • file —— 资源的文件名
  37. getAssets

    function

    webpack 4.40.0 后可用。

    返回当前编译下所有资源的数组。

  38. 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, watchCloseinvalid 等额外的事件。 通常在 开发环境 中使用, 也常常会在 webpack-dev-server 这些工具的底层调用, 由此开发人员无须每次都使用手动方式重新编译。 还可以通过 CLI 进入监听模式。

钩子

以下生命周期钩子函数,是由 compiler 暴露, 可以通过如下方式访问:

js
compiler.hooks.someHook.tap('MyPlugin', (params) => {
  /* ... */
});
123

取决于不同的钩子类型,也可以在某些钩子上访问 tapAsynctapPromise

关于钩子类型的描述,请查看 Tapable 文档.

  1. entryOption

    SyncBailHook

    在 webpack 选项中的 entry 被处理过之后调用。

    js
    compiler.hooks.entryOption.tap('MyPlugin', (context, entry) => {
      /* ... */
    });
    123

    参数:context, entry

  2. afterPlugins

    SyncHook

    在初始化内部插件集合完成设置之后调用。

    • 回调参数:compiler
  3. afterResolvers

    SyncHook

    resolver 设置完成之后触发。

    • 回调参数:compiler
  4. environment

    SyncHook

    在初始化配置文件中的插件之后立即调用,在 compiler environment 准备时调用。

  5. afterEnvironment

    SyncHook

    environment 钩子之后立即调用,在 compiler environment 完成设置时调用。

  6. beforeRun

    AsyncSeriesHook

    在开始执行一次构建之前调用,compiler.run 方法开始执行后立刻进行调用。

    • 回调参数:compiler
  7. additionalPass

    AsyncSeriesHook

    This hook allows you to do a one more additional pass of the build.

  8. run

    AsyncSeriesHook

    在开始读取 records 之前调用。

    • 回调参数:compiler
  9. watchRun

    AsyncSeriesHook

    在监听模式下,一个新的 compilation 触发之后,但在 compilation 实际开始之前执行。

    • 回调参数:compiler
  10. normalModuleFactory

    SyncHook

    NormalModuleFactory 创建之后调用。

    • 回调参数:normalModuleFactory
  11. contextModuleFactory

    SyncHook

    ContextModuleFactory 创建之后调用。

    • 回调参数:contextModuleFactory
  12. initialize

    SyncHook

    在初始化 compiler 对象时调用。

  13. beforeCompile

    AsyncSeriesHook

    在创建 compilation parameter 之后执行。

    • 回调参数:compilationParams

    初始化 compilationParams 变量的示例如下:

    js
     compilationParams = {
       normalModuleFactory,
       contextModuleFactory,
     };
    1234

    此钩子可用于添加/修改 compilation parameter:

    js
     compiler.hooks.beforeCompile.tapAsync('MyPlugin', (params, callback) => {
       params['MyPlugin - data'] = 'important stuff my plugin will use later';
       callback();
     });
    1234
  14. compile

    SyncHook

    beforeCompile 之后立即调用,但在一个新的 compilation 创建之前。

    • 回调参数:compilationParams
  15. thisCompilation

    SyncHook

    初始化 compilation 时调用,在触发 compilation 事件之前调用。

    • 回调参数:compilation, compilationParams
  16. compilation

    SyncHook

    compilation 创建之后执行。

    • 回调参数:compilation, compilationParams
  17. make

    AsyncParallelHook

    compilation 结束之前执行。

    • 回调参数:compilation
  18. afterCompile

    AsyncSeriesHook

    compilation 结束和封印之后执行。

    • 回调参数:compilation
  19. shouldEmit

    SyncBailHook

    在输出 asset 之前调用。返回一个布尔值,告知是否输出。

    • 回调参数:compilation
    js
     compiler.hooks.shouldEmit.tap('MyPlugin', (compilation) => {
       // 返回 true 以输出 output 结果,否则返回 false
       return true;
     });
    1234
  20. emit

    AsyncSeriesHook

    输出 asset 到 output 目录之前执行。

    • 回调参数:compilation
  21. afterEmit

    AsyncSeriesHook

    输出 asset 到 output 目录之后执行。

    • 回调参数:compilation
  22. assetEmitted

    AsyncSeriesHook

    在 asset 被输出时执行。此钩子可以访问被输出的 asset 的相关信息,例如它的输出路径和字节内容。

    • 回调参数:file, info

    例如,可以通过 info.content 访问 asset 的内容 buffer:

    js
     compiler.hooks.assetEmitted.tap(
       'MyPlugin',
       (file, { content, source, outputPath, compilation, targetPath }) => {
         console.log(content); // <Buffer 66 6f 6f 62 61 72>
       }
     );
    123456
  23. done

    AsyncSeriesHook

    在 compilation 完成时执行。

    • 回调参数:stats
  24. failed

    SyncHook

    在 compilation 失败时调用。

    • 回调参数:error
  25. invalid

    SyncHook

    在一个观察中的 compilation 无效时执行。

    • 回调参数:fileName, changeTime
  26. watchClose

    SyncHook

    在一个观察中的 compilation 停止时执行。

  27. infrastructureLog

    SyncBailHook

    在配置中启用 infrastructureLogging 选项 后,允许使用 infrastructure log(基础日志)。

    • 回调参数:name, type, args
  28. log

    SyncBailHook

    启用后允许记录到 stats 对象,请参阅 stats.logging, stats.loggingDebugstats.loggingTrace 选项

    • 回调参数:origin, logEntry

compilation 钩子

Compilation 模块会被 Compiler 用来创建新的 compilation 对象(或新的 build 对象)。 compilation 实例能够访问所有的模块和它们的依赖(大部分是循环依赖)。 它会对应用程序的依赖图中所有模块, 进行字面上的编译(literal compilation)。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。

Compilation 类扩展(extend)自 Tapable,并提供了以下生命周期钩子。 可以按照 compiler 钩子的相同方式来调用 tap:

js
compilation.hooks.someHook.tap(/* ... */);
1

compiler 用法相同,取决于不同的钩子类型, 所以也可以在某些钩子上访问 tapAsynctapPromise

  1. buildModule

    SyncHook

    在模块构建开始之前触发,可以用来修改模块。

    • 回调参数:module
    js
    compilation.hooks.buildModule.tap('SourceMapDevToolModuleOptionsPlugin',
      module => {
        module.useSourceMap = true;
      }
    );
    12345
  2. rebuildModule

    SyncHook

    在重新构建一个模块之前触发。

    • 回调参数:module
  3. failedModule

    SyncHook

    模块构建失败时执行。

    • 回调参数:module error
  4. succeedModule

    SyncHook

    模块构建成功时执行。

    • 回调参数:module
  5. finishModules

    AsyncSeriesHook

    所有模块都完成构建并且没有错误时执行。

    • 回调参数:modules
  6. finishRebuildingModule

    SyncHook

    一个模块完成重新构建时执行,在都成功或有错误的情况下。

    • 回调参数:module
  7. seal

    SyncHook

    compilation 对象停止接收新的模块时触发。

  8. unseal

    SyncHook

    compilation 对象开始接收新模块时触发。

  9. optimizeDependencies

    SyncBailHook

    依赖优化开始时触发。

    • 回调参数:modules
  10. afterOptimizeDependencies

    SyncHook

    依赖优化之后触发。

    • 回调参数:modules
  11. optimize

    SyncHook

    优化阶段开始时触发。

  12. optimizeModules

    SyncBailHook

    在模块优化阶段开始时调用。插件可以 tap 此钩子对模块进行优化。

    • 回调参数:modules
  13. afterOptimizeModules

    SyncHook

    在模块优化完成之后调用。

    • 回调参数:modules
  14. optimizeChunks

    SyncBailHook

    在 chunk 优化阶段开始时调用。插件可以 tap 此钩子对 chunk 执行优化。

    • 回调参数:chunks
  15. afterOptimizeChunks

    SyncHook

    chunk 优化完成之后触发。

    • 回调参数:chunks
  16. optimizeTree

    AsyncSeriesHook

    在优化依赖树之前调用。插件可以 tap 此钩子执行依赖树优化。

    • 回调参数:chunks modules
  17. afterOptimizeTree

    SyncHook

    在依赖树优化成功完成之后调用。

    • 回调参数:chunks modules
  18. optimizeChunkModules

    SyncBailHook

    在树优化之后,chunk 模块优化开始时调用。插件可以 tap 此钩子来执行 chunk 模块的优化。

    • 回调参数:chunks modules
  19. afterOptimizeChunkModules

    SyncHook

    在 chunk 模块优化成功完成之后调用。

    • 回调参数:chunks modules
  20. shouldRecord

    SyncBailHook

    调用来决定是否存储 record。返回任何内容 !== false 将阻止执行所有其他 "record" 钩子(record, recordModules, recordChunksrecordHash)。

  21. reviveModules

    SyncHook

    从 record 中恢复模块信息。

    • 回调参数:modules records
  22. beforeModuleIds

    SyncHook

    在为每个模块分配 id 之前执行。

    • 回调参数:modules
  23. moduleIds

    SyncHook

    调用来每个模块分配一个 id

    • 回调参数:modules
  24. optimizeModuleIds

    SyncHook

    在模块 id 优化开始时调用。

    • 回调参数:modules
  25. afterOptimizeModuleIds

    SyncHook

    在模块 id 优化完成时调用。

    • 回调参数:modules
  26. reviveChunks

    SyncHook

    从 record 中恢复 chunk 信息。

    • 回调参数:chunks records
  27. beforeChunkIds

    SyncHook

    在为每个 chunk 分配 id 之前执行。

    • 回调参数:chunks
  28. chunkIds

    SyncHook

    调用时,会为每个 chunk 分配一个 id

    • 回调函数的参数为:chunks
  29. optimizeChunkIds

    SyncHook

    在 chunk id 优化阶段开始时调用。

    • 回调参数:chunks
  30. afterOptimizeChunkIds

    SyncHook

    chunk id 优化结束之后触发。

    • 回调参数:chunks
  31. recordModules

    SyncHook

    将模块信息存储到 record 中。shouldRecord 返回 truthy 值时触发。

    • 回调参数:modules records
  32. recordChunks

    SyncHook

    将 chunk 存储到 record 中。shouldRecord 返回 truthy 值时触发。

    • 回调参数:chunks records
  33. beforeHash

    SyncHook

    在 compilation 添加哈希(hash)之前。

  34. afterHash

    SyncHook

    在 compilation 添加哈希(hash)之后。

  35. recordHash

    SyncHook

    将有关 record 的信息存储到 records 中。仅在 shouldRecord 返回 truthy 值时触发。

    • 回调参数:records
  36. record

    SyncHook

    compilation 相关信息存储到 record 中。仅在 shouldRecord 返回 truthy 值时触发。

    • 回调参数:compilation records
  37. beforeModuleAssets

    SyncHook

    在创建模块 asset 之前执行。

  38. additionalChunkAssets

    SyncHook

    additionalChunkAssets 已弃用(可使用 Compilation.hook.processAssets 来代替,并且可使用 Compilation.PROCESSASSETS_STAGE* 作为其选项参数。)

    为这些 chunk 创建其他 asset。

    • 回调参数:chunks
  39. shouldGenerateChunkAssets

    SyncBailHook

    调用以确定是否生成 chunk asset。返回任何 !== false 将允许生成 chunk asset。

  40. beforeChunkAssets

    SyncHook

    在创建 chunk asset 之前。

  41. additionalAssets

    AsyncSeriesHook

    为 compilation 创建额外 asset。 这个钩子可以用来下载图像,例如:

    js
     compilation.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
  42. optimizeChunkAssets

    AsyncSeriesHook

    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.

    js
     compilation.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
  43. afterOptimizeChunkAssets

    SyncHook

    afterOptimizeChunkAssets 已弃用。(可使用 Compilation.hook.processAssets 来代替,并且可使用 Compilation.PROCESSASSETS_STAGE*作为其选项参数。

    chunk asset 已经被优化。

    • 回调参数:chunks

    这里是一个来自 @boopathi 的示例插件,详细地输出每个 chunk 里有什么。

    js
     compilation.hooks.afterOptimizeChunkAssets.tap('MyPlugin', chunks => {
       chunks.forEach(chunk => {
         console.log({
           id: chunk.id,
           name: chunk.name,
           includes: chunk.getModules().map(module => module.request)
         });
       });
     });
    123456789
  44. optimizeAssets

    AsyncSeriesHook

    优化存储在 compilation.assets 中的所有 asset。

    • 回调参数:assets
  45. afterOptimizeAssets

    SyncHook

    asset 已经优化。

    • 回调参数:assets
  46. processAssets

    AsyncSeriesHook

    Asset processing.

    • Callback Parameters: assets

    Here's an example:

    js
     compilation.hooks.processAssets.tap(
       {
         name: 'MyPlugin',
         stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS, // see below for more stages
       },
       (assets) => {
         // code here
       }
     );
    123456789

    In addition to name and stage, you can pass a additionalAssets 5.8.0+ option which accepts either a value of true or a function with assets as parameter:

    1. true - Run callback against assets added later by plugins.

      js
      compilation.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
    2. (assets) => {} - Run this specified callback against assets added later by plugins.

      js
      compilation.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_INLINE 5.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.
  47. afterProcessAssets

    SyncHook

    Called after the processAssets hook had finished without error.

  48. needAdditionalSeal

    SyncBailHook

    调用来决定 compilation 是否需要解除 seal 以引入其他文件。

  49. afterSeal

    AsyncSeriesHook

    needAdditionalSeal 之后立即执行。

  50. chunkHash

    SyncHook

    触发来为每个 chunk 生成 hash。

    • 回调参数:chunk chunkHash
  51. moduleAsset

    SyncHook

    一个模块中的一个 asset 被添加到 compilation 时调用。

    • 回调参数:module filename
  52. chunkAsset

    SyncHook

    一个 chunk 中的一个 asset 被添加到 compilation 时调用。

    • 回调参数:chunk filename
  53. assetPath

    SyncWaterfallHook

    调用以决定 asset 的路径。

    • 回调参数:path options
  54. needAdditionalPass

    SyncBailHook

    调用以决定 asset 在输出后是否需要进一步处理。

  55. childCompiler

    SyncHook

    子 compiler 设置之后执行。

    • 回调参数:childCompiler compilerName compilerIndex
  56. normalModuleLoader

    从 webpack v5 开始,normalModuleLoader 钩子已经删除。现在要访问loader 请改用 NormalModule.getCompilationHooks(compilation).loader

JavascriptParser Hooks

parser 实例,在 compiler 中被发现,是用来解析由 webpack 处理过的每个模块。parser 也是扩展自 tapable 的 webpack 类 并且提供多种 tapable 钩子,

以下示例中,parser 位于 module factories 中,因此需要调用额外钩子 来进行获取:

js
compiler.hooks.normalModuleFactory.tap('MyPlugin', factory => {
  factory.hooks.parser.for('javascript/auto').tap('MyPlugin', (parser, options) => {
    parser.hooks.someHook.tap(/* ... */);
  });
});
12345

compiler 用法相同,取决于不同的钩子类型, 也可以在某些钩子上访问 tapAsynctapPromise

钩子

以下生命周期钩子函数,是由 parser 暴露,可以通过 如下方式访问:

  1. evaluateTypeof

    SyncBailHook

    Triggered when evaluating an expression consisting in a typeof of a free variable

    • Hook Parameters: identifier
    • Callback Parameters: expression
    js
    parser.hooks.evaluateTypeof.for('myIdentifier').tap('MyPlugin', expression => {
      /* ... */
      return expressionResult;
    });
    1234

    这会触发 evaluateTypeof 钩子的调用:

    js
    const a = typeof myIdentifier;
    1

    This won't trigger:

    js
    const myIdentifier = 0;
    const b = typeof myIdentifier;
    12
  2. evaluate

    SyncBailHook

    Called when evaluating an expression.

    • Hook parameters: expressionType
    • Callback parameters: expression

    For example:

    index.js

    js
    const a = new String();
    1

    MyPlugin.js

    js
    parser.hooks.evaluate.for('NewExpression').tap('MyPlugin', expression => {
      /* ... */
      return expressionResult;
    });
    1234

    Where the expressions types are:

    • 'ArrowFunctionExpression'
    • 'AssignmentExpression'
    • 'AwaitExpression'
    • 'BinaryExpression'
    • 'CallExpression'
    • 'ClassExpression'
    • 'ConditionalExpression'
    • 'FunctionExpression'
    • 'Identifier'
    • 'LogicalExpression'
    • 'MemberExpression'
    • 'NewExpression'
    • 'ObjectExpression'
    • 'SequenceExpression'
    • 'SpreadElement'
    • 'TaggedTemplateExpression'
    • 'TemplateLiteral'
    • 'ThisExpression'
    • 'UnaryExpression'
    • 'UpdateExpression'
  3. evaluateIdentifier

    SyncBailHook

    Called when evaluating an identifier that is a free variable.

    • Hook Parameters: identifier
    • Callback Parameters: expression
  4. evaluateDefinedIdentifier

    SyncBailHook

    Called when evaluating an identifier that is a defined variable.

    • Hook Parameters: identifier
    • Callback Parameters: expression
  5. evaluateCallExpressionMember

    SyncBailHook

    Called when evaluating a call to a member function of a successfully evaluated expression.

    • Hook Parameters: identifier
    • Callback Parameters: expression param

    This expression will trigger the hook:

    index.js

    js
    const a = expression.myFunc();
    1

    MyPlugin.js

    js
    parser.hooks.evaluateCallExpressionMember.for('myFunc').tap('MyPlugin', (expression, param) => {
      /* ... */
      return expressionResult;
    });
    1234
  6. statement

    SyncBailHook

    General purpose hook that is called for every parsed statement in a code fragment.

    • Callback Parameters: statement
    js
    parser.hooks.statement.tap('MyPlugin', statement => { /* ... */ });
    1

    Where the statement.type could be:

    • 'BlockStatement'
    • 'VariableDeclaration'
    • 'FunctionDeclaration'
    • 'ReturnStatement'
    • 'ClassDeclaration'
    • 'ExpressionStatement'
    • 'ImportDeclaration'
    • 'ExportAllDeclaration'
    • 'ExportDefaultDeclaration'
    • 'ExportNamedDeclaration'
    • 'IfStatement'
    • 'SwitchStatement'
    • 'ForInStatement'
    • 'ForOfStatement'
    • 'ForStatement'
    • 'WhileStatement'
    • 'DoWhileStatement'
    • 'ThrowStatement'
    • 'TryStatement'
    • 'LabeledStatement'
    • 'WithStatement'
  7. statementIf

    SyncBailHook

    Called when parsing an if statement. Same as the statement hook, but triggered only when statement.type == 'IfStatement'.

    • Callback Parameters: statement
  8. label

    SyncBailHook

    Called when parsing statements with a label. Those statements have statement.type === 'LabeledStatement'.

    • Hook Parameters: labelName
    • Callback Parameters: statement
  9. import

    SyncBailHook

    Called for every import statement in a code fragment. The source parameter contains the name of the imported file.

    • Callback Parameters: statement source

    The following import statement will trigger the hook once:

    index.js

    js
    import _ from 'lodash';
    1

    MyPlugin.js

    js
    parser.hooks.import.tap('MyPlugin', (statement, source) => {
      // source == 'lodash'
    });
    123
  10. importSpecifier

    SyncBailHook

    Called for every specifier of every import statement.

    • Callback Parameters: statement source exportName identifierName

    The following import statement will trigger the hook twice:

    index.js

    js
     import _, { has } from 'lodash';
    1

    MyPlugin.js

    js
     parser.hooks.importSpecifier.tap('MyPlugin', (statement, source, exportName, identifierName) => {
       /* First call
         source == 'lodash'
         exportName == 'default'
         identifierName == '_'
       */
       /* Second call
         source == 'lodash'
         exportName == 'has'
         identifierName == 'has'
       */
     });
    123456789101112
  11. export

    SyncBailHook

    Called for every export statement in a code fragment.

    • Callback Parameters: statement
  12. exportImport

    SyncBailHook

    Called for every export-import statement eg: export * from 'otherModule';.

    • Callback Parameters: statement source
  13. exportDeclaration

    SyncBailHook

    Called for every export statement exporting a declaration.

    • Callback Parameters: statement declaration

    Those exports will trigger this hook:

    js
     export const myVar = 'hello'; // also var, let
     export function FunctionName(){}
     export class ClassName {}
    123
  14. exportExpression

    SyncBailHook

    Called for every export statement exporting an expression e.g.export default expression;.

    • Callback Parameters: statement declaration
  15. exportSpecifier

    SyncBailHook

    Called for every specifier of every export statement.

    • Callback Parameters: statement identifierName exportName index
  16. exportImportSpecifier

    SyncBailHook

    Called for every specifier of every export-import statement.

    • Callback Parameters: statement source identifierName exportName index
  17. varDeclaration

    SyncBailHook

    Called when parsing a variable declaration.

    • Callback Parameters: declaration
  18. varDeclarationLet

    SyncBailHook

    Called when parsing a variable declaration defined using let

    • Callback Parameters: declaration
  19. varDeclarationConst

    SyncBailHook

    Called when parsing a variable declaration defined using const

    • Callback Parameters: declaration
  20. varDeclarationVar

    SyncBailHook

    Called when parsing a variable declaration defined using var

    • Callback Parameters: declaration
  21. canRename

    SyncBailHook

    Triggered before renaming an identifier to determine if the renaming is allowed. This is usually used together with the rename hook.

    • Hook Parameters: identifier
    • Callback Parameters: expression
    js
     var a = b;
    
     parser.hooks.canRename.for('b').tap('MyPlugin', expression => {
       // returning true allows renaming
       return true;
     });
    123456
  22. rename

    SyncBailHook

    Triggered when renaming to get the new identifier. This hook will be called only if canRename returns true.

    • Hook Parameters: identifier
    • Callback Parameters: expression
    js
     var a = b;
    
     parser.hooks.rename.for('b').tap('MyPlugin', expression => {});
    123
  23. assigned

    SyncBailHook

    Called when parsing an AssignmentExpression before parsing the assigned expression.

    • Hook Parameters: identifier
    • Callback Parameters: expression
    js
     a += b;
    
     parser.hooks.assigned.for('a').tap('MyPlugin', expression => {
       // this is called before parsing b
     });
    12345
  24. assign

    SyncBailHook

    Called when parsing an AssignmentExpression before parsing the assign expression.

    • Hook Parameters: identifier
    • Callback Parameters: expression
    js
     a += b;
    
     parser.hooks.assigned.for('a').tap('MyPlugin', expression => {
       // this is called before parsing a
     });
    12345
  25. typeof

    SyncBailHook

    Triggered when parsing the typeof of an identifier

    • Hook Parameters: identifier
    • Callback Parameters: expression
  26. call

    SyncBailHook

    Called when parsing a function call.

    • Hook Parameters: identifier
    • Callback Parameters: expression
    js
     eval(/* something */);
    
     parser.hooks.call.for('eval').tap('MyPlugin', expression => {});
    123
  27. callAnyMember

    SyncBailHook

    Triggered when parsing a call to a member function of an object.

    • Hook Parameters: objectIdentifier
    • Callback Parameters: expression
    js
     myObj.anyFunc();
    
     parser.hooks.callAnyMember.for('myObj').tap('MyPlugin', expression => {});
    123
  28. new

    SyncBailHook

    Invoked when parsing a new expression.

    • Hook Parameters: identifier
    • Callback Parameters: expression
    js
     new MyClass();
    
     parser.hooks.new.for('MyClass').tap('MyPlugin', expression => {});
    123
  29. expression

    SyncBailHook

    Called when parsing an expression.

    • Hook Parameters: identifier
    • Callback Parameters: expression
    js
     const a = this;
    
     parser.hooks.expression.for('this').tap('MyPlugin', expression => {});
    123
  30. expressionConditionalOperator

    SyncBailHook

    Called when parsing a ConditionalExpression e.g. condition ? a : b

    • Callback Parameters: expression
  31. program

    SyncBailHook

    Get access to the abstract syntax tree (AST) of a code fragment

    • Parameters: ast comments

Plugin API

插件是 webpack 生态的关键部分, 它为社区用户提供了一种强有力的方式来直接触及 webpack 的编译过程(compilation process)。 插件能够 hook 到每一个编译(compilation)中发出的关键事件中。 在编译的每个阶段中,插件都拥有对 compiler 对象的完全访问能力, 并且在合适的时机,还可以访问当前的 compilation 对象。

Tapable

这个小型库是 webpack 的一个核心工具,但也可用于其他地方, 以提供类似的插件接口。 在 webpack 中的许多对象都扩展自 Tapable 类。 它对外暴露了 taptapAsynctapPromise 等方法, 插件可以使用这些方法向 webpack 中注入自定义构建的步骤,这些步骤将在构建过程中触发。

请查阅文档了解更多知识。 理解上面的的三种 tap 方法, 以及提供这些方法的钩子(hooks)对于编写插件来说是至关重要的。 那些扩展自 Tapable 的对象(例如:compiler), 以及其提供的钩子(hooks)和每个钩子的类型(例如:同步钩子(SyncHook))值得关注。

插件类型

根据使用不同的钩子(hooks)和 tap 方法, 插件可以以多种不同的方式运行。 这个工作方式与 Tapable 提供的钩子(hooks)密切相关。 compiler hooks 分别记录了 Tapable 内在的钩子, 并指出哪些 tap 方法可用。

所以,依赖于使用的 tap 方法的不同, 插件可能会以不同的方式运行。 例如:当你钩入到 编译(compile) 阶段时,只有同步的 tap 方法可以使用。

js
compiler.hooks.compile.tap('MyPlugin', params => {
  console.log('以同步方式触及 compile 钩子。');
});
123

然而,对于可以使用 AsyncHookrun 阶段, 则需使用 tapAsynctapPromise(以及 tap)方法。

js
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 钩子。');
});
123456789101112131415

这些需求(story)的含义在于, 我们可以有多种方式 hook 到 compiler 中,可以让各种插件都以合适的方式去运行。

自定义钩子

为了便于其他插件的编译过程中可以 tap 到,则需要创建一个新的 hook, 我们只需要简单的从 tapablerequire 所需的 hook 类,并创建:

js
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);
1234567

再次声明, 查看 tapable 文档 来了解更多不同的钩子类(hook class),以及它们是如何工作的。

进度报告

插件能够通过 ProgressPlugin 这个在默认情况下将信息打印到标准错误输出(stderr)的插件来进行进度报告。如果想要使用这个功能,只需要在使用 webpack CLI 的时候传入 --progress 参数。

如果想要自定义打印输出,只需要传递不同的参数到 ProgressPluginreportProgress 方法。

如果想要报告进度,插件必须在 tap 到 hook 的时候使用 context: true 选项。

js
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);
});
1234567891011

reportProgress 方法在被调用的时候会传入以下的参数:

js
reportProgress(percentage, ...args);
1
  • 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-resolvetapable 文档。

类型

compiler 类中,提供了三种类型的内置解析器:

  • normal: 通过绝对或相对路径解析模块。
  • context: 在给定的上下文中解析模块。
  • loader: 解析 webpack loader

根据需要,任一个被使用在 compiler 中的内置解析器, 可以通过插件进行定制:

js
compiler.resolverFactory.hooks.resolver.for('[type]').tap('name', resolver => {
  // you can tap into resolver.hooks now
  resolver.hooks.result.tap('MyPlugin', result => {
    return result;
  });
});
123456

其中,[type] 是上述三个解析器之一。

请参阅 enhanced-resolve documentation 以获得钩子的完整列表以及它们的介绍。

配置选项

上述解析器也可以 利用 resolve or resolveLoader 选项,通过配置文件进行定制。这些选项允许 用户可以通过多种选项来更改解析行为,包括 通过解析 plugins

解析器插件,例如:DirectoryNamedPlugin,可以直接引入 在 resolve.plugins,而不是直接在 plugins configuration option 中使用。

请注意,resolve 配置会影响 normal 解析器和 context 解析器,而“ resolveLoader 用于修改 loader 解析器。

0

评论 (0)

取消