215 lines
8.1 KiB
PowerShell
215 lines
8.1 KiB
PowerShell
# GVSite 前端部署脚本:备份原站页面 → 全量编译 → 同步产物到生产目录(TempLate)
|
||
#
|
||
# 用途:
|
||
# 1. 备份已被 Vue 页面替换的 TempLate 原始文件到 backup/www
|
||
# 2. 全量重新构建(vue-tsc 类型检查 + vite build)
|
||
# 3. 同步 dist 产物到 TempLate(index.html + assets)
|
||
# 4. 校验产物一致性
|
||
#
|
||
# 前置条件:
|
||
# 1. 已修改 gvsds/apps/core/views.py 中的 SUBDOMAIN_CONFIG:
|
||
# - www: 移除 'use_base': True(SPA 不再使用 _Base 模板)
|
||
# - invite: dir 从 'Invite' 改为 '' 且移除 'use_base': True
|
||
# 2. GVSite 路由已使用 createWebHistory(支持干净 URL)
|
||
#
|
||
# 用法:
|
||
# PowerShell 中执行: .\deploy.ps1
|
||
# (若报执行策略限制: Set-ExecutionPolicy -Scope Process Bypass 后再执行)
|
||
|
||
$ErrorActionPreference = 'Stop'
|
||
|
||
$ProjectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path # d:\SMANAGE\GVSite
|
||
$DistDir = Join-Path $ProjectRoot 'dist'
|
||
$TemplateRoot = Join-Path (Split-Path -Parent $ProjectRoot) 'TempLate' # d:\SMANAGE\TempLate
|
||
$BackupRoot = Join-Path (Split-Path -Parent $ProjectRoot) 'backup\www' # d:\SMANAGE\backup\www
|
||
|
||
Write-Host "`n===== GVSite 部署开始 =====" -ForegroundColor Cyan
|
||
Write-Host "工程目录: $ProjectRoot"
|
||
Write-Host "生产目录: $TemplateRoot"
|
||
Write-Host "备份目录: $BackupRoot"
|
||
Write-Host ""
|
||
|
||
# =====================
|
||
# 0. 前置检查:确保 views.py 已更新
|
||
# =====================
|
||
Write-Host '[0/6] 前置检查...' -ForegroundColor Yellow
|
||
$ViewsPy = Join-Path (Split-Path -Parent $ProjectRoot) 'gvsds\apps\core\views.py'
|
||
$ViewsContent = Get-Content $ViewsPy -Raw
|
||
if ($ViewsContent -match "'www':\s*\{'dir':\s*'',\s*'root_is_index':\s*True\s*\}") {
|
||
Write-Host ' www 子域配置检查通过(无 use_base)' -ForegroundColor Green
|
||
} else {
|
||
Write-Warning ' www 子域配置可能仍有 use_base,请检查 views.py'
|
||
}
|
||
if ($ViewsContent -match "'invite':\s*\{'dir':\s*'',\s*'root_is_index':\s*True\s*\}") {
|
||
Write-Host ' invite 子域配置检查通过(dir 改为空,无 use_base)' -ForegroundColor Green
|
||
} else {
|
||
Write-Warning ' invite 子域配置可能未更新,请检查 views.py'
|
||
}
|
||
Write-Host ''
|
||
|
||
# =====================
|
||
# 1. 备份被替换的原始页面
|
||
# =====================
|
||
Write-Host '[1/6] 备份已被替换的 www + invite 原始页面...' -ForegroundColor Yellow
|
||
|
||
# 需要备份的文件列表(相对 TempLate 的路径)
|
||
$BackupFiles = @(
|
||
# 根目录页面
|
||
'index.html',
|
||
'about.html',
|
||
'login.html',
|
||
'register.html',
|
||
'gallery.html',
|
||
'ContactUS.html',
|
||
'members.html',
|
||
'IntegrityReport.html',
|
||
'usercard.html',
|
||
# 错误页面
|
||
'Errors/404.html',
|
||
'Errors/500.html',
|
||
'Errors/503.html',
|
||
'Errors/_403_HOST.html',
|
||
# 项目页面
|
||
'ProJect/Unauthorized.html',
|
||
# Invite 页面(模板文件保留不移除)
|
||
'Invite/index.html',
|
||
'Invite/interview.html'
|
||
)
|
||
|
||
$BackupCount = 0
|
||
foreach ($relPath in $BackupFiles) {
|
||
$sourceFile = Join-Path $TemplateRoot $relPath
|
||
$destFile = Join-Path $BackupRoot $relPath
|
||
|
||
if (Test-Path $sourceFile) {
|
||
# 确保目标目录存在
|
||
$destDir = Split-Path $destFile -Parent
|
||
if (-not (Test-Path $destDir)) {
|
||
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
|
||
}
|
||
Copy-Item -Path $sourceFile -Destination $destFile -Force
|
||
Write-Host " 已备份: $relPath"
|
||
$BackupCount++
|
||
} else {
|
||
Write-Host " 跳过(不存在): $relPath" -ForegroundColor DarkGray
|
||
}
|
||
}
|
||
|
||
if ($BackupCount -gt 0) {
|
||
Write-Host " 备份完成,共 $BackupCount 个文件" -ForegroundColor Green
|
||
} else {
|
||
Write-Host " 无文件需要备份" -ForegroundColor Yellow
|
||
}
|
||
Write-Host ''
|
||
|
||
# =====================
|
||
# 2. 清理旧构建产物
|
||
# =====================
|
||
Write-Host '[2/6] 清理旧构建产物...' -ForegroundColor Yellow
|
||
if (Test-Path $DistDir) {
|
||
Remove-Item -Recurse -Force $DistDir
|
||
Write-Host " 已删除: $DistDir"
|
||
}
|
||
# 清理 TempLate/GVSite 旧产物目录(构建产物统一收敛到该子目录)
|
||
$ProdGvsiteDir = Join-Path $TemplateRoot 'GVSite'
|
||
if (Test-Path $ProdGvsiteDir) {
|
||
Get-ChildItem -Path $ProdGvsiteDir -Recurse -Force | Remove-Item -Recurse -Force
|
||
Write-Host " 已清理旧产物目录: GVSite/"
|
||
} else {
|
||
Write-Host " GVSite 目录不存在,跳过" -ForegroundColor DarkGray
|
||
}
|
||
Write-Host ''
|
||
|
||
# =====================
|
||
# 3. 全量构建
|
||
# =====================
|
||
Write-Host '[3/6] 执行 npm run build(类型检查 + 全量编译)...' -ForegroundColor Yellow
|
||
Push-Location $ProjectRoot
|
||
try {
|
||
npm run build
|
||
if ($LASTEXITCODE -ne 0) {
|
||
throw "构建失败,exit code = $LASTEXITCODE"
|
||
}
|
||
} finally {
|
||
Pop-Location
|
||
}
|
||
Write-Host ' 构建成功'
|
||
Write-Host ''
|
||
|
||
# =====================
|
||
# 4. 同步产物到生产目录
|
||
# =====================
|
||
Write-Host '[4/6] 同步产物到 www 生产目录...' -ForegroundColor Yellow
|
||
|
||
# 复制 GVSite 构建产物到生产目录 GVSite/(vite assetsDir=GVSite,产物位于 dist/GVSite/,相对引用 GVSite/...)
|
||
$ProdGvsite = Join-Path $TemplateRoot 'GVSite'
|
||
$DistGvsite = Join-Path $DistDir 'GVSite'
|
||
if (Test-Path $DistGvsite) {
|
||
if (-not (Test-Path $ProdGvsite)) {
|
||
New-Item -ItemType Directory -Path $ProdGvsite -Force | Out-Null
|
||
}
|
||
# 先清空旧产物,避免 hash 文件堆积
|
||
Get-ChildItem -Path $ProdGvsite -File -ErrorAction SilentlyContinue | Remove-Item -Force
|
||
Copy-Item -Recurse -Force (Join-Path $DistGvsite '*') $ProdGvsite
|
||
Write-Host " 已同步: GVSite/"
|
||
} else {
|
||
Write-Warning " dist 中未找到 GVSite,请检查 vite.config.ts 的 assetsDir 配置"
|
||
}
|
||
|
||
# 复制 index.html(产物引用为 /GVSite/...,与部署位置 GVSite/ 一致,无需改写)
|
||
$DistIndex = Join-Path $DistDir 'index.html'
|
||
$ProdIndex = Join-Path $TemplateRoot 'index.html'
|
||
if (Test-Path $DistIndex) {
|
||
Copy-Item -Force $DistIndex $ProdIndex
|
||
Write-Host " 已同步: index.html"
|
||
}
|
||
|
||
Write-Host ' 同步完成'
|
||
Write-Host ''
|
||
|
||
# =====================
|
||
# 5. 校验产物一致性
|
||
# =====================
|
||
Write-Host '[5/6] 校验产物一致性...' -ForegroundColor Yellow
|
||
|
||
# 校验 index.html 存在
|
||
if (-not (Test-Path $ProdIndex)) {
|
||
throw "index.html 不存在于生产目录: $ProdIndex"
|
||
}
|
||
|
||
# 校验 index.html 引用的入口 JS 存在
|
||
$indexContent = Get-Content $ProdIndex -Raw
|
||
$entryMatch = [regex]::Match($indexContent, 'src="([^"]+\.js)"')
|
||
if ($entryMatch.Success) {
|
||
$entryPath = Join-Path $TemplateRoot ($entryMatch.Groups[1].Value.TrimStart('/'))
|
||
if (Test-Path $entryPath) {
|
||
Write-Host " 入口 JS 校验通过: $($entryMatch.Groups[1].Value)" -ForegroundColor Green
|
||
} else {
|
||
throw "index.html 引用的入口 JS 不存在: $entryPath"
|
||
}
|
||
} else {
|
||
throw 'index.html 中未找到入口 JS 引用'
|
||
}
|
||
|
||
# 校验 assets 文件存在
|
||
$ProdAssetFiles = @(Get-ChildItem -Path $ProdGvsite -Recurse -File 2>$null)
|
||
$DistAssetFiles = @(Get-ChildItem -Path $DistGvsite -Recurse -File 2>$null)
|
||
|
||
if ($ProdAssetFiles.Count -ge $DistAssetFiles.Count) {
|
||
Write-Host " assets 文件数: $($ProdAssetFiles.Count) 个(dist: $($DistAssetFiles.Count) 个)" -ForegroundColor Green
|
||
} else {
|
||
Write-Host " assets 文件数: $($ProdAssetFiles.Count) 个(dist: $($DistAssetFiles.Count) 个)" -ForegroundColor Yellow
|
||
}
|
||
|
||
Write-Host ''
|
||
Write-Host "===== GVSite 部署完成 =====" -ForegroundColor Cyan
|
||
Write-Host "备份位置: $BackupRoot" -ForegroundColor Cyan
|
||
Write-Host "请浏览器强制刷新(Ctrl+F5)加载新产物。" -ForegroundColor Cyan
|
||
Write-Host ''
|
||
Write-Host '===== 部署后提醒 =====' -ForegroundColor Magenta
|
||
Write-Host ' - www.gvsds.com 和 invite.gvsds.com 现在使用 GVSite SPA(createWebHistory)'
|
||
Write-Host ' - 旧 _Base 模板已不再使用,所有页面由 Vue Router 前端路由控制'
|
||
Write-Host ' - 原始文件已备份到 backup/www,可随时恢复'
|
||
Write-Host ' - 旧 .html 文件仍保留在 TempLate 中作为降级回退'
|
||
Write-Host ' - 如需回退:删除 TempLate/index.html 和 GVSite 的 assets,恢复 backup/www 中的文件'
|
||
Write-Host '================================================================================' -ForegroundColor Magenta |