
本文介绍一种可靠、安全且无需暴露私有仓库 api 凭据的方式,通过构建时(build-time)执行 git 命令自动注入最新提交时间,实现在静态网站中动态显示「最后更新于 xxx」。
本文介绍一种可靠、安全且无需暴露私有仓库 api 凭据的方式,通过构建时(build-time)执行 git 命令自动注入最新提交时间,实现在静态网站中动态显示「最后更新于 xxx」。
在私有 github 仓库托管内容的静态网站(如 Jekyll、Hugo、Next.js、VuePress 或纯 HTML/JS 站点)中,直接调用 GitHub REST API 获取 last_updated 时间不可行——因为私有仓库要求认证,而前端无法安全地嵌入 Token;同时,客户端发起跨域请求也会被浏览器策略拦截。因此,服务端或构建时方案才是唯一推荐路径。
✅ 推荐方案:构建时注入 Git 最新提交时间
核心思路:在 CI/CD 流水线(如 GitHub Actions、gitlab CI、Vercel Build、Netlify Build)或本地构建脚本中,执行 git log -1 –format=”%ad” –date=short 获取仓库最近一次提交日期,并将其注入 HTML 模板或 json 元数据中。
示例:通用 Shell 脚本(适用于任意静态站点)
# build.sh(运行于构建环境) LAST_COMMIT_DATE=$(git log -1 --format="%ad" --date=short 2>/dev/null) echo "Last updated: $LAST_COMMIT_DATE" # 替换 HTML 中的占位符(如 <!-- LAST_UPDATED -->) sed -i "s/<!-- LAST_UPDATED -->/Last updated: $LAST_COMMIT_DATE/g" dist/index.html
示例:Jekyll(使用 _config.yml + site.time 或自定义变量)
在 _config.yml 中添加:
# _config.yml last_updated: "{{ 'now' | date: '%Y-%m-%d' }}"
但更准确的做法是:在构建前用脚本生成 _data/last_updated.yml:
# generate-last-updated.sh echo "date: $(git log -1 --format='%Y-%m-%d')" > _data/last_updated.yml
然后在模板中使用:
<!-- _layouts/default.html --> <footer class="update-indicator"> Last updated: {{ site.data.last_updated.date }} </footer>
示例:React/Vite/Next.js(构建时注入环境变量)
在 vite.config.ts 或构建脚本中读取 Git 信息:
// vite.config.ts(Vite 示例) import { defineConfig } from 'vite'; import { execSync } from 'child_process'; const lastUpdated = execSync('git log -1 --format="%ad" --date=short', { encoding: 'utf-8', }).trim(); export default defineConfig({ define: { __LAST_UPDATED__: JSON.stringify(lastUpdated), }, });
在组件中使用:
// Footer.tsx export default function Footer() { return ( <footer> Last updated: {__LAST_UPDATED__} </footer> ); }
⚠️ 注意事项与最佳实践
- 确保工作目录为 Git 仓库根路径:CI 环境中需确认 git 命令执行位置(例如 GitHub Actions 默认检出完整仓库,但某些平台可能需显式 git fetch –depth=1)。
- 避免硬编码敏感逻辑到前端:切勿尝试在浏览器中调用 /api/v3/repos/… —— 即使使用 token,也存在泄露风险且违反 CORS。
- 考虑多分支场景:若部署基于 main 分支,应限定 git log -1 origin/main;若使用预发布分支,需同步调整命令。
- 提升可读性与国际化:可扩展为 git log -1 –format=”%aD” 获取英文全格式,或用 Intl.DateTimeFormat() 在前端做本地化渲染(仅限日期字符串已注入前提下)。
- 缓存友好性:该方案生成的是静态值,完全兼容 CDN 缓存与离线访问。
✅ 总结
“最后更新时间”不是运行时功能,而是构建元数据。它不依赖后端 API、不暴露凭证、不增加首屏延迟,且与现有 CI/CD 流程天然契合。只要你的构建环境能执行 git 命令(绝大多数现代平台均支持),即可在数分钟内完成集成——简洁、安全、可持续维护。