如何修改Node.js项目自定义启动脚本,实现启动前执行拷贝等操作并打印启动日志
启动脚本修改方案
你现有代码无法打印服务启动日志的核心原因是exec的执行机制:它会等到子进程完全退出后才会把所有输出一次性返回回调,而Express服务是常驻后台的进程,运行过程中不会主动退出,所以你永远拿不到实时打印的启动标识。
修改步骤
- 新增前置拷贝逻辑:用Node内置fs模块完成文件/目录拷贝,确保拷贝操作完成后再启动服务
- 替换
exec为spawn启动服务:spawn支持将子进程的输入输出流直接绑定到当前终端,可以实时打印所有服务日志
修改后的完整启动脚本代码如下:
const { spawn } = require('child_process'); const { program } = require('commander'); const fs = require('fs/promises'); const path = require('path'); // 自定义前置拷贝逻辑,可根据实际需求修改源路径、目标路径 async function copyFilesBeforeStart() { console.log('正在执行前置文件拷贝操作...'); // 示例:拷贝src/assets目录到dist/assets const sourcePath = path.resolve(__dirname, '../src/assets'); const targetPath = path.resolve(__dirname, '../dist/assets'); // recursive参数设为true支持递归拷贝整个目录 await fs.cp(sourcePath, targetPath, { recursive: true }); console.log('前置文件拷贝操作完成'); } program.version('0.0.1'); program .command('start') .description('Start project in development environment') .action(async () => { console.log('Script starting...'); try { // 优先执行前置拷贝操作 await copyFilesBeforeStart(); // 启动Express服务 const serverProcess = spawn('node', ['./src/server.js'], { stdio: 'inherit', // 直接把子进程输出绑定到当前终端,所有日志自动打印 shell: true // 兼容Windows系统命令执行 }); // 监听子进程退出事件,主进程同步退出 serverProcess.on('exit', (code) => { console.log(`服务进程退出,退出码:${code}`); process.exit(code); }); } catch (err) { console.error('启动失败:', err); process.exit(1); } }); program.parse(process.argv);
注意事项
- 如果你使用的Node.js版本低于16.7.0,内置
fs.cp方法不可用,可以替换为第三方库fs-extra的copy方法,或者自行实现递归拷贝逻辑 - 你的Express服务使用了ES模块
import语法,需要在项目根目录package.json中添加"type": "module"配置,或者把服务文件后缀改为.mjs,否则启动会报语法错误
内容的提问来源于stack exchange,提问作者MegaRoks
相关产品推荐
相关产品推荐

