
RolldownlogLevel配置完全指南日志级别过滤机制与onLog拦截实战【免费下载链接】rolldownFast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.项目地址: https://gitcode.com/GitHub_Trending/ro/rolldown本篇技术指南聚焦 Rolldown 构建工具的核心日志配置项logLevel系统讲解其默认行为、四档级别与优先级规则以及被过滤的日志如何影响插件onLog钩子、onLog选项与终端输出。读完本文你将掌握如何精确控制构建日志的输出范围并学会通过onLog与getLogFilter对日志进行二次加工、升降级甚至转为异常从而在大型项目中获得干净可控的构建反馈。一、logLevel是什么默认值与核心语义在 Rolldown 的输入选项Input Options中logLevel用于控制构建过程中的控制台日志输出详细程度。它的官方类型定义位于 packages/rolldown/src/options/input-options.ts/** * Controls the verbosity of console logging during the build. * * {include ./docs/log-level.md} * * default info */ logLevel?: LogLevelOption;根据 log-level.md 的官方说明其核心语义为默认的logLevel为info这意味着info 和 warning 级别的日志会被处理而debug 级别的日志会被吞掉swallowed——它们既不会被传递给插件的onLog钩子也不会被传递给onLog选项更不会被打印到控制台。这是理解整个日志系统的关键起点logLevel不只是控制台开关它会在更早的阶段就决定一条日志是否进入日志管道。二、四档级别与优先级规则从类型定义看Rolldown 提供了完整的四档日志级别。TypeScript 侧定义在 packages/rolldown/src/log/logging.ts/** inline */ export type LogLevel info | debug | warn; /** inline */ export type LogLevelOption LogLevel | silent;其中LogLevel是实际会作为日志等级出现的三种类型而LogLevelOption额外增加了silent完全静默。Rust 核心侧对应的枚举定义在 crates/rolldown_common/src/inner_bundler_options/types/log_level.rs与 JS 侧一一对应pub enum LogLevel { Silent, Warn, #[default] Info, Debug, }优先级数值表Rolldown 用数值化的优先级来判断日志是否通过过滤定义同样位于 logging.ts级别优先级数值含义debug0最低最详细info1常规信息默认过滤阈值warn2警告silent3最高仅作为配置值表示什么都不输出过滤规则为当日志的级别优先级数值 配置的logLevel优先级数值时该日志被过滤。因此logLevel: info默认优先级 0 的debug日志被过滤info1与warn2通过logLevel: warndebug、info均被过滤仅保留warnlogLevel: debug全部级别通过logLevel: silent所有日志均被过滤。注意silent永远不会作为日志的发出级别出现它只用于配置端实现完全静默。Rust 侧的字符串解析在 Rust 侧配置字符串到枚举的转换由FromString实现log_level.rs仅接受silent、warn、info、debug四个取值遇到非法值会直接 panic 提示Invalid log level——这与 JS 侧的类型约束相互印证保证了两端行为一致。三、被过滤的日志去向onLog钩子与onLog选项都收不到原文档特别强调了一个容易踩坑的事实被logLevel过滤掉的日志不仅仅是不打印到控制台而是整个处理管线都不会触及它。具体来说debug 日志在默认配置下有三个到不了的地方插件的onLog钩子Plugin Hook插件无法通过onLog观察或修改被过滤的日志onLog输入选项Input Option用户自定义的全局日志处理器同样收不到控制台最终打印输出中自然也不会出现。这一点在 on-log.md 中也有对应说明如果日志被logLevel选项过滤掉该处理器handler将不会被调用。也就是说默认情况下debug日志会被吞掉。如果默认处理器未被调用该日志也不会被打印到控制台。源码层面的过滤时机过滤发生在日志进入插件分发之前。在 packages/rolldown/src/log/log-handler.ts 中getLogHandler在构造时就直接根据优先级返回空函数export function getLogHandler( level: LogLevel, code: string, logger: LogHandler, pluginName: string, logLevel: LogLevelOption, ): LoggingFunctionWithPosition { if (logLevelPriority[level] logLevelPriority[logLevel]) { return noop; } // ... }也就是说插件上下文中的this.debug等函数在创建时就已经被判定为是否有效若当前logLevel高于 debugthis.debug就是一个noop调用它不会产生任何后续动作。在全局日志分发层 packages/rolldown/src/log/logger.ts 中getLogger同样先做优先级判断再遍历插件的onLog钩子const minimalPriority logLevelPriority[logLevel]; const logger (level: LogLevel, log: RolldownLog, ...) { const logPriority logLevelPriority[level]; if (logPriority minimalPriority) { return; // 直接丢弃不进入任何 onLog 钩子 } // 依次调用各插件的 onLog ... onLog(level, log); // 最终交给全局 onLog 选项或默认打印 };这条调用链清晰地展示了先过滤、后分发的顺序优先级判断是硬门槛被拦下的日志不会惊动任何处理器。四、onLog选项拦截、降级与升级日志当日志通过了logLevel过滤后onLog选项才有机会介入。其类型定义与示例位于 input-options.tsexport default defineConfig({ onLog(level, log, defaultHandler) { if (log.code CIRCULAR_DEPENDENCY) { return; // 忽略循环依赖警告 } if (level warn) { defaultHandler(error, log); // 把其他警告升级为错误 } else { defaultHandler(level, log); // 否则按原级别打印 } } })onLog接收三个参数level日志的当前级别info | debug | warnlog日志对象RolldownLog包含code、message、plugin、id、loc、frame等结构化字段见 logging.tsdefaultHandler默认处理器。只有调用它日志才会被打印到控制台不调用则日志静默丢弃。通过 defaultHandler 改变级别on-log.md 给出了一个非常有用的进阶能力你可以通过用不同级别调用默认处理器来改变日志的级别。使用额外的error级别会将日志变成一个被抛出的错误该错误携带日志的所有属性。这意味着onLog不仅可以吞掉日志还可以降级把warn降为info让 CI 输出更安静升级把info升为warn提升可见度抛错调用defaultHandler(error, log)直接中断构建且错误对象上挂载完整的日志属性code、id、plugin等便于精准定位失败原因。这一机制在 logger.ts 的 getOnLog 中有完整实现当用户传入onLog时内部会把defaultHandler包装为校验级别后再走默认打印逻辑并对error级别直接调用error()抛出。与旧版onwarn的关系onwarn是遗留 API标注deprecated仅拦截 warning 级别官方建议使用onLog以获得对所有日志类型的完整控制。从源码看logger.ts若同时配置了onwarn而没配置onLogwarn级别的日志会交给onwarn处理其余级别直接打印——这是向后兼容的设计。五、插件onLog钩子多插件间的日志接力除了全局onLog选项每个插件还可以声明自己的onLog钩子。日志在到达全局处理器之前会按插件顺序依次经过所有插件的onLog钩子见 logger.ts。值得注意的是plugin-hooks-onlog.md 中明确了几条防循环的规则与其它会为日志附加插件名的钩子不同插件的onLog钩子不会修改日志的属性由onLog钩子产生的日志不会再回传给同一个插件的onLog以避免无限循环若插件 A 的onLog触发了插件 B 的日志该日志也不会再回传给插件 A 的onLog。示例节选自 plugin-hooks-onlog.mdfunction plugin1() { return { name: plugin1, buildStart() { this.info({ message: Hey, pluginCode: SPECIAL_CODE }); }, onLog(level, log) { if (log.plugin plugin1 log.pluginCode SPECIAL_CODE) { this.warn(log); // 转为警告不会回传给自己避免死循环 return false; // 返回 false 终止后续传播 } }, }; }onLog钩子返回false可终止该日志的进一步传递不再进入后续插件的钩子和全局处理器。六、插件上下文this.debug/this.info/this.warn与logLevel的联动插件在构建钩子中可以通过this.debug、this.info、this.warn主动产出日志。它们与logLevel的联动关系体现在 packages/rolldown/src/plugin/minimal-plugin-context.tsthis.debug getLogHandler(LOG_LEVEL_DEBUG, PLUGIN_LOG, onLog, pluginName, logLevel); this.info getLogHandler(LOG_LEVEL_INFO, PLUGIN_LOG, onLog, pluginName, logLevel); this.warn getLogHandler(LOG_LEVEL_WARN, PLUGIN_WARNING, onLog, pluginName, logLevel);三个函数共用getLogHandler但传入的级别常量不同因此同一个logLevel配置下this.debug、this.info、this.warn的生效情况各不相同默认logLevel: info时this.debug(...)调用直接变为noop静默this.info(...)与this.warn(...)正常进入日志管线logLevel: warn时this.info(...)也被静默logLevel: debug时三者全部生效可用于排查深层问题。生成的日志会带上code: PLUGIN_LOG或code: PLUGIN_WARNING并自动附加插件名与位置信息若有pos/loc最终统一走onLog分发。七、getLogFilter复用 CLI 同款过滤语法在自定义onLog时往往需要按日志的code等字段做精确过滤。Rolldown 提供了开箱即用的辅助函数getLogFilterpackages/rolldown/src/get-log-filter.ts语法与 CLI 的日志过滤器完全一致import { defineConfig } from rolldown; import { getLogFilter } from rolldown/getLogFilter; const logFilter getLogFilter([code:FOO, code:BAR]); export default defineConfig({ input: main.js, onLog(level, log, handler) { if (logFilter(log)) { handler(level, log); } } });其语法能力包括精确匹配code:FOO匹配log.code FOO取反以!开头表示排除如!code:BAR与组合用连接多个子过滤条件需全部满足通配符值部分支持*如code:FOO*可匹配FOO1、FOOBAR等多条件或数组中的多个过滤表达式满足其一即可。从源码看get-log-filter.ts过滤器会解析每个表达式为{ inverted, key, parts }key支持点路径如plugin.name匹配时逐段比对RolldownLog的字段实现与 CLI 完全一致的行为。八、从 JS 到 Rust一条日志的完整链路Rolldown 的日志过滤不只是 TS 层的行为而是贯穿整个 JS/Rust 双端架构JS 配置层logLevel与onLog在 input-options.ts 定义经 bindingify-input-options.ts 转换为 NAPI 绑定选项NAPI 绑定层BindingLogLevel枚举定义于 crates/rolldown_binding/src/types/binding_log_level.rs四个变体Silent/Warn/Info/Debug与 JS 端一一对应并通过FromBindingLogLevel转换为核心枚举Rust 核心层rolldown_common::LogLevellog_level.rs作为规范化选项的一部分被构建管线中的各模块读取用于决定哪些日志事件需要上报。例如在模块加载阶段module_task.rs 会依据log_level决定是否产出诊断日志插件上下文的原生侧实现位于 native_plugin_context.rs。两端共享同一套级别语义保证了JS 侧吞掉的 debug 日志Rust 侧同样不会产出。测试侧同样覆盖了相关行为可参考 crates/rolldown/tests/rolldown/plugin/plugin_context/info_warn_debug/mod.rs 中对info/warn/debug三类上下文日志的实际断言。九、实践建议速查场景推荐配置日常构建只看常规信息保持默认logLevel: infoCI 流水线减少噪音logLevel: warn配合onLog吞掉已知噪音码如CIRCULAR_DEPENDENCY排查深层依赖问题logLevel: debug此时this.debug日志也会输出完全静默logLevel: silent把警告升级为构建失败onLog中defaultHandler(error, log)最后提醒一点由于过滤发生在分发之前想通过onLog捕获 debug 日志必须先调低logLevel如设为debug否则onLog根本不会收到这些日志——这是logLevel与onLog协作时最容易忽略的细节。【免费下载链接】rolldownFast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.项目地址: https://gitcode.com/GitHub_Trending/ro/rolldown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考