task-181(静态资源部署与 Nginx History 托管): 确认后台 dist 发布目录约定
补充 deploy/release-structure.md 与 verify-dist.mjs,契约测试锁 conf。 TDD: task-181.test.ts 8 用例 RED→GREEN。
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
# 仅作部署参考,实际 server/root/upstream 按环境调整。
|
||||||
|
|
||||||
|
location = /admin {
|
||||||
|
return 302 /admin-vue/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /admin-vue/assets/ {
|
||||||
|
alias /var/www/admin-vue/assets/;
|
||||||
|
try_files $uri =404;
|
||||||
|
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /admin-vue/ {
|
||||||
|
alias /var/www/admin-vue/;
|
||||||
|
try_files $uri $uri/ /admin-vue/index.html;
|
||||||
|
add_header Cache-Control "no-cache";
|
||||||
|
}
|
||||||
|
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://java_backend;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# Admin Vue 发布目录结构(module 10)
|
||||||
|
|
||||||
|
发布目标:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/var/www/
|
||||||
|
├── admin-vue-<ts>/ # 新版本临时发布目录
|
||||||
|
│ ├── index.html
|
||||||
|
│ └── assets/...
|
||||||
|
├── admin-vue-prev/ # 上一版本(回滚保留)
|
||||||
|
└── admin-vue -> admin-vue-<ts> # Nginx 根目录符号链接(原子切换)
|
||||||
|
```
|
||||||
|
|
||||||
|
发布过程:
|
||||||
|
|
||||||
|
1. `npm ci && npm run build` 产出 `dist/`。
|
||||||
|
2. 运行 `deploy/verify-dist.mjs`:校验 `index.html` 引用完整、assets 存在、base 为 `/admin-vue/`。
|
||||||
|
3. 上传 `dist/` 至 `admin-vue-<ts>/`。
|
||||||
|
4. `ln -sfn admin-vue-<ts> /var/www/admin-vue` 原子切换。
|
||||||
|
5. 旧版本目录保留为 `admin-vue-prev`,用于快速回滚。
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// Admin Vue 构建产物清单校验(module 10):base=/admin-vue/ 且 index.html 引用的资源均存在。
|
||||||
|
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
||||||
|
import { join, resolve } from 'node:path'
|
||||||
|
|
||||||
|
const root = resolve(process.cwd())
|
||||||
|
const dist = join(root, 'dist')
|
||||||
|
const index = join(dist, 'index.html')
|
||||||
|
|
||||||
|
function fail(message) {
|
||||||
|
console.error(`[verify-dist] ${message}`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existsSync(index)) fail('缺少 dist/index.html(请先 npm run build)')
|
||||||
|
|
||||||
|
const html = readFileSync(index, 'utf8')
|
||||||
|
if (!html.includes('/admin-vue/')) fail('index.html 资源引用未包含 base=/admin-vue/')
|
||||||
|
|
||||||
|
const assetsDir = join(dist, 'assets')
|
||||||
|
const assets = existsSync(assetsDir) ? readdirSync(assetsDir) : []
|
||||||
|
const refs = [...html.matchAll(/(?:src|href)="\/admin-vue\/assets\/([^"]+)"/g)].map((m) => m[1])
|
||||||
|
for (const ref of refs) {
|
||||||
|
if (!assets.includes(ref)) fail(`index.html 引用的资源缺失: assets/${ref}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[verify-dist] ok: base=/admin-vue/, assets=${assets.length}, refs=${refs.length}`)
|
||||||
Reference in New Issue
Block a user