# GERP 前端部署脚本:全量编译并同步产物到生产目录(TempLate/GERP) # # 用途: # 1. 清理旧构建产物(dist 与 TempLate/GERP/assets),保证无 hash 残留 # 2. 全量重新构建(vue-tsc 类型检查 + vite build) # 3. 同步 dist 产物到 TempLate/GERP(index.html + assets) # 4. 校验 TempLate 与 dist 完全一致 # # 用法: # PowerShell 中执行: .\deploy.ps1 # (若报执行策略限制: Set-ExecutionPolicy -Scope Process Bypass 后再执行) $ErrorActionPreference = 'Stop' $ProjectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path # d:\SMANAGE\GERP $DistDir = Join-Path $ProjectRoot 'dist' $ProdRoot = Join-Path (Split-Path -Parent $ProjectRoot) 'TempLate\GERP' # d:\SMANAGE\TempLate\GERP $ProdAssetsDir = Join-Path $ProdRoot 'assets' $IndexHtml = Join-Path $ProdRoot 'index.html' Write-Host "`n===== GERP 部署开始 =====" -ForegroundColor Cyan Write-Host "工程目录: $ProjectRoot" Write-Host "生产目录: $ProdRoot" Write-Host "" # 1. 清理旧产物(dist + 生产 assets),保证全量构建无 hash 残留 Write-Host '[1/4] 清理旧构建产物...' -ForegroundColor Yellow if (Test-Path $DistDir) { Remove-Item -Recurse -Force $DistDir Write-Host " 已删除: $DistDir" } if (Test-Path $ProdAssetsDir) { Remove-Item -Recurse -Force $ProdAssetsDir Write-Host " 已删除: $ProdAssetsDir" } if (Test-Path $IndexHtml) { Remove-Item -Force $IndexHtml Write-Host " 已删除: $IndexHtml" } Write-Host '' # 2. 全量构建(vue-tsc 类型检查 + vite build) Write-Host '[2/4] 执行 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 '' # 3. 同步产物到生产目录 Write-Host '[3/4] 同步产物到生产目录...' -ForegroundColor Yellow if (-not (Test-Path $ProdRoot)) { New-Item -ItemType Directory -Path $ProdRoot -Force | Out-Null } Copy-Item -Recurse -Force (Join-Path $DistDir '*') $ProdRoot Copy-Item -Force (Join-Path $DistDir 'index.html') $IndexHtml Write-Host ' 同步完成' Write-Host '' # 4. 校验生产目录与 dist 完全一致(文件名集合) Write-Host '[4/4] 校验产物一致性...' -ForegroundColor Yellow function Get-AssetNames([string]$dir) { if (-not (Test-Path $dir)) { return @() } return @(Get-ChildItem -Path $dir -Recurse -File | ForEach-Object { $_.FullName.Substring($dir.Length) }) } $distNames = Get-AssetNames (Join-Path $DistDir 'assets') $prodNames = Get-AssetNames $ProdAssetsDir $distSet = @($distNames | Sort-Object -Unique) $prodSet = @($prodNames | Sort-Object -Unique) $onlyDist = @($distSet | Where-Object { $_ -notin $prodSet }) $onlyProd = @($prodSet | Where-Object { $_ -notin $distSet }) if ($onlyDist.Count -eq 0 -and $onlyProd.Count -eq 0) { Write-Host " 校验通过: assets 文件数 $($distSet.Count) 个,生产与 dist 完全一致" -ForegroundColor Green } else { Write-Host ' 校验异常:' -ForegroundColor Red if ($onlyDist.Count) { Write-Host " 仅在 dist : $onlyDist" -ForegroundColor Red } if ($onlyProd.Count) { Write-Host " 仅在生产: $onlyProd" -ForegroundColor Red } throw '产物校验失败,请检查!' } # 校验 index.html 引用的入口 JS 存在 $indexContent = Get-Content $IndexHtml -Raw $entryMatch = [regex]::Match($indexContent, 'src="([^"]+\.js)"') if ($entryMatch.Success) { $entryPath = Join-Path $ProdRoot ($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 引用' } Write-Host '' Write-Host "===== GERP 部署完成 =====" -ForegroundColor Cyan Write-Host '请浏览器强制刷新(Ctrl+F5)加载新产物。' -ForegroundColor Cyan