npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@done-coding/output-node

v0.1.2

Published

node相关输出

Readme

@done-coding/output-node

NPM Version License Codecov

Node.js 环境下的同构输出工具包,基于 @done-coding/output-core 核心包构建,提供控制台输出和日志文件输出功能。

功能特性

  • 🎨 丰富的控制台输出 - 支持多种输出类型和颜色配置
  • 📝 专业的日志文件输出 - 基于 pino 的高性能日志记录
  • 🔄 混合类型接口 - 支持函数调用和属性链式调用两种方式
  • 🛡️ 临终落盘保护 - 使用 signal-exit 库实现非侵入式进程退出监听
  • 🚨 框架兼容 - 与 NestJS 等现代框架的关闭钩子完美兼容
  • 高性能 - 异步日志写入,可配置缓冲区大小
  • 🔧 完整的错误处理 - 输入验证、配置验证、文件权限检查
  • 📦 完整类型支持 - 100% TypeScript 类型定义和类型推导
  • 🔇 动态静默控制 - 支持运行时动态控制输出静默,基于类型的条件静默
  • 🎯 智能切换同步 - 支持控制台和日志文件之间的智能切换和同步
  • 📋 TABLE 类型特殊处理 - 智能表格数据展示和 JSON 序列化

快速开始

安装

npm install @done-coding/output-node
# 或
yarn add @done-coding/output-node
# 或
pnpm add @done-coding/output-node

最小可用示例

import {
  createOutputConsole,
  createOutputLogFile,
} from "@done-coding/output-node";

// 创建控制台输出
const output = createOutputConsole();
output.info("Hello World");
output.success("操作成功");

// 创建日志文件输出
const logger = createOutputLogFile({ logFilePath: "app.log" });
logger.info("应用启动");
logger.error("发生错误");

架构设计

分层架构

┌─────────────────────────────────────┐
│        Node.js 适配包层              │
│   (@done-coding/output-node)        │
├─────────────────────────────────────┤
│            核心包层                   │
│     (@done-coding/output-core)      │
├─────────────────────────────────────┤
│           驱动实现层                  │
│   (console.log, pino, chalk, etc.)  │
└─────────────────────────────────────┘

设计原则

  1. 自动化驱动 - 自动创建和管理输出驱动实现
  2. 零配置 - 提供合理的默认配置,开箱即用
  3. 高性能 - 异步日志写入,可配置缓冲区
  4. 安全可靠 - 完整的错误处理和防御性编程
  5. 框架兼容 - 与现代框架(NestJS、Express 等)完美兼容
  6. 极简 API - 最少化的配置参数,易于使用

内置实现

控制台输出驱动

  • 基础实现: console.log + chalk 颜色支持
  • 颜色配置: 支持自定义颜色映射和禁用颜色
  • TABLE 类型: 自动调用 console.table 进行表格展示
  • 错误处理: 颜色格式化失败时自动降级到无颜色输出

日志文件输出驱动

  • 基础实现: pino + sonic-boom 高性能日志写入
  • 缓冲机制: 可配置缓冲区大小,支持同步/异步写入
  • 临终保护: 使用 signal-exit 实现非侵入式进程退出监听
  • 内置控制台: 自动提供 outputConsoleFn,基于 pino 输出到控制台

API 文档

createOutputConsole

创建控制台输出实例。

签名:

function createOutputConsole(
  options?: CreateOutputConsoleOptions,
): OutputConsole;

参数:

| 参数 | 类型 | 默认值 | 说明 | | ----------------------- | ------------------------------------- | ------ | -------------------- | | options.isSilent | (type) => boolean | - | 动态静默控制函数 | | options.enableColor | boolean | true | 是否启用颜色输出 | | options.colorMap | Record<OutputConsoleTypeEnum, string> | - | 自定义颜色映射 | | options.isSwitchLogFile | (type) => boolean | - | 切换到日志文件的条件 | | options.isSyncToLogFile | (type) => boolean | - | 同步到日志文件的条件 | | options.outputFileFn | OutputConsoleRaw | - | 日志文件输出函数 |

返回值: OutputConsole 混合类型实例

示例:

const output = createOutputConsole({
  enableColor: true,
  isSilent: (type) =>
    type === OutputConsoleTypeEnum.DEBUG && !process.env.DEBUG,
});

output.info("信息");
output.success("成功");
output.error("错误");

createOutputLogFile

创建日志文件输出实例。

签名:

function createOutputLogFile(
  options: CreateOutputLogFileOptions,
): OutputLogFile;

参数:

| 参数 | 类型 | 默认值 | 说明 | | ----------------------- | ----------------- | ------ | -------------------- | | options.logFilePath | string | - | 日志文件路径(必传) | | options.isSilent | (type) => boolean | - | 动态静默控制函数 | | options.sync | boolean | false | 是否同步写入 | | options.bufferSize | number | 4096 | 缓冲区大小(字节) | | options.isSwitchConsole | (type) => boolean | - | 切换到控制台的条件 |

返回值: OutputLogFile 混合类型实例

示例:

const logger = createOutputLogFile({
  logFilePath: "app.log",
  sync: false,
  bufferSize: 8192,
});

logger.info("应用启动");
logger.error("数据库连接失败");

输出类型枚举

OutputConsoleTypeEnum

| 值 | 名称 | 说明 | | --- | ------- | -------- | | 31 | DEBUG | 调试信息 | | 32 | SKIP | 跳过 | | 33 | INFO | 提示信息 | | 34 | TABLE | 表格 | | 35 | STAGE | 步骤 | | 36 | SUCCESS | 成功 | | 37 | WARN | 警告 | | 38 | ERROR | 错误 |

OutputLogFileTypeEnum

