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

Node.js不使用Nodemon如何实现输入rs命令重启通过require启动的进程

问题原因分析
  • 逻辑顺序错误:你在代码中先执行了process.exit(),当前Node进程会直接终止,后续的require("./path/to/file")代码完全不会执行,自然没有重启效果。
  • 模块缓存问题:就算调整顺序去掉process.exit()直接重新require目标文件,Node.js默认会对已经加载的模块做缓存,重复require不会重新执行目标文件的代码,只会返回缓存的导出结果。
  • 资源残留问题:如果不清理原有业务代码占用的资源(比如端口监听、定时器、事件监听等),直接重新运行业务代码会出现端口占用、事件重复触发等冲突问题。
推荐实现方案(子进程模式,无第三方依赖)

推荐通过主进程托管业务子进程的方式实现,逻辑更稳定,和nodemon的核心实现逻辑一致,不需要额外清理业务资源:

// 把这段代码作为你的启动入口文件,替换原有启动逻辑
const { fork } = require('child_process');
const readline = require('readline');

const rl = readline.createInterface({ input: process.stdin, output: process.stdout });

let childProcess;
// 启动业务子进程的方法
function startChild() {
  // 传入启动参数-dev,和你原启动逻辑一致
  childProcess = fork('./path/to/file', ['-dev']);
  // 把子进程的输出同步到主进程控制台
  childProcess.stdout.pipe(process.stdout);
  childProcess.stderr.pipe(process.stderr);
  // 子进程意外退出时自动重启
  childProcess.on('exit', (code) => {
    if (code !== 0) startChild();
  });
}

// 首次启动业务进程
startChild();

// 监听控制台输入
rl.on('line', (input) => {
  if (input.trim() === 'rs') {
    console.log('正在重启进程...');
    // 杀掉旧的业务子进程
    childProcess.kill();
    // 启动新的业务子进程
    startChild();
  }
});
可选方案(单进程模式)

如果不想用子进程,可以参考以下实现,需要注意手动清理业务代码占用的资源:

const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const targetModulePath = require.resolve('./path/to/file');

// 业务代码启动方法
function startApp() {
  // 清除目标模块的缓存
  delete require.cache[targetModulePath];
  // 重新引入执行业务代码
  require(targetModulePath);
}

// 首次启动
startApp();

rl.on('line', (input) => {
  if (input.trim() === 'rs') {
    console.log('正在重启进程...');
    // --- 此处需要补充你业务代码的资源清理逻辑,比如关闭监听端口、清除定时器等 ---
    // 重新启动业务代码
    startApp();
  }
});

注意:单进程模式如果资源清理不全,会出现端口占用、重复事件监听等异常,优先使用子进程方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:36:04