人生的第一个vite插件
前言
想在控制台输出一下前端代码的一些构建信息, 比如打包时间、打包的人, 代码分支、commit是那个,方便在控制台追溯。
背景
遇到的问题
1、场景一
前端多人协同开发的情况下,比方测试站, 你发的代码, 貌似被人覆盖了,测试说不对啊, 你很烦, 这时你问: 谁发过吗, 没人说话, 倘若控制台可以追溯 谁 在几点 发布了什么 commit信息等等...那就不用迷茫了。
2、打印出来可以帮助排查问题
开发说: 代码发了, 客户说: 我这边还是不行。
开发说: 刷新试试, 客户说: 我都刷了好几次了还是不行。
开发陷入了沉思
这是经常会有的对话
倘若控制台有打包信息,倘若控制台可以追溯 谁 在几点 发布了什么 commit信息等等...那就可以确定代码是发成功了。
插件介绍
vite-plugin-aliyun-flow 流水线打印构建信息插件, 可以准确的在前端控制台看到当前运行代码的构建人、构建时间、分支、最新的COMMIT信息等, 方便追溯线上代码。
插件效果
使用
阿里云效流水线flow
安装
www.npmjs.com/package/vit…
npm i vite-plugin-aliyun-flow --D
复制代码
在vite.config.js/ts中配置
import vitePluginAliFlow from "vite-plugin-aliyun-flow";
// plugins
plugins: [
// 这里只需配置项目名称即可,其他信息都会从流水线自动抓取
vitePluginAliFlow({ projectName: '绩效'}),
...
]
复制代码
插件参数
目前版本只有一个项目名称配置
interface options {
projectName?: string; // 项目名称 没有配置的话会取 package.json里的name字段
}
复制代码
实现思路
确定输出的信息列表
1、打包时间 buildTime
我的思路是vite插件执行的时候获取当前时间就可以, 就是打包时间。
2、构建时nodejs的版本
这个我们用的是阿里云流水线, 我在想应该可以在流水线的运行时,全局变量获取到。
3、分支信息
同上
4、commit信息
同上
5、流水线执行人
同上
从流水线运行时, 获取环境变量里用的到的数据
1、打印一下 process.env 查看有哪儿些信息
信息量有点大呀
或者查看阿里云文档也可以 help.aliyun.com/document_de…
2、 找寻我们需要的子段
CI_RUNTIME_VERSION // 构建时nodejs的版本
EXECUTOR_NAME // 流水线执行人
CI_COMMIT_REF_NAME // 分支名
CI_COMMIT_TITLE // commit信息中文
CI_COMMIT_ID // commit哈希
复制代码
写vite插件
vite插件文档 cn.vitejs.dev/guide/api-p…
我这个用一句话概括就是在打包的时候拿到了我要的信息,然后组装成了js字符串,插到了index.html
的script
标签里,运行中的时候可以执行就行了。
1、代码中获取流水线环境变量
process.env 为什么可以获取,因为打包的时候是用nodejs打包, process.env就是获取执行时环境变量的
const env = process.env
复制代码
2、创建输出的js文件
这边单独写了个js文件, 写这些个输出
内容如下, 并且通过style给console加了颜色 背景 字体大小
最后通过插件读取这个js字符串, 和变量拼在一起。
// 1. 将css样式内容放入数
const styles = [
'color: white',
'background: green',
'font-size: 19px',
'border: 1px solid #fff',
'text-shadow: 2px 2px black',
'padding: 5px',
].join(';');
console.log(`%c${__APP_INFO__.projectName}, 当前版本: V${__APP_INFO__.pkg.version}`, styles);
console.log(
`%c打包时间: ${__APP_INFO__.lastBuildTime}`,
styles,
);
console.log(__GLOBAL_ENV_, __GLOBAL_ENV_);
console.log(`%c构建Node.js版本: ${__GLOBAL_ENV_.CI_RUNTIME_VERSION || '-'}`, styles);
console.log(`%c流水线执行人: ${__GLOBAL_ENV_.EXECUTOR_NAME || '-'}`, styles);
console.log(`%c分支: ${__GLOBAL_ENV_.CI_COMMIT_REF_NAME || '-'}`, styles);
console.log(
`%cCOMMIT信息: ${__GLOBAL_ENV_.CI_COMMIT_TITLE || '-'} ${
__GLOBAL_ENV_.CI_COMMIT_ID || '-'
}`,
styles,
);
复制代码
3、拿到需要的信息, 拼接js字符串
extStr 就是上一步的js字符串
而后通过 htmlStr
把 __APP_INFO__
、__GLOBAL_ENV_
(这两是咱们要的信息)和 extStr 组装了起来。
// 获取环境变量
const env = process.env
// 获取当前项目包信息
const pkg: any = fs.readFileSync(process.cwd() + '/package.json', 'utf-8')
// 获取输出的js文件
const extStr: string = fs.readFileSync(path.join(__dirname, '../src/external.js'), 'utf-8')
const { name, version } = JSON.parse(pkg);
// 项目名称、 版本号、打包时间
const __APP_INFO__ = {
projectName: options.projectName || name,
pkg: { name, version },
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
};
// 把输出的变量一起拼接js字符串
const HtmlStr: string = `const __GLOBAL_ENV_ = ${JSON.stringify(env)};
const __APP_INFO__ = ${JSON.stringify(__APP_INFO__)};
\n ${extStr}`
复制代码
4、输出到index.html的body下面
transformIndexHtml vite暴露的方法,可以修改输出的index.html
如下就是 把HtmlStr放在script标签里输出到html的body下
transformIndexHtml(html): HtmlTagDescriptor[] {
return [
{
tag: 'script',
attrs: { defer: true },
children: HtmlStr,
injectTo: 'body'
},
]
}
复制代码
完整代码
import type { Plugin, HtmlTagDescriptor } from 'vite';
import dayjs from 'dayjs';
import path from 'path';
import fs from 'fs';
interface AliflowOptions {
projectName?: string
}
export default function Aliflow(options: AliflowOptions): Plugin {
// 流水线环境变量
const env = process.env
// 当前项目包信息
const pkg: any = fs.readFileSync(process.cwd() + '/package.json', 'utf-8')
// 输出的js
const extStr: string = fs.readFileSync(path.join(__dirname, '../src/external.js'), 'utf-8')
const { name, version } = JSON.parse(pkg);
// 项目名称、包版本、打包时间等
const __APP_INFO__ = {
projectName: options.projectName || name,
pkg: { name, version },
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
};
// 拼接输出的js字符串 最后查到script标签里
const HtmlStr: string = `const __GLOBAL_ENV_ = ${JSON.stringify(env)};
const __APP_INFO__ = ${JSON.stringify(__APP_INFO__)};
\n ${extStr}`
return {
name: 'vite-plugin-aliuyun-flow',
apply: 'build',
transformIndexHtml(html): HtmlTagDescriptor[] {
// 将htmlStr插到body里
return [
{
tag: 'script',
attrs: { defer: true },
children: HtmlStr,
injectTo: 'body'
},
]
}
};
}
复制代码
总结
以上我们通过写vite插件注入打包信息, 让线上项目控制台可以追溯构建信息, 更好的排查问题。