简简单单一个vite⚡⚡插件搞定用户的另类需求——自给自足的感觉真好
文章同步在公众号:萌萌哒草头将军,欢迎关注!
需求背景
前几天我们的客户对我们组的客户经理提了个需求,每次上线前端页面需要在HTML里给定版本信息,因为我们客户单位会定期爬取版本信息进行汇总展示在大屏。
版本信息要求如下:
- 上线日期
- 上线内容描述
- 对应git提交ID
- 对应项目的版本号
调研
我立马想到使用插件,前几天我已经将项目脚手架换成vite了,我找了一圈,发现了几个相似的需求,不过都是直接生成 meta 标签,跟我的需求不符
(我的需求是让版本信息成为入口标签的属性),
他们分别是下面几个库,希望可以帮到大家
https://www.npmjs.com/package/vite-plugin-version-mark
https://www.npmjs.com/package/git-commit-info-plugin
可以满足我的需求的插件基本上没有
推荐上篇 面对躺平同事,我开发了一个vite插件,治好了我的精神内耗
基于前面几次的插件经验,我又打算自己开发插件满足自己的需求。
实现
下面是我本地的初始版本,使用 vite 特有的钩子 transformIndexHtml ,
我们通过 childProcess 同步的方式访问 git 信息,
通过 jsdom 库将html字符串转化为 dom 对象插入信息,最后序列化为字符串返回即可。
import childProcess from 'child_process';
import { JSDOM } from 'jsdom';
import moment from 'moment';
const AddCommitAndVersion = () => {
return {
name: 'add-commit-and-version',
transformIndexHtml (html) {
const commitID = childProcess.execSync('git rev-parse --short HEAD', { encoding: 'utf-8' })
const commitInfo = childProcess.execSync('git log -3 --pretty="%s"', { encoding: 'utf-8' })
const dom = new JSDOM(html)
const document = dom.window.document
const container = document.getElementById('root')
container.setAttribute("commitID", commitID.trim());
container.setAttribute("verion", moment(new Date()).format(`YYYY.MM.DD.HH:mm:ss`));
container.setAttribute("description", commitInfo.trim().split('\n').toString());
return dom.serialize()
}
}
}
为了可以让更多的人方便用,我们在此基础上提供更多的灵活性。所以我们定义如下的签名
interface OptionProps {
/**
* 挂载信息的节点,该值为 querySelector 参数
* 默认:body标签
*/
root?: string
/**
* moment日期格式
* 默认:YYYY-MM-DD HH:mm:ss
*/
dateFormat?: string
/**
* commitID,如果为true,则表示禁用,不显示
* 默认:打包分支,最后一次提交commitID
*/
commitID?: string | true
/**
* 版本号,如果为true,则表示禁用,不显示
* 默认: 打包时间,格式取决于 dateFormat
*/
verion?: string | true
/**
* 版本描述,如果为true,则表示禁用,不显示
* 默认: 最近三次commit内容,使用`、`隔开
*/
description?: string | true
/**
* 扩展字段
* 默认 null
*/
extendInfo?: {[key in string]: string}
}
除了预设的信息外,我还新增了扩展信息的字段,方便面对更多需求。
扩展之后的代码如下,主要是解析配置文件。
import childProcess from 'child_process';
import { JSDOM } from 'jsdom';
import moment from 'moment';
export default (option) => {
let {
dateFormat = `YYYY.MM.DD.HH:mm:ss`,
commitID,
verion,
description,
extendInfo = {},
root = 'body'
} = option ?? {}
return {
name: 'vate-plugin-add-commit-info',
transformIndexHtml (html) {
const dom = new JSDOM(html)
const document = dom.window.document
const container = document.querySelector(root)
// 最后一次提交commit的ID
if (commitID !== true) {
commitID = commitID
? commitID
: childProcess.execSync('git rev-parse --short HEAD', { encoding: 'utf-8' })
container?.setAttribute("commitID", commitID.trim());
}
// 版本信息,默认是当前打包的时间点
if (verion !== true) {
container?.setAttribute("verion", verion ?? moment(new Date())?.format(dateFormat))
}
// 描述信息,默认最近三次的commit描述
if (description !== true) {
description = description
? description
: childProcess
.execSync('git log -3 --pretty="%s"', { encoding: 'utf-8' })
.trim()
.split('\n')
.toString()
container?.setAttribute("description", description)
}
// 自定义扩展字段
if (extendInfo) {
const keys = Object.keys(extendInfo)
if (keys.length) {
keys.map(key => container?.setAttribute(key, extendInfo[key]))
}
}
return dom.serialize()
}
}
}
默认效果如下
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import addCommitInfo from 'vite-plugin-add-commit-info';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
addCommitInfo(),
react()
]
})
当使用配置时效果如下
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import addCommitInfo from 'vite-plugin-add-commit-info';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
addCommitInfo({
root: '#root',
description: 'test'
}),
react()
]
})
最后
我已经开源了,感兴趣的小伙伴可以下载体验一番。
npm地址:https://www.npmjs.com/package/vite-plugin-add-commit-info
github地址:https://github.com/mmdctjj/vite-plugin-add-commit-info
今天的分享就到这了,文章中有纰漏的地方欢迎指正。