134 lines
3.2 KiB
JavaScript
134 lines
3.2 KiB
JavaScript
/**
|
|
* JNote 后端启动脚本
|
|
* 跨平台兼容 Windows 和 Linux
|
|
*/
|
|
|
|
const { spawn, execSync } = require('child_process');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const os = require('os');
|
|
|
|
const scriptDir = __dirname;
|
|
process.chdir(scriptDir);
|
|
|
|
const APP_NAME = 'jnote-api';
|
|
const isWindows = os.platform() === 'win32';
|
|
|
|
function log(msg) {
|
|
console.log(`[Start] ${msg}`);
|
|
}
|
|
|
|
function loadEnv() {
|
|
const envFile = path.join(scriptDir, '.env');
|
|
if (!fs.existsSync(envFile)) {
|
|
log('⚠️ 未找到 .env 文件');
|
|
return;
|
|
}
|
|
|
|
const content = fs.readFileSync(envFile, 'utf8');
|
|
content.split('\n').forEach(line => {
|
|
line = line.trim();
|
|
if (!line || line.startsWith('#')) return;
|
|
const idx = line.indexOf('=');
|
|
if (idx > 0) {
|
|
const key = line.substring(0, idx).trim();
|
|
let value = line.substring(idx + 1).trim();
|
|
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
(value.startsWith("'") && value.endsWith("'"))) {
|
|
value = value.slice(1, -1);
|
|
}
|
|
process.env[key] = value;
|
|
}
|
|
});
|
|
}
|
|
|
|
function getExePath() {
|
|
const possibleNames = isWindows
|
|
? ['jnote-api.exe', 'jnote-api']
|
|
: ['jnote-api', 'jnote-api.exe'];
|
|
|
|
for (const name of possibleNames) {
|
|
const p = path.join(scriptDir, name);
|
|
if (fs.existsSync(p)) return p;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function startWithPM2(exePath) {
|
|
log('🚀 使用 PM2 启动...');
|
|
|
|
try {
|
|
execSync('pm2 --version', { stdio: 'ignore' });
|
|
} catch {
|
|
log('📦 安装 PM2...');
|
|
execSync('npm install -g pm2', { cwd: scriptDir, stdio: 'inherit' });
|
|
}
|
|
|
|
try {
|
|
execSync(`pm2 stop ${APP_NAME}`, { stdio: 'ignore' });
|
|
execSync(`pm2 delete ${APP_NAME}`, { stdio: 'ignore' });
|
|
} catch {}
|
|
|
|
spawn('pm2', ['start', exePath, '--name', APP_NAME], {
|
|
cwd: scriptDir,
|
|
stdio: 'inherit',
|
|
shell: true
|
|
});
|
|
|
|
setTimeout(() => {
|
|
try { execSync('pm2 save', { stdio: 'ignore' }); } catch {}
|
|
}, 2000);
|
|
|
|
log('✅ 服务已启动');
|
|
log(' 状态: pm2 status');
|
|
log(' 日志: pm2 logs jnote-api');
|
|
}
|
|
|
|
function startDirect(exePath) {
|
|
log('🚀 直接启动服务...');
|
|
log(` 端口: ${process.env.PORT || 3000}`);
|
|
log('');
|
|
|
|
if (!isWindows) {
|
|
fs.chmodSync(exePath, 0o755);
|
|
}
|
|
|
|
spawn(exePath, [], {
|
|
cwd: scriptDir,
|
|
stdio: 'inherit',
|
|
env: process.env
|
|
});
|
|
}
|
|
|
|
function main() {
|
|
console.log('=========================================');
|
|
console.log(' JNote 后端启动脚本');
|
|
console.log(` 平台: ${isWindows ? 'Windows' : 'Linux'}`);
|
|
console.log('=========================================');
|
|
|
|
loadEnv();
|
|
|
|
const exe = getExePath();
|
|
if (!exe) {
|
|
console.error('❌ 错误: 未找到 jnote-api 可执行文件');
|
|
console.error(` 请确保可执行文件与本脚本在同一目录下: ${scriptDir}`);
|
|
console.error('');
|
|
console.error(' Linux 应有: jnote-api');
|
|
console.error(' Windows 应有: jnote-api.exe');
|
|
console.error('');
|
|
console.error(' 如果还没有打包,请先运行: node build.js');
|
|
process.exit(1);
|
|
}
|
|
|
|
log(`✓ 找到: ${path.basename(exe)}`);
|
|
|
|
// 优先使用 PM2
|
|
try {
|
|
execSync('pm2 --version', { stdio: 'ignore' });
|
|
startWithPM2(exe);
|
|
} catch {
|
|
startDirect(exe);
|
|
}
|
|
}
|
|
|
|
main(); |