最近在项目中做了个优化项,就是打包时自动更新版本号,在页面上展示当前应用的版本信息。
- 版本号 :来自
package.json
,方便业务层面区分不同版本。 - commitId:来自 Git,表示当前版本号对应代码仓库里的具体提交。
最终效果大概是这样的:
scss
当前版本:v1.2.3 (a1b2c3d)
实现步骤
1. 使用 npm version
管理版本
在发版时,不要手动改 package.json
,而是用 npm 自带的 npm version
命令
perl
# 小版本更新
npm version patch -m "chore(release): %s"
# 中版本更新
npm version minor -m "chore(release): %s"
# 大版本更新
npm version major -m "chore(release): %s"
执行后会自动:
- 修改
package.json
和package-lock.json
的版本号 - 打 git tag
- 生成一次 commit,tag 与版本号强绑定
这样可以保证版本号和 git 历史保持一致。
css
# 推送代码和 tag
git push origin main --tags
2. 获取 tag 版本对应的 commitId
javascript
import { execSync } from 'child_process';
function getCommitId(version: string) {
try {
// 获取 tag 对应的 commitId
return execSync(`git rev-parse --short v${version}^{}`).toString().trim();
} catch {
// 如果 tag 不存在
throw new Error(`Tag v${version} 不存在,请先执行 npm version 并推送 tag`);
}
}
3. 将版本信息注入到打包结果
在 vite.config.ts
里进行配置:
javascript
import { defineConfig } from 'vite';
import pkg from './package.json';
const version = pkg.version;
const commitId = getCommitId(version);
export default defineConfig({
define: {
__APP_VERSION__: JSON.stringify(version),
__APP_COMMIT__: JSON.stringify(commitId),
},
});
4. 页面展示
javascript
export default function AppVersion() {
return (
<footer>
<p>
版本号: {__APP_VERSION__} (commit: {__APP_COMMIT__})
</p>
</footer>
);
}
这样每次发版,页面都会展示正确的版本号和对应的 commitId。
提示
页面中使用 APP_VERSION 和 APP_COMMIT 时,TS 报错: TS2304: Cannot find name __COMMIT_ID__
src 目录下添加类型声明即可解决
php
// env.d.ts
/// <reference types="vite/client" />
declare const __APP_VERSION__: string
declare const __COMMIT_ID__: string
git rev-parse --short v${version}^{} 命令解析
作用: 解析一个 revision(tag/branch/HEAD/commit)到 commitId。
--short
: 输出 短格式(默认前 7 位)
为什么要写 ^{} :
执行 npm version patch
时,Git 会创建一个 注解标签(annotated tag) ,这种标签会:
- 创建一个标签对象
- 创建一个标签引用(指向标签对象)
所以当执行 git ls-remote --tags origin
可以看到远程仓库中有两个 tag:

refs/tags/v1.0.2
- 标签对象refs/tags/v1.0.2^{}
- 实际的提交
最终在仓库中看到的 commitId 是带 ^{} 。所以在通过 tag 获取 commitId 的时候也要带上 ^{} 。
也可以通过 git rev-list -1 v${version}
获取到完整的 commitId 手动截取成短的。