CC 4.0 许可

本节内容源自以下链接的内容,并受 CC BY 4.0 许可。

除非另有说明,否则以下内容可以被认为是基于原始内容的修改和删除的结果。

日志记录器

日志输出是向最终用户显示消息的另一种方式。

Rspack 日志记录器可供 加载器插件 使用。它作为 统计信息 的一部分发出,并由用户在 rspack 配置 中配置。

Rspack 中自定义日志记录 API 的优势

  • 配置日志显示级别的通用位置
  • 日志输出可作为 stats.json 的一部分导出
  • 统计信息预设影响日志输出
  • 插件可以影响日志捕获和显示级别
  • 当使用多个插件和加载器时,它们使用通用的日志记录解决方案
  • Rspack 的 CLI、UI 工具可以选择不同的日志显示方式
  • Rspack 核心可以发出日志输出,例如计时数据

通过引入 Rspack 日志记录 API,我们希望统一 Rspack 插件和加载器发出日志的方式,并允许更好的方式来检查构建问题。集成的日志记录解决方案通过改善开发人员的开发体验来支持插件和加载器开发人员。为非 CLI Rspack 解决方案(如仪表板或其他 UI)铺平了道路。

避免日志中的噪声

避免日志中的噪声!

请记住,多个插件和加载器一起使用。加载器通常处理多个文件,并为每个文件调用。选择尽可能低的日志级别以使日志输出信息丰富。

示例

在插件中

有两种类型的日志记录方法

  1. compilation.getLogger:内容将存储在统计信息中,当日志记录与编译相关时使用此方法。
  2. compiler.getInfrastructureLogger:内容不会被存储,当日志记录在编译周期之外使用时使用此方法。

您可以在您的插件中像下面这样使用它们

MyPlugin.js
const PLUGIN_NAME = 'my-plugin';
export class MyRspackPlugin {
  apply(compiler) {
    // access Logger from compiler
    const logger = compiler.getInfrastructureLogger(PLUGIN_NAME);
    logger.log('log from compiler');

    compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
      // access Logger from compilation
      const logger = compilation.getLogger(PLUGIN_NAME);
      logger.info('log from compilation');
    });
  }
}

在加载器中

您可以从加载器上下文中获取日志记录器,如下所示

MyLoader.js
module.exports = function (source) {
  // access Logger from loader
  const logger = this.getLogger('my-loader');
  logger.info('hello Logger');
  return source;
};

日志记录器 API

基本 API

类型: (...args: any[]): void;

方法按日志级别从高到低排列

  • error:用于错误消息。
  • warn:用于警告。
  • info:用于重要信息消息。这些消息默认显示。仅在用户真正需要看到的消息时使用此方法。
  • log:用于不重要的信息消息。这些消息仅在用户选择查看它们时显示。
  • debug:用于调试信息。这些消息仅在用户选择查看特定模块的调试日志时显示。

在使用 compilation.getLogger 时,输出级别可以通过 stats.loggingstats.loggingDebug 控制

rspack.config.js
module.exports = {
  plugins: [{
    apply(compiler) {
      compiler.hooks.thisCompilation.tap("test plugin", compilation => {
        const logger = compilation.getLogger("TEST");
        logger.error("I am an error");
        logger.warn("I am a warning");
        logger.info("I am an information");
        logger.log("I am a log");
        logger.debug("I am a debug log");
      });
    }
  }],
  stats: {
    logging: "verbose",
    loggingDebug: true
  },
};
输出
asset main.js 264 bytes [emitted] (name: main)
runtime modules 124 bytes 2 modules
./index.js 15 bytes [built] [code generated]

DEBUG LOG from TEST
<e> I am an error
<w> I am a warning
<i> I am an information
    I am a log
    I am a debug log

在使用 compiler.getInfrastructureLogger 时,输出级别可以通过 infrastructureLogging.levelinfrastructureLogging.debug 控制

