109 lines
3.2 KiB
JavaScript
109 lines
3.2 KiB
JavaScript
import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync } from 'node:fs'
|
||
import path from 'node:path'
|
||
import { fileURLToPath } from 'node:url'
|
||
import { spawnSync } from 'node:child_process'
|
||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||
const desktopRoot = path.resolve(__dirname, '..')
|
||
const workspaceRoot = path.resolve(desktopRoot, '..')
|
||
const backendProject = path.join(
|
||
workspaceRoot,
|
||
'YD_TrainingCompetition_Api',
|
||
'YD_TrainingCompetition_Api.csproj',
|
||
)
|
||
const frontendRoot = path.join(workspaceRoot, 'YD_TrainingCompetition_Api_Web')
|
||
const frontendDist = path.join(frontendRoot, 'dist')
|
||
const packagedBackend = path.join(desktopRoot, 'build', 'backend')
|
||
const packagedFrontend = path.join(desktopRoot, 'frontend')
|
||
const skipFrontendBuild = process.argv.includes('--skip-frontend-build')
|
||
|
||
function run(command, args, options = {}) {
|
||
const useCmd = process.platform === 'win32' && command === 'npm'
|
||
const executable = useCmd ? process.env.ComSpec || 'cmd.exe' : command
|
||
const executableArgs = useCmd ? ['/d', '/s', '/c', `npm ${args.join(' ')}`] : args
|
||
console.log(`\n> ${command} ${args.join(' ')}`)
|
||
const result = spawnSync(executable, executableArgs, {
|
||
cwd: options.cwd || workspaceRoot,
|
||
env: {
|
||
...process.env,
|
||
...(options.env || {}),
|
||
},
|
||
stdio: 'inherit',
|
||
})
|
||
|
||
if (result.error) {
|
||
throw result.error
|
||
}
|
||
|
||
if (result.status !== 0) {
|
||
process.exit(result.status || 1)
|
||
}
|
||
}
|
||
|
||
function cleanDirectory(directory) {
|
||
rmSync(directory, { force: true, recursive: true })
|
||
mkdirSync(directory, { recursive: true })
|
||
}
|
||
|
||
function copyDirectory(source, destination) {
|
||
mkdirSync(destination, { recursive: true })
|
||
|
||
for (const entry of readdirSync(source, { withFileTypes: true })) {
|
||
const sourcePath = path.join(source, entry.name)
|
||
const destinationPath = path.join(destination, entry.name)
|
||
|
||
if (entry.isDirectory()) {
|
||
copyDirectory(sourcePath, destinationPath)
|
||
} else if (entry.isFile()) {
|
||
copyFileSync(sourcePath, destinationPath)
|
||
}
|
||
}
|
||
}
|
||
|
||
cleanDirectory(packagedBackend)
|
||
cleanDirectory(packagedFrontend)
|
||
|
||
run('dotnet', [
|
||
'publish',
|
||
backendProject,
|
||
'-c',
|
||
'Release',
|
||
'-r',
|
||
'win-x64',
|
||
'--self-contained',
|
||
'true',
|
||
'-o',
|
||
packagedBackend,
|
||
'/p:PublishSingleFile=false',
|
||
])
|
||
|
||
if (skipFrontendBuild) {
|
||
console.log('\n> skip frontend install/build, using existing dist')
|
||
} else {
|
||
run('npm', ['install'], { cwd: frontendRoot })
|
||
run('npm', ['run', 'build'], {
|
||
cwd: frontendRoot,
|
||
env: {
|
||
VITE_API_BASE_URL: 'http://localhost:9996',
|
||
},
|
||
})
|
||
}
|
||
|
||
if (!existsSync(frontendDist)) {
|
||
throw new Error(`前端构建产物不存在:${frontendDist}`)
|
||
}
|
||
|
||
copyDirectory(frontendDist, packagedFrontend)
|
||
|
||
// 同时把前端拷进后端 wwwroot,使后端通过 http 直接托管页面与静态资源。
|
||
const backendWwwRoot = path.join(packagedBackend, 'wwwroot')
|
||
cleanDirectory(backendWwwRoot)
|
||
copyDirectory(frontendDist, backendWwwRoot)
|
||
|
||
const appSettingsPath = path.join(workspaceRoot, 'YD_TrainingCompetition_Api', 'appsettings.json')
|
||
if (existsSync(appSettingsPath)) {
|
||
copyFileSync(appSettingsPath, path.join(packagedBackend, 'appsettings.json'))
|
||
}
|
||
|
||
console.log('\n桌面端打包资源已准备完成。')
|