需求背景
前几天我们的客户对我们组的客户经理提了个需求,每次上线前端页面需要在HTML里给定版本信息,因为我们客户单位会定期爬取版本信息进行汇总展示在大屏。
版本信息要求如下:
- 上线日期
- 上线内容描述
- 对应git提交ID
- 对应项目的版本号
调研
我立马想到使用插件,前几天我已经将项目脚手架换成vite了,我找了一圈,发现了几个相似的需求,不过都是直接生成 meta 标签,跟我的需求不符
(我的需求是让版本信息成为入口标签的属性),
他们分别是下面几个库,希望可以帮到大家
https://www.npmjs.com/package/vite-plugin-version-mark
https://www.npmjs.com/package/git-commit-info-plugin
可以满足我的需求的插件基本上没有
基于前面几次的插件经验,我又打算自己开发插件满足自己的需求。
实现
下面是我本地的初始版本,使用 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
今天的分享就到这了,文章中有纰漏的地方欢迎指正。