refactor: simplify compile.ts to single-target and add per-platform compile scripts
- Rewrite compile.ts from 112 to 66 lines: single target with auto-detect host, remove multi-target batch logic - Add compile:linux/mac/win scripts to server, root, and turbo configs - Wire desktop dist:* to depend on matching server compile:* (avoid unnecessary cross-platform compilation) - Update AGENTS.md docs across root, server, and desktop
This commit is contained in:
@@ -1,111 +1,66 @@
|
||||
import { rm } from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
|
||||
const ALL_TARGETS = [
|
||||
const ENTRYPOINT = '.output/server/index.mjs'
|
||||
const OUTDIR = 'out'
|
||||
|
||||
const VALID_TARGETS = [
|
||||
'bun-windows-x64',
|
||||
'bun-darwin-arm64',
|
||||
'bun-darwin-x64',
|
||||
'bun-linux-x64',
|
||||
'bun-linux-arm64',
|
||||
] as const
|
||||
|
||||
type BunTarget = (typeof ALL_TARGETS)[number]
|
||||
type Target = (typeof VALID_TARGETS)[number]
|
||||
|
||||
const ENTRYPOINT = '.output/server/index.mjs'
|
||||
const OUTDIR = 'out'
|
||||
const OUTFILE_BASE = 'server'
|
||||
|
||||
const DEFAULT_TARGETS: BunTarget[] = [
|
||||
'bun-windows-x64',
|
||||
'bun-darwin-arm64',
|
||||
'bun-linux-x64',
|
||||
]
|
||||
|
||||
const suffixFor = (target: BunTarget) => target.replace('bun-', '')
|
||||
|
||||
const isTarget = (value: string): value is BunTarget =>
|
||||
(ALL_TARGETS as readonly string[]).includes(value)
|
||||
|
||||
const parseTargets = (): BunTarget[] => {
|
||||
const args = process.argv.slice(2)
|
||||
const targets: string[] = []
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i]
|
||||
const next = args[i + 1]
|
||||
if (arg === '--target' && next) {
|
||||
targets.push(next)
|
||||
i++
|
||||
} else if (arg === '--targets' && next) {
|
||||
targets.push(...next.split(','))
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
if (targets.length === 0) return DEFAULT_TARGETS
|
||||
|
||||
const invalid = targets.filter((t) => !isTarget(t))
|
||||
if (invalid.length) {
|
||||
throw new Error(
|
||||
`Unknown target(s): ${invalid.join(', ')}\nAllowed: ${ALL_TARGETS.join(', ')}`,
|
||||
)
|
||||
}
|
||||
return targets as BunTarget[]
|
||||
const HOST_MAP: Record<string, Target> = {
|
||||
'win32-x64': 'bun-windows-x64',
|
||||
'darwin-arm64': 'bun-darwin-arm64',
|
||||
'linux-x64': 'bun-linux-x64',
|
||||
'linux-arm64': 'bun-linux-arm64',
|
||||
}
|
||||
|
||||
const buildOne = async (target: BunTarget) => {
|
||||
const suffix = suffixFor(target)
|
||||
const outfile = `${OUTFILE_BASE}-${suffix}`
|
||||
const resolveTarget = (): Target => {
|
||||
const idx = process.argv.indexOf('--target')
|
||||
if (idx !== -1) {
|
||||
const value = process.argv[idx + 1]
|
||||
if (!value || !VALID_TARGETS.includes(value as Target)) {
|
||||
throw new Error(
|
||||
`Invalid target: ${value}\nAllowed: ${VALID_TARGETS.join(', ')}`,
|
||||
)
|
||||
}
|
||||
return value as Target
|
||||
}
|
||||
|
||||
const key = `${process.platform}-${process.arch}`
|
||||
const target = HOST_MAP[key]
|
||||
if (!target) {
|
||||
throw new Error(`Unsupported host: ${key}`)
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
const target = resolveTarget()
|
||||
const suffix = target.replace('bun-', '')
|
||||
const outfile = `server-${suffix}`
|
||||
|
||||
await rm(OUTDIR, { recursive: true, force: true })
|
||||
|
||||
const result = await Bun.build({
|
||||
entrypoints: [ENTRYPOINT],
|
||||
outdir: OUTDIR,
|
||||
compile: {
|
||||
outfile,
|
||||
target,
|
||||
},
|
||||
compile: { outfile, target },
|
||||
})
|
||||
|
||||
if (!result.success) {
|
||||
throw new Error(
|
||||
`Build failed for ${target}:\n${result.logs.map(String).join('\n')}`,
|
||||
)
|
||||
throw new Error(result.logs.map(String).join('\n'))
|
||||
}
|
||||
|
||||
return {
|
||||
target,
|
||||
outputs: result.outputs.map((o) => path.relative('.', o.path)),
|
||||
}
|
||||
}
|
||||
|
||||
const main = async () => {
|
||||
const targets = parseTargets()
|
||||
|
||||
await rm(OUTDIR, { recursive: true, force: true })
|
||||
console.log(`✓ 已清理输出目录: ${OUTDIR}`)
|
||||
|
||||
// Bun cross-compile 不支持真正并行,逐目标串行构建
|
||||
const results: Awaited<ReturnType<typeof buildOne>>[] = []
|
||||
for (const target of targets) {
|
||||
const start = Date.now()
|
||||
process.stdout.write(`🔨 构建 ${target}... `)
|
||||
const result = await buildOne(target)
|
||||
results.push(result)
|
||||
console.log(`完成 (${Date.now() - start}ms)`)
|
||||
}
|
||||
|
||||
console.log('\n📦 构建完成:')
|
||||
for (const r of results) {
|
||||
console.log(` ${r.target}:`)
|
||||
for (const p of r.outputs) {
|
||||
console.log(` - ${p}`)
|
||||
}
|
||||
}
|
||||
console.log(`✓ ${target} → ${OUTDIR}/${outfile}`)
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error('\n❌ 构建失败:')
|
||||
console.error(err instanceof Error ? err.message : err)
|
||||
console.error('❌', err instanceof Error ? err.message : err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user