vite-plugin-git-build-info
v1.0.0
Published
Inject stable Git and build metadata into Vite build outputs.
Maintainers
Readme
vite-plugin-git-build-info
在 Vite 构建期间读取稳定的 Git / Build Context,并将其注入 HTML 或输出为文本文件。
插件只在 vite build 中运行,不提供 Runtime API,也不会引入 Git SDK 或 HTML Parser。
Installation
pnpm add -D vite-plugin-git-build-info要求:
- 使用 Vite 5 / 6 时为 Node.js 18 或更高版本;Vite 7 需要 Node.js 20.19+ 或 22.12+
- Vite 5、6 或 7
- 构建环境可以执行 Git CLI
Quick Start
import { defineConfig } from 'vite'
import gitBuildInfo from 'vite-plugin-git-build-info'
export default defineConfig({
plugins: [
gitBuildInfo({
html: context => [
{
tag: 'meta',
attrs: {
name: 'commitId',
content: context.commitId
},
injectTo: 'head'
}
]
})
]
})执行 vite build 后,最终 HTML 中将包含:
<meta name="commitId" content="<当前完整 Git Commit SHA>">Build Context
一次构建只创建一个 BuildContext。同次构建中的所有 html 和 file.content 回调共享该对象,因此 Commit ID 和构建时间保持一致。
interface BuildContext {
commitId: string
shortCommitId: string
branch: string
tag?: string
dirty: boolean
buildTime: string
committerDate?: string
}字段语义:
commitId:完整 Commit SHA。shortCommitId:由git rev-parse --short HEAD返回的短 SHA。branch:当前分支;detached HEAD 时为''。tag:当前 HEAD 精确对应的 Tag;没有时为undefined。如果存在多个 Tag,返回按创建时间倒序排列的第一个。dirty:已跟踪或未跟踪文件存在未提交变化时为true;ignored 文件不计入。buildTime:本次构建开始时生成的 ISO 8601 时间。committerDate:当前 Commit 的提交者日期,采用 Git 严格 ISO 8601 格式并保留原始时区偏移;它反映当前 Commit 对象形成或最后被改写的时间。Git fallback 未提供时为undefined。
Git 仓库不必与 Vite root 相同。插件从 Vite root 开始,交由 Git 向上识别仓库根目录,适用于常见 monorepo 结构。
HTML
html 直接返回 Vite 官方的 HtmlTagDescriptor[],支持 head、head-prepend、body 和 body-prepend:
gitBuildInfo({
html: context => [
{
tag: 'script',
attrs: {
id: 'build-info',
type: 'application/json'
},
children: JSON.stringify(context),
injectTo: 'head'
}
]
})插件不转换或限制 Descriptor,标签渲染和属性转义由 Vite 处理。多页面构建时,每个经过 Vite transformIndexHtml 的 HTML 都会收到同一 Build Context 生成的标签。
回调的第二个参数是 Vite 原生 IndexHtmlTransformContext,可通过 page.path 控制只注入特定页面:
gitBuildInfo({
html: (context, page) => {
if (page.path !== '/admin.html') {
return []
}
return [
{
tag: 'meta',
attrs: { name: 'commitId', content: context.commitId },
injectTo: 'head'
}
]
}
})部分框架会自行处理 HTML 入口而不调用 Vite 的 transformIndexHtml,此时 html 不会生效;file 不受影响。
File
gitBuildInfo({
file: {
output: 'version.txt',
content: context => context.commitId
}
})output 相对于 Vite build.outDir。文件通过构建系统的 asset emission 能力生成,不直接写入项目目录。
content 必须同步返回字符串。JSON 不属于特殊类型,可直接使用 JSON.stringify。
子目录
gitBuildInfo({
file: {
output: 'meta/build-info.json',
content: context => JSON.stringify(context, null, 2)
}
})输出结果为 dist/meta/build-info.json,或者位于用户配置的其他 build.outDir 下。
出于安全考虑,绝对路径、Windows 盘符路径、包含 .. 的越界路径、Windows 保留文件名和跨平台非法文件名都会终止构建。
Multiple Files
gitBuildInfo({
file: [
{
output: 'version.txt',
content: context => context.commitId
},
{
output: 'build-info.json',
content: context => JSON.stringify(context, null, 2)
}
]
})同一插件配置中不允许出现规范化后相同的 output。如果 output 已被 Vite 或其他插件生成的构建产物占用,构建也会明确失败,不会静默覆盖。
TypeScript
包提供完整类型声明,并直接引用 Vite 的 HtmlTagDescriptor 类型:
import gitBuildInfo, {
type BuildContext,
type FileOutput,
type PluginOptions
} from 'vite-plugin-git-build-info'CI / Docker
默认情况下,缺少 .git、未安装 Git,或者无法取得核心 Commit 信息会终止构建,并给出带 [vite-plugin-git-build-info] 前缀的错误。
如果希望没有 Git 时仍生成版本信息,可以显式设置静态 fallback:
gitBuildInfo({
fallback: {
commitId: process.env.GITHUB_SHA!,
branch: process.env.GITHUB_REF_NAME,
dirty: false
}
})也可以使用同步函数。函数只会在核心 Git 信息读取失败时执行:
gitBuildInfo({
fallback: () => ({
commitId: process.env.GITHUB_SHA ?? process.env.CI_COMMIT_SHA ?? '',
branch: process.env.GITHUB_REF_NAME ?? process.env.CI_COMMIT_REF_NAME,
dirty: false,
committerDate: process.env.CI_COMMIT_TIMESTAMP
})
})fallback 必须提供非空 commitId 和明确的 dirty 值;shortCommitId 未提供时取 Commit ID 前七位。Git 可用时 fallback 不会执行。fallback 缺失或无效时,才由 onGitError 决定是终止构建还是跳过全部插件输出。插件不会用空字符串伪造 Commit ID 或提交者日期。
第一版不会自动识别 CI Provider 环境变量;Docker 构建可手动传入 CI 环境变量,或将 .git 提供给构建阶段。
API
gitBuildInfo(options?)
interface PluginOptions {
html?: (
context: BuildContext,
page: IndexHtmlTransformContext
) => HtmlTagDescriptor[]
file?: FileOutput | FileOutput[]
fallback?: FallbackContext | FallbackResolver
onGitError?: 'error' | 'warn'
}
interface FileOutput {
output: string
content: (context: BuildContext) => string
}
interface FallbackContext {
commitId: string
shortCommitId?: string
branch?: string
tag?: string
dirty: boolean
committerDate?: string
}
type FallbackResolver = () => FallbackContext | undefinedonGitError 默认为 'error':
'error':核心 Git 信息不可用时终止构建。'warn':记录 warning,继续构建,并跳过插件的全部输出。
分支、Tag、工作区状态属于非核心字段。读取失败时插件会 warning,并分别使用 ''、undefined、false。
FAQ
为什么只支持 build?
该插件描述的是一次构建产物的 Git 和时间信息。限定为 build 可以让 Context 生命周期和输出结果保持明确稳定。
为什么不直接提供 JSON 配置?
content 已允许将 Context 转换成任意文本,JSON.stringify(context) 即可覆盖 JSON 场景,无需增加格式 DSL。
为什么我的框架没有注入 HTML?
html 依赖 Vite transformIndexHtml。如果框架绕过该 Hook 或自行生成 HTML,需要使用框架提供的集成方式;本插件首版不提供 SSR 或框架 Runtime 集成。
浅克隆可以使用吗?
只要当前 checkout 包含有效 HEAD,读取 Commit、分支和工作区状态通常不需要完整历史。当前 HEAD 没有精确 Tag 时,tag 为 undefined。
Build Context 会泄露隐私信息吗?
插件不会自动将任何 Context 写入构建产物;只有 html 或 file.content 回调显式使用字段时,这些字段才会被公开。当前 Context 不读取作者姓名、邮箱、提交 message、环境变量内容或本机绝对路径。
如果仓库、分支名或 Commit SHA 不应公开,请不要将对应字段写入 HTML、JSON 或其他公开文件。fallback 函数也只应返回版本元数据,绝不能返回 token、密码、私钥或其他 secret。
