154 lines
3.9 KiB
JavaScript
Executable File
154 lines
3.9 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
||
|
||
/**
|
||
* 部署助手脚本
|
||
*
|
||
* 使用:
|
||
* node scripts/deploy.js # 标准部署(生产构建 + 依赖)
|
||
* node scripts/deploy.js --docker # Docker 镜像
|
||
* node scripts/deploy.js --help # 显示帮助
|
||
*/
|
||
|
||
import fs from 'fs'
|
||
import path from 'path'
|
||
import { execSync } from 'child_process'
|
||
|
||
const args = process.argv.slice(2)
|
||
const help = args.includes('--help') || args.includes('-h')
|
||
const isDocker = args.includes('--docker')
|
||
const outDir = args.includes('--out') ? args[args.indexOf('--out') + 1] : 'dist'
|
||
|
||
if (help) {
|
||
console.log(`
|
||
Usage: node scripts/deploy.js [options]
|
||
|
||
Options:
|
||
--docker 生成 Dockerfile
|
||
--out PATH 输出目录(默认: dist)
|
||
--help 显示此帮助信息
|
||
|
||
Examples:
|
||
node scripts/deploy.js 生产构建
|
||
node scripts/deploy.js --out build 输出到 build 目录
|
||
node scripts/deploy.js --docker 生成 Docker 配置
|
||
`)
|
||
process.exit(0)
|
||
}
|
||
|
||
console.log('🚀 开始部署流程...\n')
|
||
|
||
try {
|
||
// 1. 生产构建
|
||
console.log('📦 构建应用...')
|
||
execSync('npm run build:prod', { stdio: 'inherit', cwd: process.cwd() })
|
||
|
||
// 2. 创建部署目录
|
||
console.log('\n📁 准备部署目录...')
|
||
const deployDir = path.join(process.cwd(), 'deploy')
|
||
|
||
if (fs.existsSync(deployDir)) {
|
||
fs.rmSync(deployDir, { recursive: true })
|
||
}
|
||
fs.mkdirSync(deployDir, { recursive: true })
|
||
|
||
// 3. 复制必要文件
|
||
console.log('📋 复制文件...')
|
||
|
||
// 复制构建输出
|
||
fs.copyFileSync(
|
||
path.join(process.cwd(), 'dist/index.js'),
|
||
path.join(deployDir, 'index.js'),
|
||
)
|
||
fs.copyFileSync(
|
||
path.join(process.cwd(), 'dist/package.json'),
|
||
path.join(deployDir, 'package.json'),
|
||
)
|
||
|
||
// 复制 package.json(用于 npm install)
|
||
const srcPkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'))
|
||
const deployPkg = {
|
||
name: srcPkg.name,
|
||
version: srcPkg.version,
|
||
type: 'module',
|
||
dependencies: srcPkg.dependencies,
|
||
}
|
||
fs.writeFileSync(
|
||
path.join(deployDir, 'package.json'),
|
||
JSON.stringify(deployPkg, null, 2),
|
||
)
|
||
|
||
// 复制 .env 模板
|
||
if (fs.existsSync('.env.example')) {
|
||
fs.copyFileSync('.env.example', path.join(deployDir, '.env.example'))
|
||
}
|
||
|
||
console.log(`✅ 部署文件已生成到 ${path.relative(process.cwd(), deployDir)}/`)
|
||
|
||
// 4. 可选:生成 Docker 配置
|
||
if (isDocker) {
|
||
console.log('\n🐳 生成 Docker 配置...')
|
||
|
||
const dockerfile = `FROM node:22-alpine
|
||
|
||
WORKDIR /app
|
||
|
||
# 复制应用文件
|
||
COPY package.json .
|
||
COPY index.js .
|
||
|
||
# 安装依赖
|
||
RUN npm ci --omit=dev
|
||
|
||
# 暴露端口
|
||
EXPOSE 3001
|
||
|
||
# 启动应用
|
||
CMD ["node", "index.js"]
|
||
`
|
||
|
||
const dockerCompose = `version: '3.8'
|
||
|
||
services:
|
||
csms:
|
||
build: .
|
||
ports:
|
||
- "3001:3001"
|
||
environment:
|
||
NODE_ENV: production
|
||
# env_file:
|
||
# - .env
|
||
restart: unless-stopped
|
||
`
|
||
|
||
fs.writeFileSync(path.join(deployDir, 'Dockerfile'), dockerfile)
|
||
fs.writeFileSync(path.join(deployDir, 'docker-compose.yml'), dockerCompose)
|
||
|
||
console.log('✅ Docker 文件已生成')
|
||
}
|
||
|
||
// 5. 显示部署信息
|
||
console.log('\n📊 部署信息:')
|
||
console.log(` 名称: ${deployPkg.name}`)
|
||
console.log(` 版本: ${deployPkg.version}`)
|
||
console.log(` 主文件: index.js`)
|
||
console.log(` 依赖数: ${Object.keys(deployPkg.dependencies).length}`)
|
||
|
||
const indexSize = fs.statSync(path.join(deployDir, 'index.js')).size
|
||
console.log(` 代码大小: ${(indexSize / 1024).toFixed(1)}KB`)
|
||
|
||
console.log('\n✨ 部署准备完成!\n')
|
||
console.log('下一步:')
|
||
console.log(` 1. cd ${path.relative(process.cwd(), deployDir)}`)
|
||
console.log(` 2. npm install --omit=dev`)
|
||
console.log(` 3. node index.js`)
|
||
|
||
if (isDocker) {
|
||
console.log('\n或使用 Docker:')
|
||
console.log(` 1. cd ${path.relative(process.cwd(), deployDir)}`)
|
||
console.log(` 2. docker compose up`)
|
||
}
|
||
} catch (error) {
|
||
console.error('\n❌ 部署失败:', error.message)
|
||
process.exit(1)
|
||
}
|