前端动态生成Git_Tag原理
🧾 组件打包信息写入工具:Git Tag Writer
该脚本用于自动遍历组件目录 ./src/widgets/*/
,获取每个组件的 Git 信息(commit、branch、user.name),并将其写入 dist/{组件名}/version.tag
文件中。便于后期发布版本追踪、回溯打包信息。
功能简介
功能 | 描述 |
---|---|
遍历组件路径 | 通过 glob 匹配 ./src/widgets/*/ |
获取组件对应 Git 信息 | 提取 commit , branch , userName |
写入版本标记文件 | 输出到 dist/{widget}/version.tag |
判断是否已构建成功 | 若未找到 index.js ,则不写入 version.tag 文件 |
目录结构预期
src/
└── widgets/
├── widgetA/
├── widgetB/
dist/
└── widgetA/
└── index.js <- 存在则写入 version.tag
核心方法说明
getWidgetsPath()
步骤 | 说明 |
---|---|
1. glob | 匹配所有组件路径 ./src/widgets/*/ |
2. Git | 执行 git rev-parse 和 git config 获取信息 |
3. 写文件 | 若 dist/{组件}/index.js 存在,则写入 tag 文件 |
getGitInfo(cwd: string)
返回该组件目录下的 Git 信息对象:
{
commit: 'abc123',
branch: 'main',
userName: 'yourname'
}
输出示例
{
"commit": "c7e5a4f",
"branch": "feature/widgetA",
"userName": "alice"
}
代码实现如下:
import { globSync } from 'glob'
import { execa } from 'execa'
import slash from 'slash'
import path from 'path'
import fs from 'fs-extra'
const getWidgetsPath = async () => {
const widgetsPath = globSync(`./src/widgets/*/`)
for (let index = 0; index < widgetsPath.length; index++) {
const widgetPath = slash(widgetsPath[index])
const slashCwd = slash(process.cwd())
const cwd = slash(path.resolve(slashCwd, widgetPath))
const gitInfo = await getGitInfo(cwd)
const wPaths = widgetPath.split('/')
const widgetName = wPaths[wPaths.length - 1]
if (widgetName) {
const tag = {
commit: gitInfo.commit?.stdout,
branch: gitInfo.branch?.stdout,
userName: gitInfo.userName?.stdout,
}
const widgetTagFile = slash(
path.resolve(slashCwd, `dist/${widgetName}/version.tag`)
)
const widgetFile = slash(
path.resolve(slashCwd, `dist/${widgetName}/index.js`)
)
const isExist = fs.existsSync(widgetFile)
if (isExist) {
fs.writeJsonSync(widgetTagFile, tag)
}
}
}
}
/**
* 获取git信息
* @returns
*/
const getGitInfo = async (cwd) => {
const option = {
cwd,
}
async function getGitHash() {
return await execa('git', ['rev-parse', '--short', 'HEAD'], option)
}
async function getGitBranch() {
return execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], option)
}
async function getGitUserName() {
return execa('git', ['config', 'user.name'], option)
}
try {
const commit = await getGitHash()
const branch = await getGitBranch()
const userName = await getGitUserName()
return {
commit,
branch,
userName,
}
} catch (error) {
console.error(error)
return {}
}
}
const start = getWidgetsPath
export default start