| 值 | 名称 | 说明 | | --- | ----- | ------------ | | 10 | TRACE | 跟踪级别 | | 20 | DEBUG | 调试级别 | | 30 | INFO | 信息级别 | | 40 | WARN | 警告级别 | | 50 | ERROR | 错误级别 | | 60 | FATAL | 致命错误级别 |

进阶使用

动态静默控制

import {
  createOutputConsole,
  OutputConsoleTypeEnum,
} from "@done-coding/output-node";

const output = createOutputConsole({
  // 动态控制静默:只在调试模式下显示 DEBUG 信息
  isSilent: (type) => {
    if (type === OutputConsoleTypeEnum.DEBUG) {
      return !process.env.DEBUG;
    }
    // 生产环境下静默所有 SKIP 类型
    if (type === OutputConsoleTypeEnum.SKIP) {
      return process.env.NODE_ENV === "production";
    }
    return false;
  },
});

output.debug("调试信息"); // 只在 DEBUG=true 时显示
output.skip("跳过信息"); // 生产环境下不显示
output.info("普通信息"); // 总是显示

切换和同步逻辑

import {
  createOutputConsole,
  createOutputLogFile,
  OutputConsoleTypeEnum,
} from "@done-coding/output-node";

// 创建日志文件输出
const fileLogger = createOutputLogFile({ logFilePath: "error.log" });

// 创建带有切换和同步逻辑的控制台输出
const output = createOutputConsole({
  enableColor: true,
  // 错误级别切换到日志文件(不在控制台显示)
  isSwitchLogFile: (type) => type === OutputConsoleTypeEnum.ERROR,
  // 警告级别同步到日志文件(控制台和文件都显示)
  isSyncToLogFile: (type) => type === OutputConsoleTypeEnum.WARN,
  outputFileFn: (type, ...messages) => {
    // 将控制台类型映射到日志文件类型并输出
    fileLogger(type, ...messages);
  },
});

output.info("普通信息"); // 只在控制台显示
output.warn("警告信息"); // 控制台和文件都显示
output.error("错误信息"); // 只在文件中记录

自定义颜色配置

import {
  createOutputConsole,
  OutputConsoleTypeEnum,
} from "@done-coding/output-node";

const output = createOutputConsole({
  enableColor: true,
  colorMap: {
    [OutputConsoleTypeEnum.INFO]: "blue",
    [OutputConsoleTypeEnum.SUCCESS]: "greenBright",
    [OutputConsoleTypeEnum.ERROR]: "redBright",
    [OutputConsoleTypeEnum.WARN]: "yellow",
  },
});

缓冲区配置

// 异步写入模式(推荐用于生产环境)
const logger = createOutputLogFile({
  logFilePath: "app.log",
  sync: false, // 异步写入
  bufferSize: 8192, // 8KB 缓冲区
});

// 同步写入模式(性能较低但数据安全性更高)
const syncLogger = createOutputLogFile({
  logFilePath: "critical.log",
  sync: true, // 同步写入
  bufferSize: 1024, // 较小的缓冲区
});

TABLE 类型处理

const output = createOutputConsole();

// 数组表格
output.table([
  { name: "张三", age: 25, city: "北京" },
  { name: "李四", age: 30, city: "上海" },
]);

// 对象表格
output.table({
  total: 100,
  success: 95,
  failed: 5,
});

临终落盘保护

import { createOutputLogFile } from "@done-coding/output-node";

// 创建日志实例会自动注册 signal-exit 监听器
const logger = createOutputLogFile({ logFilePath: "app.log" });

logger.info("应用启动");

// 当收到 SIGINT 或 SIGTERM 信号时,会自动刷新日志缓冲区
// 与 NestJS 等现代框架的关闭钩子完美兼容

开发与测试

测试覆盖率

  • 语句覆盖率: 99.35%
  • 分支覆盖率: 97.63%
  • 函数覆盖率: 97.5%
  • 行覆盖率: 99.35%
  • 测试数量: 181 个测试,全部通过

本地开发

# 克隆仓库
git clone https://github.com/done-coding/output-node.git
cd output-node

# 安装依赖
pnpm install

# 开发模式
pnpm dev

# 运行测试
pnpm test

# 构建
pnpm build

贡献流程

  1. Fork 本仓库
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启 Pull Request

常见问题

Q: 为什么 Node 包不需要传入 outputImpl 参数?

A: Node 包自动提供了基于 console.log + chalkpino 的输出实现,用户无需手动创建和传入 outputImpl。这是 Node 包相比 Core 包的主要优势。

Q: 如何在生产环境中优化日志性能?

A: 使用异步写入模式(sync: false),适当增加缓冲区大小(如 8KB 或 16KB),并合理配置 isSilent 函数来过滤不必要的日志输出。

Q: 如何在 NestJS 中使用?

A: 可以在 NestJS 的 OnModuleInit 和 OnApplicationShutdown 钩子中使用,临终落盘保护会自动处理进程退出时的日志刷新。

Q: 日志文件路径可以是相对路径吗?

A: 可以,相对路径会相对于当前工作目录。建议使用绝对路径以避免歧义。

Q: 如何禁用颜色输出?

A: 设置 enableColor: false 即可。

Q: 缓冲区大小应该设置多少?

A: 默认 4KB 适合大多数场景。高频输出可以增加到 8KB 或 16KB,低频输出可以减少到 1KB。

Q: 支持哪些 Node.js 版本?

A: 支持 Node.js 14+,推荐使用 Node.js 16+。

Q: 如何处理日志文件权限错误?

A: 包会自动捕获权限错误并静默处理,日志会降级到内存缓冲。建议检查文件路径和目录权限。

许可证

MIT