diff --git a/docs/开发与部署SOP.md b/docs/开发与部署SOP.md index dc7430b9..bf91abd3 100644 --- a/docs/开发与部署SOP.md +++ b/docs/开发与部署SOP.md @@ -33,6 +33,7 @@ 项目使用专属构建器 `caiwu-builder`,缓存与其他项目分开: - 前端在 Windows 主机使用项目专用 Node 20 构建,避开 Docker 虚拟机内存上限; +- 前端输入指纹未变化时直接复用上次产物,纯后端改动不重复打包前端; - PHP 扩展层只在 Dockerfile 的基础环境变化时重建; - Composer 只在 `composer.lock` 变化时重新解析依赖,并复用下载缓存; - npm 优先使用本机下载缓存,`node_modules` 原位刷新,不会逐版本堆积; diff --git a/scripts/build-frontend.ps1 b/scripts/build-frontend.ps1 index fa1112c5..6f7edd6e 100644 --- a/scripts/build-frontend.ps1 +++ b/scripts/build-frontend.ps1 @@ -16,6 +16,7 @@ $archivePath = Join-Path $toolRoot $archiveName $checksumPath = Join-Path $toolRoot 'SHASUMS256.txt' $trackedCssPath = Join-Path $repoRoot 'public/css/app.css' $frontendOutputRoot = Join-Path $repoRoot '.caiwu-build/public' +$fingerprintPath = Join-Path $repoRoot '.caiwu-build/frontend.sha' function Invoke-Native { param( @@ -31,6 +32,30 @@ function Invoke-Native { } } +$fingerprintInputs = @( + 'HEAD:resources', + 'HEAD:package.json', + 'HEAD:package-lock.json', + 'HEAD:webpack.mix.js', + 'HEAD:tailwind.config.js' +) +$fingerprintHashes = @(& git -C $repoRoot rev-parse @fingerprintInputs) +if ($LASTEXITCODE -ne 0) { + throw '无法计算前端输入指纹。' +} +$frontendFingerprint = "$NodeVersion|$($fingerprintHashes -join '|')" +$cachedOutputs = @( + (Join-Path $frontendOutputRoot 'js/auth/common.min.js'), + (Join-Path $frontendOutputRoot 'css/app.css'), + (Join-Path $frontendOutputRoot 'mix-manifest.json'), + $fingerprintPath +) +$cacheComplete = -not ($cachedOutputs | Where-Object { -not (Test-Path -LiteralPath $_) }) +if ($cacheComplete -and (Get-Content -Raw -LiteralPath $fingerprintPath).Trim() -eq $frontendFingerprint) { + Write-Host '前端输入未变化,复用已有构建产物。' + return +} + if (-not (Test-Path -LiteralPath $nodeExe)) { New-Item -ItemType Directory -Force -Path $toolRoot | Out-Null @@ -105,6 +130,7 @@ try { Copy-Item -LiteralPath (Join-Path $repoRoot 'public/js') -Destination $frontendOutputRoot -Recurse Copy-Item -LiteralPath (Join-Path $repoRoot 'public/css/app.css') -Destination (Join-Path $frontendOutputRoot 'css/app.css') Copy-Item -LiteralPath (Join-Path $repoRoot 'public/mix-manifest.json') -Destination $frontendOutputRoot + Set-Content -LiteralPath $fingerprintPath -Value $frontendFingerprint -NoNewline } finally { Pop-Location diff --git a/scripts/deploy-from-workstation.ps1 b/scripts/deploy-from-workstation.ps1 index 07fb2346..d0d70134 100644 --- a/scripts/deploy-from-workstation.ps1 +++ b/scripts/deploy-from-workstation.ps1 @@ -145,8 +145,8 @@ try { . } '本机镜像构建失败。服务器未发生任何变更。' - $previousShaOutput = & ssh -i $keyFullPath -o BatchMode=yes -o StrictHostKeyChecking=accept-new $sshTarget "cat '$RemotePath/.deployed-sha' 2>/dev/null || true" - $previousSha = ([string]$previousShaOutput).Trim() + $previousShaOutput = @(& ssh -i $keyFullPath -o BatchMode=yes -o StrictHostKeyChecking=accept-new $sshTarget "cat '$RemotePath/.deployed-sha' 2>/dev/null || true") + $previousSha = ($previousShaOutput -join "`n").Trim() if ($LASTEXITCODE -ne 0) { throw '无法连接服务器。' }