@done-coding/output-node 0.1.0-alpha.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,22 +1,28 @@
1
1
  # @done-coding/output-node
2
2
 
3
+ [![NPM Version](https://img.shields.io/npm/v/@done-coding/output-node)](https://www.npmjs.com/package/@done-coding/output-node)
4
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
+ [![Codecov](https://img.shields.io/codecov/c/github/done-coding/output-node)](https://codecov.io/gh/done-coding/output-node)
6
+
3
7
  Node.js 环境下的同构输出工具包,基于 @done-coding/output-core 核心包构建,提供控制台输出和日志文件输出功能。
4
8
 
5
- ## 特性
9
+ ## 功能特性
6
10
 
7
11
  - 🎨 **丰富的控制台输出** - 支持多种输出类型和颜色配置
8
12
  - 📝 **专业的日志文件输出** - 基于 pino 的高性能日志记录
9
13
  - 🔄 **混合类型接口** - 支持函数调用和属性链式调用两种方式
10
14
  - 🛡️ **临终落盘保护** - 使用 signal-exit 库实现非侵入式进程退出监听
11
- - 🚨 **信号监听** - 与 NestJS 等现代框架完美兼容
12
- - ⚡ **高性能** - 异步日志写入,预计算枚举映射
15
+ - 🚨 **框架兼容** - 与 NestJS 等现代框架的关闭钩子完美兼容
16
+ - ⚡ **高性能** - 异步日志写入,可配置缓冲区大小
13
17
  - 🔧 **完整的错误处理** - 输入验证、配置验证、文件权限检查
14
- - 📦 **TypeScript 支持** - 完整的类型定义和类型推导
15
- - 🎯 **输出模式切换** - 支持控制台和日志文件之间的智能切换
18
+ - 📦 **完整类型支持** - 100% TypeScript 类型定义和类型推导
19
+ - 🔇 **动态静默控制** - 支持运行时动态控制输出静默,基于类型的条件静默
20
+ - 🎯 **智能切换同步** - 支持控制台和日志文件之间的智能切换和同步
16
21
  - 📋 **TABLE 类型特殊处理** - 智能表格数据展示和 JSON 序列化
17
- - 🔧 **常量集中管理** - 所有配置参数的默认值统一管理
18
22
 
19
- ## 安装
23
+ ## 快速开始
24
+
25
+ ### 安装
20
26
 
21
27
  ```bash
22
28
  npm install @done-coding/output-node
@@ -26,247 +32,228 @@ yarn add @done-coding/output-node
26
32
  pnpm add @done-coding/output-node
27
33
  ```
28
34
 
29
- ## 快速开始
30
-
31
- ### 控制台输出
35
+ ### 最小可用示例
32
36
 
33
37
  ```typescript
34
38
  import {
35
39
  createOutputConsole,
36
- OutputConsoleTypeEnum,
37
- } from "@done-coding/output-node";
38
-
39
- // 创建控制台输出实例
40
- const outputConsole = createOutputConsole({
41
- enableColor: true, // 启用颜色输出
42
- silent: false, // 非静默模式
43
- });
44
-
45
- // 函数调用方式
46
- outputConsole(OutputConsoleTypeEnum.INFO, "这是一条信息");
47
- outputConsole(OutputConsoleTypeEnum.SUCCESS, "操作成功!");
48
- outputConsole(OutputConsoleTypeEnum.ERROR, "发生错误");
49
-
50
- // 属性链式调用方式(推荐)
51
- outputConsole.info("这是一条信息");
52
- outputConsole.success("操作成功!");
53
- outputConsole.error("发生错误");
54
- outputConsole.warn("这是一个警告");
55
- outputConsole.debug("调试信息");
56
- outputConsole.stage("当前步骤");
57
- outputConsole.skip("跳过此步骤");
58
-
59
- // TABLE 类型特殊处理
60
- outputConsole.table({
61
- name: "张三",
62
- age: 25,
63
- city: "北京",
64
- });
65
- ```
66
-
67
- ### 日志文件输出
68
-
69
- ```typescript
70
- import {
71
40
  createOutputLogFile,
72
- OutputLogFileTypeEnum,
73
41
  } from "@done-coding/output-node";
74
42
 
75
- // 创建日志文件输出实例
76
- const logger = createOutputLogFile({
77
- logFilePath: "app.log", // 可选,默认自动生成
78
- prettyPrint: false, // 是否美化输出
79
- silent: false, // 非静默模式
80
- sync: false, // 异步写入(推荐)
81
- bufferSize: 4096, // 缓冲区大小
82
- });
43
+ // 创建控制台输出
44
+ const output = createOutputConsole();
45
+ output.info("Hello World");
46
+ output.success("操作成功");
83
47
 
84
- // 函数调用方式
85
- logger(OutputLogFileTypeEnum.INFO, "应用启动");
86
- logger(OutputLogFileTypeEnum.ERROR, "数据库连接失败");
87
-
88
- // 属性链式调用方式(推荐)
48
+ // 创建日志文件输出
49
+ const logger = createOutputLogFile({ logFilePath: "app.log" });
89
50
  logger.info("应用启动");
90
- logger.warn("内存使用率较高");
91
- logger.error("数据库连接失败");
92
- logger.debug("调试信息");
93
- logger.trace("详细跟踪信息");
94
- logger.fatal("致命错误,应用即将退出");
51
+ logger.error("发生错误");
95
52
  ```
96
53
 
97
- ### 输出模式切换
54
+ ## 架构设计
98
55
 
99
- ```typescript
100
- import { outputLogFile } from "@done-coding/output-node";
56
+ ### 分层架构
101
57
 
102
- // 支持输出到控制台
103
- const logger1 = outputLogFile({
104
- outputToConsole: true, // 输出到控制台
105
- prettyPrint: true, // 美化输出
106
- });
107
-
108
- // 支持输出到文件
109
- const logger2 = outputLogFile({
110
- outputToConsole: false, // 输出到文件
111
- logFilePath: "app.log",
112
- sync: true, // 同步写入
113
- });
58
+ ```
59
+ ┌─────────────────────────────────────┐
60
+ │ Node.js 适配包层 │
61
+ │ (@done-coding/output-node) │
62
+ ├─────────────────────────────────────┤
63
+ │ 核心包层 │
64
+ │ (@done-coding/output-core) │
65
+ ├─────────────────────────────────────┤
66
+ │ 驱动实现层 │
67
+ │ (console.log, pino, chalk, etc.) │
68
+ └─────────────────────────────────────┘
114
69
  ```
115
70
 
116
- ### 切换和同步逻辑
71
+ ### 设计原则
117
72
 
118
- ```typescript
119
- import {
120
- createOutputConsole,
121
- createOutputLogFile,
122
- OutputConsoleTypeEnum,
123
- } from "@done-coding/output-node";
73
+ 1. **自动化驱动** - 自动创建和管理输出驱动实现
74
+ 2. **零配置** - 提供合理的默认配置,开箱即用
75
+ 3. **高性能** - 异步日志写入,可配置缓冲区
76
+ 4. **安全可靠** - 完整的错误处理和防御性编程
77
+ 5. **框架兼容** - 与现代框架(NestJS、Express 等)完美兼容
78
+ 6. **极简 API** - 最少化的配置参数,易于使用
124
79
 
125
- // 创建日志文件输出实例
126
- const fileLogger = createOutputLogFile({ logFilePath: "error.log" });
80
+ ### 内置实现
127
81
 
128
- // 创建带有切换和同步逻辑的控制台输出
129
- const outputConsole = createOutputConsole({
130
- enableColor: true,
131
- // 错误级别切换到日志文件(不在控制台显示)
132
- isSwitchLogFile: (type) => type === OutputConsoleTypeEnum.ERROR,
133
- // 警告级别同步到日志文件(控制台和文件都显示)
134
- isSyncToLogFile: (type) => type === OutputConsoleTypeEnum.WARN,
135
- // 指定日志文件输出函数
136
- outputFileFn: fileLogger,
137
- });
82
+ #### 控制台输出驱动
138
83
 
139
- outputConsole.info("普通信息"); // 只在控制台显示
140
- outputConsole.warn("警告信息"); // 控制台和文件都显示
141
- outputConsole.error("错误信息"); // 只在文件中记录
142
- ```
84
+ - **基础实现**: `console.log` + `chalk` 颜色支持
85
+ - **颜色配置**: 支持自定义颜色映射和禁用颜色
86
+ - **TABLE 类型**: 自动调用 `console.table` 进行表格展示
87
+ - **错误处理**: 颜色格式化失败时自动降级到无颜色输出
88
+
89
+ #### 日志文件输出驱动
90
+
91
+ - **基础实现**: `pino` + `sonic-boom` 高性能日志写入
92
+ - **缓冲机制**: 可配置缓冲区大小,支持同步/异步写入
93
+ - **临终保护**: 使用 `signal-exit` 实现非侵入式进程退出监听
94
+ - **内置控制台**: 自动提供 `outputConsoleFn`,基于 pino 输出到控制台
143
95
 
144
96
  ## API 文档
145
97
 
146
- ### createOutputConsole(options?)
98
+ ### createOutputConsole
147
99
 
148
100
  创建控制台输出实例。
149
101
 
150
- #### 参数
102
+ **签名:**
151
103
 
152
- - `options` (可选) - 配置选项
153
- - `silent?: boolean` - 是否静默模式,默认 `false`
154
- - `enableColor?: boolean` - 是否启用颜色输出,默认 `true`
155
- - `colorMap?: Record<OutputConsoleTypeEnum, string>` - 自定义颜色映射
156
- - `isSwitchLogFile?: (type: OutputConsoleTypeEnum) => boolean` - 切换到日志文件的条件函数
157
- - `isSyncToLogFile?: (type: OutputConsoleTypeEnum) => boolean` - 同步到日志文件的条件函数
158
- - `outputFileFn?: OutputLogFile` - 日志文件输出函数
104
+ ```typescript
105
+ function createOutputConsole(
106
+ options?: CreateOutputConsoleOptions,
107
+ ): OutputConsole;
108
+ ```
159
109
 
160
- #### 返回值
110
+ **参数:**
161
111
 
162
- 返回 `OutputConsole` 混合类型实例,支持:
112
+ | 参数 | 类型 | 默认值 | 说明 |
113
+ | ----------------------- | ------------------------------------- | ------ | -------------------- |
114
+ | options.isSilent | (type) => boolean | - | 动态静默控制函数 |
115
+ | options.enableColor | boolean | true | 是否启用颜色输出 |
116
+ | options.colorMap | Record<OutputConsoleTypeEnum, string> | - | 自定义颜色映射 |
117
+ | options.isSwitchLogFile | (type) => boolean | - | 切换到日志文件的条件 |
118
+ | options.isSyncToLogFile | (type) => boolean | - | 同步到日志文件的条件 |
119
+ | options.outputFileFn | OutputConsoleRaw | - | 日志文件输出函数 |
163
120
 
164
- - 函数调用:`output(type, ...messages)`
165
- - 属性调用:`output.info(...messages)`、`output.error(...messages)` 等
121
+ **返回值:** OutputConsole 混合类型实例
166
122
 
167
- ### createOutputLogFile(options?)
123
+ **示例:**
168
124
 
169
- 创建日志文件输出实例。
125
+ ```typescript
126
+ const output = createOutputConsole({
127
+ enableColor: true,
128
+ isSilent: (type) =>
129
+ type === OutputConsoleTypeEnum.DEBUG && !process.env.DEBUG,
130
+ });
170
131
 
171
- #### 参数
132
+ output.info("信息");
133
+ output.success("成功");
134
+ output.error("错误");
135
+ ```
172
136
 
173
- - `options` (可选) - 配置选项
174
- - `silent?: boolean` - 是否静默模式,默认 `false`
175
- - `logFilePath?: string` - 日志文件路径,默认自动生成
176
- - `prettyPrint?: boolean` - 是否启用美化输出,默认 `false`
177
- - `sync?: boolean` - 是否同步写入,默认 `false`
178
- - `bufferSize?: number` - 缓冲区大小,默认 `4096`
137
+ ### createOutputLogFile
179
138
 
180
- #### 返回值
139
+ 创建日志文件输出实例。
181
140
 
182
- 返回 `OutputLogFile` 混合类型实例,支持:
141
+ **签名:**
183
142
 
184
- - 函数调用:`logger(type, ...messages)`
185
- - 属性调用:`logger.info(...messages)`、`logger.error(...messages)` 等
143
+ ```typescript
144
+ function createOutputLogFile(
145
+ options: CreateOutputLogFileOptions,
146
+ ): OutputLogFile;
147
+ ```
186
148
 
187
- ### outputLogFile(options?)
149
+ **参数:**
188
150
 
189
- 创建支持输出模式切换的日志实例。
151
+ | 参数 | 类型 | 默认值 | 说明 |
152
+ | ----------------------- | ----------------- | ------ | -------------------- |
153
+ | options.logFilePath | string | - | 日志文件路径(必传) |
154
+ | options.isSilent | (type) => boolean | - | 动态静默控制函数 |
155
+ | options.sync | boolean | false | 是否同步写入 |
156
+ | options.bufferSize | number | 4096 | 缓冲区大小(字节) |
157
+ | options.isSwitchConsole | (type) => boolean | - | 切换到控制台的条件 |
190
158
 
191
- #### 参数
159
+ **返回值:** OutputLogFile 混合类型实例
192
160
 
193
- - `options` (可选) - 配置选项
194
- - `outputToConsole?: boolean` - 是否输出到控制台,默认 `false`
195
- - `prettyPrint?: boolean` - 是否美化输出,默认 `false`
196
- - `logFilePath?: string` - 日志文件路径(当 `outputToConsole` 为 `false` 时)
197
- - `sync?: boolean` - 是否同步写入,默认 `false`
198
- - `bufferSize?: number` - 缓冲区大小,默认 `4096`
161
+ **示例:**
162
+
163
+ ```typescript
164
+ const logger = createOutputLogFile({
165
+ logFilePath: "app.log",
166
+ sync: false,
167
+ bufferSize: 8192,
168
+ });
169
+
170
+ logger.info("应用启动");
171
+ logger.error("数据库连接失败");
172
+ ```
199
173
 
200
174
  ### 输出类型枚举
201
175
 
202
176
  #### OutputConsoleTypeEnum
203
177
 
204
- 控制台输出类型枚举:
205
-
206
- ```typescript
207
- enum OutputConsoleTypeEnum {
208
- DEBUG = 31, // 调试信息
209
- SKIP = 32, // 跳过
210
- INFO = 33, // 提示信息
211
- TABLE = 34, // 表格
212
- STAGE = 35, // 步骤
213
- SUCCESS = 36, // 成功
214
- WARN = 37, // 警告
215
- ERROR = 38, // 错误
216
- }
217
- ```
178
+ | 值 | 名称 | 说明 |
179
+ | --- | ------- | -------- |
180
+ | 31 | DEBUG | 调试信息 |
181
+ | 32 | SKIP | 跳过 |
182
+ | 33 | INFO | 提示信息 |
183
+ | 34 | TABLE | 表格 |
184
+ | 35 | STAGE | 步骤 |
185
+ | 36 | SUCCESS | 成功 |
186
+ | 37 | WARN | 警告 |
187
+ | 38 | ERROR | 错误 |
218
188
 
219
189
  #### OutputLogFileTypeEnum
220
190
 
221
- 日志文件输出类型枚举(对齐 Pino 标准):
191
+ | 值 | 名称 | 说明 |
192
+ | --- | ----- | ------------ |
193
+ | 10 | TRACE | 跟踪级别 |
194
+ | 20 | DEBUG | 调试级别 |
195
+ | 30 | INFO | 信息级别 |
196
+ | 40 | WARN | 警告级别 |
197
+ | 50 | ERROR | 错误级别 |
198
+ | 60 | FATAL | 致命错误级别 |
222
199
 
223
- ```typescript
224
- enum OutputLogFileTypeEnum {
225
- TRACE = 10, // 跟踪级别
226
- DEBUG = 20, // 调试级别
227
- INFO = 30, // 信息级别
228
- WARN = 40, // 警告级别
229
- ERROR = 50, // 错误级别
230
- FATAL = 60, // 致命错误级别
231
- }
232
- ```
233
-
234
- ## 高级功能
200
+ ## 进阶使用
235
201
 
236
- ### 临终落盘保护
237
-
238
- Node.js 包使用 signal-exit 库实现非侵入式临终落盘保护机制,确保进程退出时日志数据不丢失:
202
+ ### 动态静默控制
239
203
 
240
204
  ```typescript
241
- import { createOutputLogFile } from "@done-coding/output-node";
205
+ import {
206
+ createOutputConsole,
207
+ OutputConsoleTypeEnum,
208
+ } from "@done-coding/output-node";
242
209
 
243
- // 创建日志实例会自动注册 signal-exit 监听器
244
- const logger = createOutputLogFile({ logFilePath: "app.log" });
210
+ const output = createOutputConsole({
211
+ // 动态控制静默:只在调试模式下显示 DEBUG 信息
212
+ isSilent: (type) => {
213
+ if (type === OutputConsoleTypeEnum.DEBUG) {
214
+ return !process.env.DEBUG;
215
+ }
216
+ // 生产环境下静默所有 SKIP 类型
217
+ if (type === OutputConsoleTypeEnum.SKIP) {
218
+ return process.env.NODE_ENV === "production";
219
+ }
220
+ return false;
221
+ },
222
+ });
245
223
 
246
- logger.info("应用启动");
247
- // 当收到 SIGINT 或 SIGTERM 信号时,会自动刷新日志缓冲区
248
- // 与 NestJS 等现代框架的关闭钩子完美兼容
224
+ output.debug("调试信息"); // 只在 DEBUG=true 时显示
225
+ output.skip("跳过信息"); // 生产环境下不显示
226
+ output.info("普通信息"); // 总是显示
249
227
  ```
250
228
 
251
- ### 错误处理
252
-
253
- 包含完整的错误处理机制:
229
+ ### 切换和同步逻辑
254
230
 
255
231
  ```typescript
256
232
  import {
257
233
  createOutputConsole,
258
- DriverInitializationError,
234
+ createOutputLogFile,
235
+ OutputConsoleTypeEnum,
259
236
  } from "@done-coding/output-node";
260
237
 
261
- try {
262
- const outputConsole = createOutputConsole({
263
- bufferSize: -1, // 无效配置会抛出错误
264
- });
265
- } catch (error) {
266
- if (error instanceof DriverInitializationError) {
267
- console.error("驱动初始化失败:", error.message);
268
- }
269
- }
238
+ // 创建日志文件输出
239
+ const fileLogger = createOutputLogFile({ logFilePath: "error.log" });
240
+
241
+ // 创建带有切换和同步逻辑的控制台输出
242
+ const output = createOutputConsole({
243
+ enableColor: true,
244
+ // 错误级别切换到日志文件(不在控制台显示)
245
+ isSwitchLogFile: (type) => type === OutputConsoleTypeEnum.ERROR,
246
+ // 警告级别同步到日志文件(控制台和文件都显示)
247
+ isSyncToLogFile: (type) => type === OutputConsoleTypeEnum.WARN,
248
+ outputFileFn: (type, ...messages) => {
249
+ // 将控制台类型映射到日志文件类型并输出
250
+ fileLogger(type, ...messages);
251
+ },
252
+ });
253
+
254
+ output.info("普通信息"); // 只在控制台显示
255
+ output.warn("警告信息"); // 控制台和文件都显示
256
+ output.error("错误信息"); // 只在文件中记录
270
257
  ```
271
258
 
272
259
  ### 自定义颜色配置
@@ -277,7 +264,7 @@ import {
277
264
  OutputConsoleTypeEnum,
278
265
  } from "@done-coding/output-node";
279
266
 
280
- const outputConsole = createOutputConsole({
267
+ const output = createOutputConsole({
281
268
  enableColor: true,
282
269
  colorMap: {
283
270
  [OutputConsoleTypeEnum.INFO]: "blue",
@@ -291,161 +278,126 @@ const outputConsole = createOutputConsole({
291
278
  ### 缓冲区配置
292
279
 
293
280
  ```typescript
294
- import { createOutputLogFile } from "@done-coding/output-node";
295
-
296
- // 自定义缓冲区大小
281
+ // 异步写入模式(推荐用于生产环境)
297
282
  const logger = createOutputLogFile({
298
- bufferSize: 8192, // 8KB 缓冲区
283
+ logFilePath: "app.log",
299
284
  sync: false, // 异步写入
285
+ bufferSize: 8192, // 8KB 缓冲区
300
286
  });
301
287
 
302
288
  // 同步写入模式(性能较低但数据安全性更高)
303
289
  const syncLogger = createOutputLogFile({
290
+ logFilePath: "critical.log",
304
291
  sync: true, // 同步写入
305
292
  bufferSize: 1024, // 较小的缓冲区
306
293
  });
307
294
  ```
308
295
 
309
- ### 工具函数
296
+ ### TABLE 类型处理
310
297
 
311
298
  ```typescript
312
- import {
313
- generateDefaultNodeLogFileName,
314
- getConsoleTypeName,
315
- getLogFileTypeName,
316
- } from "@done-coding/output-node";
299
+ const output = createOutputConsole();
317
300
 
318
- // 生成默认日志文件名
319
- const fileName = generateDefaultNodeLogFileName();
320
- console.log(fileName); // 20240131_235959-12345.log
301
+ // 数组表格
302
+ output.table([
303
+ { name: "张三", age: 25, city: "北京" },
304
+ { name: "李四", age: 30, city: "上海" },
305
+ ]);
321
306
 
322
- // 获取类型名称
323
- console.log(getConsoleTypeName(OutputConsoleTypeEnum.INFO)); // "INFO"
324
- console.log(getLogFileTypeName(OutputLogFileTypeEnum.ERROR)); // "ERROR"
307
+ // 对象表格
308
+ output.table({
309
+ total: 100,
310
+ success: 95,
311
+ failed: 5,
312
+ });
325
313
  ```
326
314
 
327
- ## 最佳实践
328
-
329
- ### 1. 使用属性调用方式
315
+ ### 临终落盘保护
330
316
 
331
317
  ```typescript
332
- // 推荐:属性调用方式
333
- outputConsole.info("用户登录成功");
334
- outputConsole.error("数据库连接失败");
318
+ import { createOutputLogFile } from "@done-coding/output-node";
335
319
 
336
- // 不推荐:函数调用方式(虽然也支持)
337
- outputConsole(OutputConsoleTypeEnum.INFO, "用户登录成功");
320
+ // 创建日志实例会自动注册 signal-exit 监听器
321
+ const logger = createOutputLogFile({ logFilePath: "app.log" });
322
+
323
+ logger.info("应用启动");
324
+
325
+ // 当收到 SIGINT 或 SIGTERM 信号时,会自动刷新日志缓冲区
326
+ // 与 NestJS 等现代框架的关闭钩子完美兼容
338
327
  ```
339
328
 
340
- ### 2. 合理配置日志级别
329
+ ## 开发与测试
341
330
 
342
- ```typescript
343
- // 开发环境
344
- const devLogger = createOutputLogFile({
345
- prettyPrint: true, // 美化输出便于调试
346
- logFilePath: "dev.log",
347
- outputToConsole: true, // 同时输出到控制台
348
- });
331
+ ### 测试覆盖率
349
332
 
350
- // 生产环境
351
- const prodLogger = createOutputLogFile({
352
- prettyPrint: false, // 标准 JSON 格式
353
- logFilePath: `/var/log/app-${process.pid}.log`,
354
- sync: false, // 异步写入提高性能
355
- bufferSize: 8192, // 较大缓冲区
356
- });
357
- ```
333
+ - **语句覆盖率**: 99.35%
334
+ - **分支覆盖率**: 97.63%
335
+ - **函数覆盖率**: 97.5%
336
+ - **行覆盖率**: 99.35%
337
+ - **测试数量**: 181 个测试,全部通过
358
338
 
359
- ### 3. 错误处理和降级
339
+ ### 本地开发
360
340
 
361
- ```typescript
362
- import { createOutputLogFile } from "@done-coding/output-node";
341
+ ```bash
342
+ # 克隆仓库
343
+ git clone https://github.com/done-coding/output-node.git
344
+ cd output-node
363
345
 
364
- try {
365
- const logger = createOutputLogFile({
366
- logFilePath: "/protected/app.log",
367
- bufferSize: 4096,
368
- });
369
- } catch (error) {
370
- // 降级到控制台输出
371
- console.warn("日志文件创建失败,降级到控制台输出");
372
- const fallbackLogger = createOutputLogFile({
373
- outputToConsole: true,
374
- prettyPrint: true,
375
- });
376
- }
377
- ```
346
+ # 安装依赖
347
+ pnpm install
378
348
 
379
- ### 4. 性能优化
349
+ # 开发模式
350
+ pnpm dev
380
351
 
381
- ```typescript
382
- // 在高频输出场景下使用静默模式进行性能测试
383
- const outputConsole = createOutputConsole({
384
- silent: process.env.NODE_ENV === "test",
385
- });
352
+ # 运行测试
353
+ pnpm test
386
354
 
387
- // 批量输出时考虑使用异步日志
388
- const logger = createOutputLogFile({
389
- logFilePath: "batch.log",
390
- prettyPrint: false, // 禁用美化以提高性能
391
- sync: false, // 异步写入
392
- bufferSize: 16384, // 更大的缓冲区
393
- });
355
+ # 构建
356
+ pnpm build
394
357
  ```
395
358
 
396
- ### 5. TABLE 类型最佳实践
359
+ ### 贡献流程
397
360
 
398
- ```typescript
399
- // 推荐:结构化数据
400
- outputConsole.table([
401
- { name: "张三", age: 25, city: "北京" },
402
- { name: "李四", age: 30, city: "上海" },
403
- ]);
361
+ 1. Fork 本仓库
362
+ 2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
363
+ 3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
364
+ 4. 推送到分支 (`git push origin feature/AmazingFeature`)
365
+ 5. 开启 Pull Request
404
366
 
405
- // ✅ 推荐:对象数据
406
- outputConsole.table({
407
- total: 100,
408
- success: 95,
409
- failed: 5,
410
- });
367
+ ## 常见问题
411
368
 
412
- // 避免:非结构化数据
413
- outputConsole.table("这不是表格数据");
414
- ```
369
+ **Q: 为什么 Node 包不需要传入 `outputImpl` 参数?**
415
370
 
416
- ## 依赖
371
+ A: Node 包自动提供了基于 `console.log + chalk` 和 `pino` 的输出实现,用户无需手动创建和传入 `outputImpl`。这是 Node 包相比 Core 包的主要优势。
417
372
 
418
- - `@done-coding/output-core` - 核心包
419
- - `chalk` - 控制台颜色输出
420
- - `pino` - 高性能日志库
421
- - `pino-pretty` - 日志美化输出
422
- - `signal-exit` - 非侵入式进程退出监听
373
+ **Q: 如何在生产环境中优化日志性能?**
423
374
 
424
- ## 测试覆盖率
375
+ A: 使用异步写入模式(`sync: false`),适当增加缓冲区大小(如 8KB 或 16KB),并合理配置 `isSilent` 函数来过滤不必要的日志输出。
425
376
 
426
- - **语句覆盖率**: 99.51%
427
- - **分支覆盖率**: 98.13%
428
- - **函数覆盖率**: 97.29%
429
- - **行覆盖率**: 99.51%
430
- - **测试数量**: 182 个测试,全部通过
377
+ **Q: 如何在 NestJS 中使用?**
431
378
 
432
- ## 许可证
379
+ A: 可以在 NestJS 的 OnModuleInit 和 OnApplicationShutdown 钩子中使用,临终落盘保护会自动处理进程退出时的日志刷新。
433
380
 
434
- MIT
381
+ **Q: 日志文件路径可以是相对路径吗?**
382
+
383
+ A: 可以,相对路径会相对于当前工作目录。建议使用绝对路径以避免歧义。
384
+
385
+ **Q: 如何禁用颜色输出?**
386
+
387
+ A: 设置 `enableColor: false` 即可。
388
+
389
+ **Q: 缓冲区大小应该设置多少?**
435
390
 
436
- ## 贡献
391
+ A: 默认 4KB 适合大多数场景。高频输出可以增加到 8KB 或 16KB,低频输出可以减少到 1KB。
437
392
 
438
- 欢迎提交 Issue Pull Request!
393
+ **Q: 支持哪些 Node.js 版本?**
439
394
 
440
- ## 更新日志
395
+ A: 支持 Node.js 14+,推荐使用 Node.js 16+。
441
396
 
442
- ### v0.0.0
397
+ **Q: 如何处理日志文件权限错误?**
443
398
 
444
- - 初始版本发布
445
- - 支持控制台输出和日志文件输出
446
- - 实现基于 signal-exit 的临终落盘保护机制
447
- - 完整的错误处理和类型推导支持
448
- - 输出模式切换功能
449
- - TABLE 类型特殊处理
450
- - 常量集中管理
451
- - 缓冲区大小配置和验证
399
+ A: 包会自动捕获权限错误并静默处理,日志会降级到内存缓冲。建议检查文件路径和目录权限。
400
+
401
+ ## 许可证
402
+
403
+ MIT