#!/usr/bin/env node /** * 将项目打包并部署到远程服务器 * 使用方式:npm run deploy * 通过 SSH rsync 部署到 root@38.246.250.238:/opt/1panel/www/sites/pm.xtrader.vip/index * * 环境变量(可选):DEPLOY_HOST、DEPLOY_USER、DEPLOY_PATH * 依赖:rsync(系统自带)、ssh 免密或密钥 */ import { execSync, spawnSync } from 'child_process' import { dirname, join } from 'path' import { fileURLToPath } from 'url' const __dirname = dirname(fileURLToPath(import.meta.url)) const projectRoot = join(__dirname, '..') const distDir = join(projectRoot, 'dist') const config = { host: process.env.DEPLOY_HOST || '38.246.250.238', user: process.env.DEPLOY_USER || 'root', path: process.env.DEPLOY_PATH || '/opt/1panel/www/sites/pm.xtrader.vip/index', } const target = `${config.user}@${config.host}:${config.path}` function build() { const apiUrl = process.env.VITE_API_BASE_URL || 'https://api.xtrader.vip' console.log(`📦 正在打包项目(.env.production API: ${apiUrl})...`) execSync('npm run build', { cwd: projectRoot, stdio: 'inherit', // 继承 process.env(已由 --env-file=.env.production 加载生产配置) env: process.env, }) console.log('✅ 打包完成\n') } function deploy() { const rsyncCheck = spawnSync('which', ['rsync'], { encoding: 'utf8' }) if (rsyncCheck.status !== 0) { console.error('❌ 未找到 rsync') process.exit(1) } console.log(`🔌 正在通过 SSH 部署到 ${target} ...`) const result = spawnSync( 'rsync', [ '-avz', '--delete', '--exclude=.DS_Store', `${distDir}/`, `${target}/`, ], { cwd: projectRoot, stdio: 'inherit', encoding: 'utf8', } ) if (result.status !== 0) { console.error('❌ 部署失败') process.exit(1) } console.log('\n🎉 部署成功!') } function main() { build() deploy() } main()