跳转到内容

为什么是 Logaria

日志是那种远看简单、近看就别扭的问题。一个 TypeScript 包、CLI 或构建工具只要稍微长大,就会同时面对三种张力:

  • 开发者想在开发时拥有丰富的日志,看到系统在做什么、为什么。
  • 使用者想要生产环境安静、快速、打包产物体积小,没有调试噪音。
  • 库作者希望日志不会让消费者意外——决定可见性的应该是应用,而不是库。

绝大多数日志库都只挑了一边。要么功能齐全但庞大且和框架绑定,要么足够精简却逼你在发布前删掉所有 console.log。归属权问题更是几乎没人解决:决定一条日志是否输出的,是库、应用,还是构建工具?

Logaria 的目标就是用一个小而可预测的答案,把这三种张力一起拆开。

核心想法:让日志消失

核心想法很简单。一个日志库应当让你:

  1. 在库、脚本与应用代码里自由地写日志,全靠一组很小的 API。
  2. 运行时按级别、按组、按消息或按预设规则过滤——切换可见性永远不需要重新编译。
  3. 当被关闭的调用可以被静态证明是死代码时,构建期裁掉它,让生产打包产物保持小巧。

运行时过滤是唯一的真理来源。构建期裁剪是只在能静态证明“此调用永远过不了过滤”的前提下才会执行的优化——绝不靠启发式,也不会破坏行为。

实际效果是:一个调试日志丰富的库可以直接发布,生产打包产物里既没有 console.log 的字符串、也没有未被使用的格式化器调用或字符串字面量。

为什么坚持框架无关

Logaria 刻意不绑定任何框架或打包工具:没有偏爱的框架,没有偏爱的打包工具,也没有为“某个流行选项”留的专属通路。

  • 运行时 就是几个纯函数。可以跑在 Node.js、浏览器、Worker、CLI——任何支持 ESM 的环境。不依赖 DOM、不依赖 Node 专有全局变量、不挂任何元框架的对等依赖。
  • 构建插件基于 unplugin,同一个插件对象暴露 Vite、Rollup、Rolldown、esbuild、webpack、Rspack、Farm 的适配器。
  • 集成方式让框架与工具作者可以注册独立的作用域,不会和应用层冲突——见 作用域集成

CLI 里调用的 createLogger 与 Vite 插件里调用的是同一个。我们会抵制只在某一个框架里成立的功能:如果一个能力可以表达为通用的 Logaria 原语,它属于核心;否则它属于由该生态贡献的预设插件。

为什么强调显式归属

大多数日志库默认有一份全局配置,谁都可以往里写。一旦两个包对“该不该输出某条日志”有分歧,最后调用 configure() 的一方说了算。

Logaria 在这里划了一条硬线:运行时里只有一个默认作用域,且只有一个所有者。这个所有者要么是应用本身(直接调用 setLoggerConfig / resetLoggerConfig),要么是构建插件(把配置作为构建期常量注入)。当插件被安装时,运行时中改写默认作用域的 API 会直接抛错——杜绝插件裁剪出的策略与运行时允许的策略悄悄漂移。

正是这条规则,让库可以安心依赖 Logaria:一个传递依赖没办法悄悄改向或静音你的日志。宿主集成如果需要自己的可见性策略,就通过 logaria/core 注册显式作用域,配置完全独立,永不触碰默认作用域。

为什么裁剪那么保守

构建插件只在能证明以下全部静态事实时才移除某条日志调用:

  • createLoggerlogaria 以原名(无别名)命名导入。
  • maingroup、message 都是字符串字面量。
  • 日志器绑定从未被重新赋值。
  • 这条日志是独立表达式。
  • 插件正在构建上下文运行,且开启了 treeshake: true

任何动态——拼接出来的消息、别名导入、解构出方法——都会留在打包产物中,交给运行时过滤。这是刻意的,而且这场交易并不对称:错过一次移除的代价只是几个字节,而错误移除一次的代价是生产事故现场少了一条本该出现的日志。Logaria 主动规避后者,把前者让出去。

为什么是小而可预测的运行时

再往运行时里加功能其实并不难,难的是“克制不加”。

  • 一个默认作用域,加可选的若干显式作用域。
  • 每个日志器都提供 5 个日志方法(infosuccesswarnerrordebug)——没有为了花哨而发明的额外级别。
  • 不提供传输器、运行时配置的格式化器、异步接收端。Logaria 只往 console 写;需要更多就在应用层包一层。
  • 辅助工具(createElapsedTimerformatErrorMessageformatDebugMessage)放在独立的 logaria/helper 入口,让根入口保持最小化。

它默认也是类型安全的:公共类型由 logaria/types 暴露,预设插件经过类型化,extendsrules 的引用会自动补全并拒绝拼错的标签。由此,API 表面五分钟可读完,离开文档也能回想起来。

让生态成长,而不是让库膨胀

真实项目里有意思的可见性决策几乎不是“显示错误”,而是“在这个子系统变慢时显示它”,或者“当 CI 重跑开发构建时启用这条规则”。要在不让核心变臃肿的前提下支持这种需求,答案是 预设插件:把规则模板与配置打成小巧、可分享的包,业务项目通过 extends 启用,并按项目覆盖。

Logaria 自己的工作是让原语足够锋利;生态的工作是把它们装配成各项目需要的形状。

未来去哪里

Logaria 现在仍然很小,而且会刻意保持这样。运行时保持最小化,插件保持保守,新功能只有在不破坏这两条性质时才会引入。路线图重点在:

  • 给工具链提供更好的“已解析规则”与“裁剪决策”可观察性。
  • 引入更多由生态包贡献的预设模板。
  • 持续打磨插件依赖的静态分析门控的正确性。

如果上述约束正好是你想要的那种日志器,那么 快速开始 就是下一站。

根据 MIT 许可证发布。 (0463eff)