Files
BYW-VoiceHub/VoiceHub-main/scripts/netlify-build.js
T
Henry_Du 4ce4649aaf
Build VoiceHub FPK / build-fpk (push) Failing after 56m5s
Build and Push Docker Image / build-and-push (push) Canceled after 1h9m35s
初次提交
2026-09-06 08:19:02 +08:00

173 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
import { execSync } from 'child_process'
import fs from 'fs'
// 颜色输出
const colors = {
reset: '\x1b[0m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
cyan: '\x1b[36m'
}
const BUILD_MEMORY_MB = 6144
const DEFAULT_NODE_OPTIONS = `--max-old-space-size=${BUILD_MEMORY_MB}`
function log(message, color = 'reset') {
console.log(`${colors[color]}${message}${colors.reset}`)
}
function logStep(step, message) {
log(`${step} ${message}`, 'cyan')
}
function logSuccess(message) {
log(`✅ ${message}`, 'green')
}
function logWarning(message) {
log(`⚠️ ${message}`, 'yellow')
}
function logError(message) {
log(`❌ ${message}`, 'red')
}
// 安全执行命令
function safeExec(command, options = {}) {
try {
execSync(command, { stdio: 'inherit', ...options })
return true
} catch (error) {
logError(`命令执行失败: ${command}`)
logError(error.message)
return false
}
}
// 检查文件是否存在
function fileExists(filePath) {
try {
return fs.existsSync(filePath)
} catch {
return false
}
}
// Netlify 构建流程
async function netlifyBuild() {
log('🚀 Netlify 构建', 'cyan')
try {
// 1. 设置环境变量
process.env.NETLIFY = 'true'
process.env.NITRO_PRESET = 'netlify'
// 2. 清理构建目录
logStep('🧹', '清理构建目录...')
if (fileExists('dist')) safeExec('rm -rf dist')
if (fileExists('.netlify')) safeExec('rm -rf .netlify')
if (fileExists('.nuxt')) safeExec('rm -rf .nuxt')
logSuccess('清理完成')
// 3. 安装依赖
logStep('📦', '安装依赖...')
let installed = false
if (fileExists('node_modules')) {
safeExec('rm -rf node_modules')
}
if (fileExists('pnpm-lock.yaml')) {
if (safeExec('pnpm install --frozen-lockfile')) {
installed = true
logSuccess('依赖安装完成 (pnpm install --frozen-lockfile)')
} else {
logWarning('pnpm install --frozen-lockfile 安装失败,准备回退到 pnpm install...')
}
} else {
logWarning('未检测到 pnpm-lock.yaml,跳过冻结锁文件安装,直接使用 pnpm install...')
}
if (!installed) {
if (!safeExec('pnpm install')) {
throw new Error('依赖安装失败')
}
logSuccess('依赖安装完成 (pnpm install)')
}
// 验证 Drizzle 依赖
if (!safeExec('pnpm list drizzle-orm drizzle-kit')) {
if (!safeExec('pnpm add drizzle-orm drizzle-kit')) {
throw new Error('Drizzle 依赖安装失败')
}
}
// 4. 检查 Drizzle 配置
if (!fileExists('drizzle.config.ts') || !fileExists('app/drizzle/schema.ts')) {
throw new Error('Drizzle 配置文件不完整')
}
// 5. 确保迁移目录存在
if (!fileExists('app/drizzle/migrations')) {
fs.mkdirSync('app/drizzle/migrations', { recursive: true })
}
// 6. 数据库同步
if (process.env.DATABASE_URL) {
logStep('�️', '同步数据库...')
const env = { ...process.env, CI: 'true', DRIZZLE_KIT_FORCE: 'true', NODE_ENV: 'production' }
if (safeExec('node scripts/db-sync.js', { env })) {
logSuccess('数据库同步成功')
} else {
logWarning('数据库同步失败')
}
// 检查管理员账户
if (fileExists('scripts/create-admin.js')) {
logStep('👤', '检查管理员账户...')
safeExec('pnpm run create-admin', { env })
}
} else {
logWarning('未设置 DATABASE_URL')
}
// 7. 构建应用
logStep('🔨', '构建应用...')
const buildEnv = {
...process.env,
NODE_OPTIONS: process.env.NODE_OPTIONS || DEFAULT_NODE_OPTIONS
}
if (!safeExec('pnpm exec nuxt build', { env: buildEnv })) {
throw new Error('构建失败')
}
logSuccess('构建完成')
// 8. 验证构建输出
const hasNetlifyFunctions = fileExists('.netlify/functions-internal/server')
const hasOutputPublic = fileExists('.output/public')
if (hasNetlifyFunctions) {
logSuccess('Netlify Functions 生成成功')
}
if (hasOutputPublic) {
logSuccess('静态资源生成成功')
}
if (!hasNetlifyFunctions && !hasOutputPublic) {
throw new Error('构建输出目录不存在')
}
log('🎉 构建完成!', 'green')
} catch (error) {
logError(`构建失败: ${error.message}`)
process.exit(1)
}
}
// 运行构建
netlifyBuild().catch((error) => {
logError(`未预期的错误: ${error.message}`)
process.exit(1)
})