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:
10
AGENTS.md
10
AGENTS.md
@@ -20,7 +20,10 @@ Guidelines for AI agents working in this Bun monorepo.
|
||||
```bash
|
||||
bun dev # Start all apps in dev mode
|
||||
bun build # Build all apps
|
||||
bun compile # Compile server to standalone binary (depends on build)
|
||||
bun compile # Compile server to standalone binary (current platform, depends on build)
|
||||
bun compile:linux # Compile server for Linux x64
|
||||
bun compile:mac # Compile server for macOS arm64
|
||||
bun compile:win # Compile server for Windows x64
|
||||
bun dist # Full packaging pipeline: server build → compile → desktop distributable (current platform)
|
||||
bun dist:linux # Full pipeline → Linux distributable
|
||||
bun dist:mac # Full pipeline → macOS distributable
|
||||
@@ -33,7 +36,10 @@ bun typecheck # TypeScript check across monorepo
|
||||
```bash
|
||||
bun dev # Vite dev server (localhost:3000)
|
||||
bun build # Production build -> .output/
|
||||
bun compile # Compile to standalone binary
|
||||
bun compile # Compile to standalone binary (current platform)
|
||||
bun compile:linux # Compile for Linux x64
|
||||
bun compile:mac # Compile for macOS arm64
|
||||
bun compile:win # Compile for Windows x64
|
||||
bun fix # Biome auto-fix
|
||||
bun typecheck # TypeScript check
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ bun typecheck # TypeScript check
|
||||
From monorepo root, run `bun dist` to execute the full pipeline automatically (via Turbo task dependencies):
|
||||
|
||||
1. **Build server**: `apps/server` → `vite build` → `.output/`
|
||||
2. **Compile server**: `apps/server` → `bun compile.ts` → `out/server-{platform}`
|
||||
2. **Compile server**: `apps/server` → `bun compile.ts` → `out/server-{os}-{arch}`
|
||||
3. **Package desktop**: `apps/desktop` → `electron-vite build` + `electron-builder` → distributable
|
||||
|
||||
The `electron-builder.yml` `extraResources` config reads binaries directly from `../server/out/`, no manual copy needed.
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/electron-userland/electron-builder/refs/heads/master/packages/app-builder-lib/scheme.json
|
||||
appId: com.furtherverse.app
|
||||
productName: Furtherverse
|
||||
directories:
|
||||
buildResources: build
|
||||
files:
|
||||
- '!**/.vscode/*'
|
||||
- '!src/*'
|
||||
- '!electron.vite.config.{js,ts,mjs,cjs}'
|
||||
- '!{.env,.env.*,bun.lock}'
|
||||
- '!{tsconfig.json,tsconfig.node.json}'
|
||||
- '!{AGENTS.md,README.md,CHANGELOG.md}'
|
||||
- "!**/.vscode/*"
|
||||
- "!src/*"
|
||||
- "!electron.vite.config.{js,ts,mjs,cjs}"
|
||||
- "!{.env,.env.*,bun.lock}"
|
||||
- "!{tsconfig.json,tsconfig.node.json}"
|
||||
- "!{AGENTS.md,README.md,CHANGELOG.md}"
|
||||
asarUnpack:
|
||||
- resources/**
|
||||
win:
|
||||
|
||||
@@ -25,8 +25,10 @@ bun db:studio # Drizzle Studio GUI
|
||||
|
||||
# Build
|
||||
bun build # Production build → .output/
|
||||
bun compile # Compile to standalone binary (depends on build)
|
||||
# Also triggered automatically by root `bun dist`
|
||||
bun compile # Compile to standalone binary (current platform, depends on build)
|
||||
bun compile:linux # Compile for Linux x64
|
||||
bun compile:mac # Compile for macOS arm64
|
||||
bun compile:win # Compile for Windows x64
|
||||
|
||||
# Code Quality
|
||||
bun fix # Biome auto-fix
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"compile": "bun compile.ts",
|
||||
"compile:linux": "bun compile.ts --target bun-linux-x64",
|
||||
"compile:mac": "bun compile.ts --target bun-darwin-arm64",
|
||||
"compile:win": "bun compile.ts --target bun-windows-x64",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate",
|
||||
"db:push": "drizzle-kit push",
|
||||
|
||||
@@ -8,6 +8,15 @@
|
||||
},
|
||||
"compile": {
|
||||
"outputs": ["out/**"]
|
||||
},
|
||||
"compile:linux": {
|
||||
"outputs": ["out/**"]
|
||||
},
|
||||
"compile:mac": {
|
||||
"outputs": ["out/**"]
|
||||
},
|
||||
"compile:win": {
|
||||
"outputs": ["out/**"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
"scripts": {
|
||||
"build": "turbo run build",
|
||||
"compile": "turbo run compile",
|
||||
"compile:linux": "turbo run compile:linux",
|
||||
"compile:mac": "turbo run compile:mac",
|
||||
"compile:win": "turbo run compile:win",
|
||||
"dev": "turbo run dev",
|
||||
"dist": "turbo run dist",
|
||||
"dist:linux": "turbo run dist:linux",
|
||||
|
||||
15
turbo.json
15
turbo.json
@@ -9,6 +9,15 @@
|
||||
"compile": {
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"compile:linux": {
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"compile:mac": {
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"compile:win": {
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"dist": {},
|
||||
"dist:linux": {},
|
||||
"dist:mac": {},
|
||||
@@ -17,13 +26,13 @@
|
||||
"dependsOn": ["@furtherverse/server#compile"]
|
||||
},
|
||||
"@furtherverse/desktop#dist:linux": {
|
||||
"dependsOn": ["@furtherverse/server#compile"]
|
||||
"dependsOn": ["@furtherverse/server#compile:linux"]
|
||||
},
|
||||
"@furtherverse/desktop#dist:mac": {
|
||||
"dependsOn": ["@furtherverse/server#compile"]
|
||||
"dependsOn": ["@furtherverse/server#compile:mac"]
|
||||
},
|
||||
"@furtherverse/desktop#dist:win": {
|
||||
"dependsOn": ["@furtherverse/server#compile"]
|
||||
"dependsOn": ["@furtherverse/server#compile:win"]
|
||||
},
|
||||
"dev": {
|
||||
"cache": false,
|
||||
|
||||
Reference in New Issue
Block a user