Frontend Dynamic Git Tag Generation Principle
๐งพ Component Packaging Info Writer Tool: Git Tag Writerโ
This script is used to automatically traverse the component directory ./src/widgets/*/, obtain the Git information (commit, branch, user.name) of each component, and write it to the dist/{widgetName}/version.tag file. It facilitates subsequent version tracking and backtracking of packaging information.
Function Introductionโ
| Function | Description |
|---|---|
| Traverse component path | Match ./src/widgets/*/ via glob |
| Get component Git info | Extract commit, branch, userName |
| Write version tag file | Output to dist/{widget}/version.tag |
| Determine if build succeeded | If index.js is not found, do not write version.tag file |
Directory Structure Expectationโ
src/
โโโ widgets/
โโโ widgetA/
โโโ widgetB/
dist/
โโโ widgetA/
โโโ index.js <- Write version.tag if exists
Core Method Explanationโ
getWidgetsPath()โ
| Step | Description |
|---|---|
| 1. glob | Match all component paths ./src/widgets/*/ |
| 2. Git | Execute git rev-parse and git config to get info |
| 3. Write file | If dist/{component}/index.js exists, write tag file |
getGitInfo(cwd: string)โ
Returns the Git information object under the component directory:
{
commit: 'abc123',
branch: 'main',
userName: 'yourname'
}
Output Example
{
"commit": "c7e5a4f",
"branch": "feature/widgetA",
"userName": "alice"
}
Code implementation follows:
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)
}
}
}
}
/**
* Get git info
* @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