rspack.config.js
module.exports = {
  plugins: [{
    apply(compiler) {
      compiler.hooks.thisCompilation.tap("test plugin", compilation => {
        const logger = compiler.getInfrastructureLogger("TEST");
        logger.error("I am an error");
        logger.warn("I am a warning");
        logger.info("I am an information");
        logger.log("I am a log");
        logger.debug("I am a debug log");
      });
    }
  }],
  infrastructureLogging: {
    level: "verbose",
    debug: true
  },
};
输出
<e> [TEST] I am an error
<w> [TEST] I am a warning
<i> [TEST] I am an information
    [TEST] I am a log
    [TEST] I am a debug log
Rspack compiled successfully in 49 ms

断言

断言为假时显示错误。

  • 级别: error
  • 类型:: assert(assertion: any, ...args: any[]): void;
rspack.config.js
logger.assert(false, "I am an assert error");
logger.assert(true, "Never displayed");
输出
LOG from TEST
<e> I am an assert error

状态

显示进度状态信息,如果存在 console.status,则使用它,否则回退到 `console.info。

  • 级别: info
  • 类型: status(...args: any[]): void
rspack.config.js
logger.status("status info");
输出
[TEST] status info

跟踪

显示堆栈跟踪,仅在使用编译日志记录器时可用,并且还需要启用 stats.loggingTrace

  • 级别: debug
  • 类型: trace(): void
rspack.config.js
logger.trace();
输出
DEBUG LOG from TEST
    Trace
|     at Object.fn
|     at SyncHook.callAsyncStageRange

清除

清除所有日志,就像 console.clear() 一样。

  • 级别: log
  • 类型: clear(): void;
rspack.config.js
logger.debug("not displayed");
logger.clear();
logger.debug("will displayed");
输出
[TEST] will displayed

组 API

包含以下方法

  • group(...args: any[]): void:用于分组消息。以折叠的方式显示,就像 logger.log 一样。
  • groupEnd(...args: any[]): void:用于结束日志记录组。
  • groupCollapsed(...args: any[]): void:用于将消息分组在一起。以折叠的方式显示,就像 logger.log 一样。当日志级别设置为 'verbose''debug' 时,以展开的方式显示。
rspack.config.js
logger.group("Group");
logger.info("Info");
logger.log("Log");
logger.debug("Debug");
logger.groupCollapsed("Collapsed group");
logger.log("Log inside collapsed group");
logger.group("Inner group");
logger.log("Inner inner message");
logger.groupEnd();
logger.groupEnd();
logger.log("Log");
logger.groupEnd();
logger.log("End");
输出
<-> [TEST] Group
  <i> [TEST] Info
      [TEST] Log
      [TEST] Debug
  <-> [TEST] Collapsed group
        [TEST] Log inside collapsed group
    <-> [TEST] Inner group
          [TEST] Inner inner message
      [TEST] Log
    [TEST] End

计时 API

包含以下方法

  • time(label: any): void:用于启动计时器。
  • timeLog(label: any): void:记录时间差,不结束计时器。
  • timeEnd(label: any): void:用于结束计时器并记录时间差。
  • timeAggregate(label: any): void:用于聚合捕获时间差。
  • timeAggregateEnd(label: any): void:用于结束聚合捕获并记录总时间差。
rspack.config.js
const wait = time => new Promise(resolve => setTimeout(resolve, time))
logger.time("normal");
await wait(100);
logger.timeLog("normal");
await wait(100);
logger.timeEnd("normal");

for (let i = 10;i--;) {
logger.time("aggregate")
await wait(i \* 10);
logger.timeAggregate("aggregate")
}
logger.timeAggregateEnd("aggregate")
输出
<t> [TEST] normal: 101.091167 ms
<t> [TEST] normal: 202.565 ms
<t> [TEST] aggregate: 460.416124 ms

分析 API

包含以下方法

  • profile(label: any): void:用于开始捕获分析。当支持时委托给 console.profile
  • profileEnd(label: any): void:用于结束捕获分析。当支持时委托给 console.profileEnd

子日志记录器

您也可以使用 logger.getChildLogger() 创建子日志记录器。子日志记录器具有相同的方法。

rspack.config.js
const logger = compiler.getInfrastructureLogger("TEST");
logger.info("logger info");
const childLogger = logger.getChildLogger("CHILD");
childLogger.info("child logger info");
输出
<i> [TEST] logger info
<i> [TEST/CHILD] child logger info