diff --git a/deploy/README.md b/deploy/README.md index da09a74..3476d69 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -16,3 +16,4 @@ 3. **本地重建**:在项目根按 `pull-and-restart.sh` 方式在 `admin/` 执行 `npm run build`,`vite.config` 中 `base` 须为 `'/admin/'`。 4. **勿用旧版 `nginx/admin.conf`**:若曾把仅含 `location /` 的旧配置拷到服务器,会导致 `/assets/*.js` 全部变成 `index.html`(约 640B、MIME 错)。请以 **`deploy/admin/default.conf`** 或 **`admin/nginx.conf`** 为准,并 **`docker compose restart admin nginx`**。 5. **若出现 500**:外层 `yuheng.docker.conf.tpl` 仅用 **`location /admin/`** 反代即可(勿对 `/admin/assets/` 再写 `rewrite` + 变量 `proxy_pass`,部分环境会 **500**);白屏仍以 **内层** `deploy/admin/default.conf` 的 `^~ /assets/` 为准。 +6. **`restart.sh` 构建 admin** 已与 **`pull-and-restart.sh` 一致**(挂载**项目根**到容器,否则 `@yh-web` 无法解析)。发版后脚本会执行 **`scripts/verify-admin-dist.sh`**:若 `index.html` 引用的 chunk 在 `dist/assets/` 中缺失或过小(几百字节),会直接报错退出,避免白屏上线。 diff --git a/pull-and-restart.sh b/pull-and-restart.sh index b9cf86b..7ed3970 100755 --- a/pull-and-restart.sh +++ b/pull-and-restart.sh @@ -323,6 +323,8 @@ if [ ! -f "$ROOT/deploy/web/dist/index.html" ] || [ ! -f "$ROOT/deploy/admin/dis exit 1 fi +bash "$ROOT/scripts/verify-admin-dist.sh" "$ROOT" + # 仅构建 api 运行时镜像(轻量,无业务代码);web/admin 使用官方 nginx 镜像无需构建 compose_cmd build api diff --git a/restart.sh b/restart.sh index 3a2411f..b90ec84 100755 --- a/restart.sh +++ b/restart.sh @@ -211,7 +211,8 @@ else [ -f "$ROOT/web/promotion/index.html" ] && cp -a "$ROOT/web/promotion/index.html" "$ROOT/deploy/web/dist/promotion/" || true fi echo "构建 admin 前端 -> deploy/admin/dist ..." -run_sudo docker run --rm -v "$ROOT/admin:/app" -v "$ROOT/deploy/admin/dist:/out" -w /app \ +# 与 pull-and-restart.sh 一致:须挂载项目根,@yh-web -> ../web/src(仅挂 admin 会构建失败或产物异常) +run_sudo docker run --rm -v "$ROOT:/repo" -v "$ROOT/deploy/admin/dist:/out" -w /repo/admin \ "${REGISTRY_MIRROR}node:20-alpine" sh -c "rm -rf /out/* 2>/dev/null; (npm ci --legacy-peer-deps 2>/dev/null || npm install --legacy-peer-deps) && npm run build && cp -r dist/. /out/" echo "构建 api 二进制 -> deploy/api/server ..." run_sudo docker run --rm -v "$ROOT/server:/src" -v "$ROOT/deploy/api:/out" -w /src -e GOPROXY="${GOPROXY}" \ @@ -221,6 +222,8 @@ if [ ! -f "$ROOT/deploy/web/dist/index.html" ] || [ ! -f "$ROOT/deploy/admin/dis echo "错误: 构建产物不完整(缺少 index.html),请检查上方构建日志。" >&2 exit 1 fi +bash "$ROOT/scripts/verify-admin-dist.sh" "$ROOT" + compose_cmd build api MONGO_IMAGE="${REGISTRY_MIRROR}mongo:7" diff --git a/scripts/verify-admin-dist.sh b/scripts/verify-admin-dist.sh new file mode 100644 index 0000000..eed9305 --- /dev/null +++ b/scripts/verify-admin-dist.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Verify admin dist: chunks referenced in index.html must exist under deploy/admin/dist and be large enough +# (avoids nginx serving index.html for missing assets -> white screen, tiny JS/CSS in Network tab) +set -e +ROOT="${1:?usage: $0 }" +D="$ROOT/deploy/admin/dist" +H="$D/index.html" +if [ ! -f "$H" ]; then + echo "verify-admin-dist: missing $H" >&2 + exit 1 +fi +if ! grep -qE '/admin/assets/[^"'\''<> ]+\.js' "$H"; then + echo "verify-admin-dist: no /admin/assets/*.js in index.html (check admin/vite.config.js base: /admin/)" >&2 + exit 1 +fi +TMP="$(mktemp)" +grep -oE '/admin/assets/[^"'\''<> ]+' "$H" | sort -u >"$TMP" +while IFS= read -r path; do + [ -n "$path" ] || continue + rel="${path#/admin}" + f="$D$rel" + if [ ! -f "$f" ]; then + echo "verify-admin-dist: referenced but missing on disk: $path -> $f" >&2 + echo " Deploy full deploy/admin/dist, not index.html alone." >&2 + rm -f "$TMP" + exit 1 + fi + sz=$(wc -c <"$f" 2>/dev/null | tr -d ' \r\n' || echo 0) + if [ "${sz:-0}" -lt 800 ]; then + echo "verify-admin-dist: file too small (${sz} bytes), likely wrong content: $f" >&2 + echo " Admin build must mount repo root (see pull-and-restart.sh / restart.sh docker -v ROOT:/repo)." >&2 + rm -f "$TMP" + exit 1 + fi +done <"$TMP" +rm -f "$TMP" + +echo "verify-admin-dist: OK ($D)"