You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用commander.js时如何实现运行中的实时日志输出?

解决Commander.js持续运行程序的实时日志输出问题

问题分析

你的代码里日志延迟输出,核心原因有两个:

  1. Node.js 的标准输出(stdout)默认会缓冲内容,直到缓冲区满或进程退出才会刷新到控制台;
  2. 异步 Action 未保持挂起状态,Commander 可能误判命令已执行完成,间接影响日志即时输出。

解决方案

1. 禁用 stdout 缓冲

在程序开头添加代码,强制关闭 stdout 的缓冲机制,让内容实时输出:

// 禁用 stdout 缓冲,确保日志实时打印
process.stdout._handle.setBlocking(true);

2. 让异步 Action 保持运行状态

因为dev命令是持续监听文件的长任务,需要让 Action 的 Promise 一直处于 pending 状态,避免 Commander 认为命令已结束。可以在 Action 末尾添加一个永不 resolve 的 Promise:

program
  .command('dev')
  .description('启动开发服务器')
  .action(async (options, command) => {
    // 现在会实时输出日志
    console.log('开始监听文件变化...');
    chokidar.watch('./src')
      .on('change', (path) => {
        console.log(`文件 ${path} 已修改`);
      });
    // 保持进程持续运行
    await new Promise(() => {});
  });

3. 完整示例代码

import { program } from 'commander';
import chokidar from 'chokidar';

// 禁用 stdout 缓冲
process.stdout._handle.setBlocking(true);

program
  .command('dev')
  .description('启动开发服务器')
  .action(async (options, command) => {
    console.log('开发服务器已启动,开始监听文件...');
    chokidar.watch('./src')
      .on('add', (path) => console.log(`新增文件:${path}`))
      .on('change', (path) => console.log(`修改文件:${path}`))
      .on('unlink', (path) => console.log(`删除文件:${path}`));
    
    // 监听退出信号,实现优雅终止
    process.on('SIGINT', () => {
      console.log('\n正在退出开发服务器...');
      process.exit(0);
    });

    // 保持进程运行
    await new Promise(() => {});
  });

program.parse();

额外说明

  • console.log默认会在输出后添加换行并触发刷新,但在长时异步环境下仍可能受缓冲影响,禁用缓冲是最可靠的方案;
  • 添加SIGINT信号监听可以让程序在用户按下Ctrl+C时优雅退出,避免强制终止带来的问题。

内容的提问来源于stack exchange,提问作者seancdavis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:19:57