/** * 宝塔面板启动脚本 - Node.js v16兼容版 * 解决宝塔面板Node.js项目部署问题 */ const { spawn } = require('child_process'); const path = require('path'); const fs = require('fs'); // 设置环境变量 process.env.PORT = process.env.PORT || 4001; process.env.NODE_ENV = 'production'; console.log('=== 宝塔面板启动脚本 ==='); console.log(`端口: ${process.env.PORT}`); console.log(`环境: ${process.env.NODE_ENV}`); console.log(`工作目录: ${process.cwd()}`); // 检查关键文件是否存在 const requiredFiles = [ 'api/server.ts', 'api/app.ts', 'package.json' ]; for (const file of requiredFiles) { if (!fs.existsSync(file)) { console.error(`错误: 缺少必要文件 ${file}`); process.exit(1); } } console.log('✓ 必要文件检查通过'); // 检查Node.js版本 const nodeVersion = process.version; console.log(`Node.js版本: ${nodeVersion}`); // 启动后端服务 console.log('正在启动后端服务...'); // 使用node --loader tsx/esm来启动,兼容Node.js v16 let server; // 尝试不同的启动方式 function tryStartServer() { // 方式1: 使用node --loader (推荐用于Node.js v16) console.log('尝试使用 node --loader 启动...'); server = spawn('node', ['--loader', 'tsx/esm', 'api/server.ts'], { cwd: process.cwd(), stdio: 'inherit', env: { ...process.env, PORT: process.env.PORT || 4001, NODE_ENV: 'production' } }); // 如果失败,尝试方式2 server.on('error', (err) => { console.log('方式1失败,尝试方式2...'); tryStartServerMethod2(); }); server.on('exit', (code, signal) => { if (code === 1) { console.log('方式1失败,尝试方式2...'); tryStartServerMethod2(); } else { console.log(`服务器进程退出,代码: ${code}, 信号: ${signal}`); if (code !== 0) { console.error('服务器异常退出'); process.exit(1); } } }); } function tryStartServerMethod2() { console.log('尝试使用 npx tsx 启动...'); server = spawn('npx', ['tsx', 'api/server.ts'], { cwd: process.cwd(), stdio: 'inherit', env: { ...process.env, PORT: process.env.PORT || 4001, NODE_ENV: 'production' } }); server.on('error', (err) => { console.error('所有启动方式都失败了:', err); tryStartServerMethod3(); }); server.on('exit', (code, signal) => { if (code === 1) { console.log('方式2失败,尝试方式3...'); tryStartServerMethod3(); } else { console.log(`服务器进程退出,代码: ${code}, 信号: ${signal}`); if (code !== 0) { console.error('服务器异常退出'); process.exit(1); } } }); } function tryStartServerMethod3() { console.log('尝试使用 node --experimental-loader 启动...'); server = spawn('node', ['--experimental-loader', 'tsx/esm', 'api/server.ts'], { cwd: process.cwd(), stdio: 'inherit', env: { ...process.env, PORT: process.env.PORT || 4001, NODE_ENV: 'production' } }); server.on('error', (err) => { console.error('服务器启动失败:', err); process.exit(1); }); server.on('exit', (code, signal) => { console.log(`服务器进程退出,代码: ${code}, 信号: ${signal}`); if (code !== 0) { console.error('服务器异常退出'); process.exit(1); } }); } // 开始启动 tryStartServer(); // 处理进程退出信号 process.on('SIGTERM', () => { console.log('收到SIGTERM信号,正在关闭服务...'); if (server) { server.kill('SIGTERM'); } setTimeout(() => { process.exit(0); }, 5000); }); process.on('SIGINT', () => { console.log('收到SIGINT信号,正在关闭服务...'); if (server) { server.kill('SIGINT'); } setTimeout(() => { process.exit(0); }, 5000); }); // 防止进程意外退出 process.on('uncaughtException', (err) => { console.error('未捕获的异常:', err); }); process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', reason); }); console.log('✓ 启动脚本初始化完成');