vite-plugin-build-version-file 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +555 -272
- package/dist/index.cjs +25 -2
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.mjs +25 -2
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,34 +1,33 @@
|
|
|
1
1
|
# vite-plugin-build-version-file
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
一个用于 Vite 项目的构建版本信息插件。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
它负责在开发态和构建产物中暴露统一的版本信息:
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- 开发态通过 dev server 提供 `version.json`
|
|
8
|
+
- 构建后在输出目录生成 `version.json`
|
|
9
|
+
- 普通 Vite HTML 自动注入 `window["__VERSION__"]`
|
|
10
|
+
- VitePress 可通过顶层 `transformHtml` 注入同一份版本信息
|
|
11
|
+
- 支持自定义版本号、输出文件名、全局变量名、时区和额外字段
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
插件只负责生成和暴露版本信息,不负责运行时更新策略。
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
它不会内置这些业务行为:
|
|
14
16
|
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
+
- 定时轮询新版本
|
|
18
|
+
- 弹窗提示用户刷新
|
|
17
19
|
- 用户取消后的重试策略
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
适合用在这些场景:
|
|
20
|
+
- 自动刷新页面的时机
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
- 检测线上是否有新版本并提示刷新
|
|
24
|
-
- 灰度发布时对比本地版本和服务端版本
|
|
22
|
+
这些行为通常应放在业务项目中实现。
|
|
25
23
|
|
|
26
24
|
## 适用范围
|
|
27
25
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
26
|
+
- Vite 项目
|
|
27
|
+
- Vue 3 + Vite 项目
|
|
28
|
+
- VitePress 项目
|
|
30
29
|
- `peerDependencies` 要求 `vite >= 5`
|
|
31
|
-
-
|
|
30
|
+
- Node.js 要求 `>= 18`
|
|
32
31
|
|
|
33
32
|
## 安装
|
|
34
33
|
|
|
@@ -36,7 +35,7 @@
|
|
|
36
35
|
pnpm add vite-plugin-build-version-file
|
|
37
36
|
```
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
也可以使用 npm:
|
|
40
39
|
|
|
41
40
|
```bash
|
|
42
41
|
npm install vite-plugin-build-version-file
|
|
@@ -44,28 +43,56 @@ npm install vite-plugin-build-version-file
|
|
|
44
43
|
|
|
45
44
|
## 快速开始
|
|
46
45
|
|
|
46
|
+
### 普通 Vite / Vue 3 项目
|
|
47
|
+
|
|
47
48
|
```ts
|
|
48
49
|
import { defineConfig } from 'vite'
|
|
49
50
|
import vue from '@vitejs/plugin-vue'
|
|
50
51
|
import buildVersionPlugin from 'vite-plugin-build-version-file'
|
|
51
52
|
|
|
52
53
|
export default defineConfig({
|
|
53
|
-
plugins: [
|
|
54
|
+
plugins: [
|
|
55
|
+
vue(),
|
|
56
|
+
buildVersionPlugin()
|
|
57
|
+
]
|
|
54
58
|
})
|
|
55
59
|
```
|
|
56
60
|
|
|
61
|
+
### VitePress 项目
|
|
62
|
+
|
|
63
|
+
VitePress 构建 HTML 时不完全走普通 Vite `index.html` 注入链路。需要复用同一个插件实例,并把它的 `transformHtml` 接到 VitePress 顶层配置上。
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
import { defineConfig } from 'vitepress'
|
|
67
|
+
import buildVersionPlugin from 'vite-plugin-build-version-file'
|
|
68
|
+
|
|
69
|
+
const buildVersion = buildVersionPlugin()
|
|
70
|
+
|
|
71
|
+
export default defineConfig({
|
|
72
|
+
vite: {
|
|
73
|
+
plugins: [buildVersion],
|
|
74
|
+
},
|
|
75
|
+
transformHtml: buildVersion.transformHtml,
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
注意:这里必须复用同一个 `buildVersion` 实例。不要分别调用两次 `buildVersionPlugin()`,否则 `transformHtml` 拿不到 Vite 插件阶段生成的 payload。
|
|
80
|
+
|
|
57
81
|
## 默认行为
|
|
58
82
|
|
|
59
|
-
|
|
83
|
+
默认配置下,插件会做这些事:
|
|
60
84
|
|
|
61
85
|
- 开发态访问 `/version.json` 时返回版本信息
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
86
|
+
- 构建后输出 `version.json`
|
|
87
|
+
- 向 HTML 注入 `window["__VERSION__"]`
|
|
88
|
+
- 自动读取业务项目最近的 `package.json`
|
|
89
|
+
- 将 `package.json` 的 `name` 写入 `pkgName`
|
|
90
|
+
- 将 `package.json` 的 `version` 写入 `pkgVersion`
|
|
65
91
|
- 开发态默认版本号为 `0`
|
|
66
|
-
-
|
|
92
|
+
- 构建态默认版本号为当前时间,格式为 `YYYYMMDDHHmmss`
|
|
93
|
+
- 默认时区为 `Asia/Shanghai`
|
|
67
94
|
|
|
68
|
-
|
|
95
|
+
构建态默认输出示例:
|
|
69
96
|
|
|
70
97
|
```json
|
|
71
98
|
{
|
|
@@ -76,7 +103,7 @@ export default defineConfig({
|
|
|
76
103
|
}
|
|
77
104
|
```
|
|
78
105
|
|
|
79
|
-
|
|
106
|
+
开发态默认输出示例:
|
|
80
107
|
|
|
81
108
|
```json
|
|
82
109
|
{
|
|
@@ -87,29 +114,6 @@ export default defineConfig({
|
|
|
87
114
|
}
|
|
88
115
|
```
|
|
89
116
|
|
|
90
|
-
## 职责边界
|
|
91
|
-
|
|
92
|
-
这个库的职责是:
|
|
93
|
-
|
|
94
|
-
- 生成版本号
|
|
95
|
-
- 输出 `version.json`
|
|
96
|
-
- 向页面注入版本信息
|
|
97
|
-
- 让业务代码能读取当前版本
|
|
98
|
-
|
|
99
|
-
这些逻辑建议写在业务项目里,而不是放进这个库里:
|
|
100
|
-
|
|
101
|
-
- 多久检查一次新版本
|
|
102
|
-
- 请求失败后是否重试
|
|
103
|
-
- 用什么 UI 提示用户
|
|
104
|
-
- 用户点击取消后怎么处理
|
|
105
|
-
- 是否立即刷新页面
|
|
106
|
-
|
|
107
|
-
如果你的项目要做“检测到新版本后提示刷新”,推荐做法是:
|
|
108
|
-
|
|
109
|
-
- 用 `window["__VERSION__"]` 读取当前页面版本
|
|
110
|
-
- 请求 `version.json` 读取服务端版本
|
|
111
|
-
- 在业务项目里自行决定提示方式和刷新时机
|
|
112
|
-
|
|
113
117
|
## 配置项
|
|
114
118
|
|
|
115
119
|
```ts
|
|
@@ -125,6 +129,8 @@ type BuildVersionPluginOptions = {
|
|
|
125
129
|
timeZone?: string
|
|
126
130
|
version?: string | number | ((ctx: BuildVersionContext) => string | number)
|
|
127
131
|
data?: Record<string, any>
|
|
132
|
+
log?: (content: any) => string
|
|
133
|
+
payload?: (json: any) => any
|
|
128
134
|
}
|
|
129
135
|
```
|
|
130
136
|
|
|
@@ -132,13 +138,29 @@ type BuildVersionPluginOptions = {
|
|
|
132
138
|
|
|
133
139
|
- 类型:`string`
|
|
134
140
|
- 默认值:`"version.json"`
|
|
135
|
-
-
|
|
141
|
+
- 作用:控制开发态访问路径和构建态输出文件路径
|
|
142
|
+
|
|
143
|
+
示例:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
buildVersionPlugin({
|
|
147
|
+
filename: 'meta/version.json'
|
|
148
|
+
})
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
构建后输出:
|
|
136
152
|
|
|
137
|
-
|
|
153
|
+
```text
|
|
154
|
+
dist/meta/version.json
|
|
155
|
+
```
|
|
138
156
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
157
|
+
开发态访问:
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
/meta/version.json
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
如果项目配置了 Vite `base`,访问路径会自动跟随 `base`。
|
|
142
164
|
|
|
143
165
|
### `globalName`
|
|
144
166
|
|
|
@@ -154,18 +176,23 @@ type BuildVersionPluginOptions = {
|
|
|
154
176
|
</script>
|
|
155
177
|
```
|
|
156
178
|
|
|
157
|
-
|
|
179
|
+
这里注入的是完整 payload 对象,不是单独版本字符串。
|
|
158
180
|
|
|
159
181
|
### `injectToHtml`
|
|
160
182
|
|
|
161
183
|
- 类型:`boolean`
|
|
162
184
|
- 默认值:`true`
|
|
163
|
-
-
|
|
185
|
+
- 作用:控制是否向 HTML 注入 `window["__VERSION__"]`
|
|
164
186
|
|
|
165
|
-
|
|
187
|
+
设置为 `false` 后,仍会生成和提供 `version.json`。
|
|
166
188
|
|
|
167
|
-
|
|
168
|
-
|
|
189
|
+
### `timeZone`
|
|
190
|
+
|
|
191
|
+
- 类型:`string`
|
|
192
|
+
- 默认值:`"Asia/Shanghai"`
|
|
193
|
+
- 作用:控制默认构建时间按哪个时区生成
|
|
194
|
+
|
|
195
|
+
只影响插件默认生成的 `time`。如果你传了 `version`,则以自定义逻辑为准。
|
|
169
196
|
|
|
170
197
|
### `version`
|
|
171
198
|
|
|
@@ -173,85 +200,274 @@ type BuildVersionPluginOptions = {
|
|
|
173
200
|
- 默认值:开发态为 `0`,构建态为当前时间戳
|
|
174
201
|
- 作用:自定义版本号生成逻辑
|
|
175
202
|
|
|
176
|
-
|
|
203
|
+
```ts
|
|
204
|
+
buildVersionPlugin({
|
|
205
|
+
version: ({ command, mode }) => {
|
|
206
|
+
if (command === 'serve') {
|
|
207
|
+
return 0
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return `${mode}-20260401153045`
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### `data`
|
|
216
|
+
|
|
217
|
+
- 类型:`Record<string, any>`
|
|
218
|
+
- 默认值:`{}`
|
|
219
|
+
- 作用:向最终 payload 追加自定义字段
|
|
177
220
|
|
|
178
221
|
```ts
|
|
222
|
+
buildVersionPlugin({
|
|
223
|
+
data: {
|
|
224
|
+
appName: 'admin',
|
|
225
|
+
gitBranch: 'release/2026-04',
|
|
226
|
+
commitSha: 'abc1234'
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
生成结果示例:
|
|
232
|
+
|
|
233
|
+
```json
|
|
179
234
|
{
|
|
180
|
-
|
|
181
|
-
|
|
235
|
+
"appName": "admin",
|
|
236
|
+
"gitBranch": "release/2026-04",
|
|
237
|
+
"commitSha": "abc1234",
|
|
238
|
+
"pkgName": "your-app-name",
|
|
239
|
+
"pkgVersion": "1.0.0",
|
|
240
|
+
"time": "20260401153045",
|
|
241
|
+
"env": "production"
|
|
182
242
|
}
|
|
183
243
|
```
|
|
184
244
|
|
|
185
|
-
|
|
245
|
+
字段覆盖顺序:
|
|
186
246
|
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
247
|
+
- `data` 会先写入
|
|
248
|
+
- `pkgName`、`pkgVersion` 会使用项目 `package.json` 的值覆盖同名字段
|
|
249
|
+
- `time`、`env` 会使用插件生成的值覆盖同名字段
|
|
250
|
+
- `payload` 可以在最后改写整个结果
|
|
190
251
|
|
|
191
|
-
|
|
252
|
+
### `payload`
|
|
192
253
|
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
- 如果传了 `version`,则以你自己的 `version` 逻辑为准
|
|
254
|
+
- 类型:`(json: any) => any`
|
|
255
|
+
- 作用:最终改写 payload
|
|
196
256
|
|
|
197
|
-
|
|
257
|
+
适合做字段裁剪、字段重命名或兼容旧系统。
|
|
198
258
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
259
|
+
```ts
|
|
260
|
+
buildVersionPlugin({
|
|
261
|
+
payload: (json) => ({
|
|
262
|
+
version: json.time,
|
|
263
|
+
env: json.env,
|
|
264
|
+
name: json.pkgName
|
|
265
|
+
})
|
|
266
|
+
})
|
|
267
|
+
```
|
|
202
268
|
|
|
203
|
-
|
|
269
|
+
建议返回对象,避免业务端读取结构不稳定。
|
|
204
270
|
|
|
205
|
-
|
|
206
|
-
- 查找位置是从当前 Vite 项目根目录开始,向上寻找最近的 `package.json`
|
|
207
|
-
- 会同时影响开发态接口返回、构建产物中的 `version.json` 和注入到 `window` 的对象
|
|
208
|
-
- 如果 `data` 里存在 `time` 或 `env` 同名字段,最终仍以插件生成的值为准
|
|
209
|
-
- 如果 `data` 里存在 `pkgName` 或 `pkgVersion`,读取到业务项目 `package.json` 时会以自动读取的值为准;读取不到时会保留 `data` 里的值
|
|
271
|
+
### `log`
|
|
210
272
|
|
|
211
|
-
|
|
273
|
+
- 类型:`(content: any) => string`
|
|
274
|
+
- 作用:自定义构建完成后的控制台输出
|
|
212
275
|
|
|
213
|
-
|
|
276
|
+
```ts
|
|
277
|
+
buildVersionPlugin({
|
|
278
|
+
log: (payload) => `build version: ${payload.time}`
|
|
279
|
+
})
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## 读取版本信息
|
|
283
|
+
|
|
284
|
+
### 读取全局变量
|
|
214
285
|
|
|
215
286
|
```ts
|
|
216
|
-
|
|
217
|
-
import vue from '@vitejs/plugin-vue'
|
|
218
|
-
import buildVersionPlugin from 'vite-plugin-build-version-file'
|
|
287
|
+
const payload = window['__VERSION__']
|
|
219
288
|
|
|
220
|
-
|
|
221
|
-
|
|
289
|
+
console.log(payload.time)
|
|
290
|
+
console.log(payload.env)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
适用于需要知道“当前页面构建版本”的场景。
|
|
294
|
+
|
|
295
|
+
### 读取 `version.json`
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
const response = await fetch('/version.json', {
|
|
299
|
+
cache: 'no-store'
|
|
222
300
|
})
|
|
301
|
+
const payload = await response.json()
|
|
302
|
+
|
|
303
|
+
console.log(payload.time)
|
|
304
|
+
console.log(payload.env)
|
|
223
305
|
```
|
|
224
306
|
|
|
225
|
-
|
|
307
|
+
适用于和服务器上的最新版本做对比。
|
|
226
308
|
|
|
227
|
-
|
|
228
|
-
- `version` -> `pkgVersion`
|
|
309
|
+
## 做版本检查
|
|
229
310
|
|
|
230
|
-
|
|
311
|
+
插件不内置版本检查 UI。推荐业务项目自行处理:
|
|
231
312
|
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
import buildVersionPlugin from 'vite-plugin-build-version-file'
|
|
313
|
+
```js
|
|
314
|
+
const CHECK_INTERVAL = 60 * 1000
|
|
315
|
+
const VERSION_URL = '/version.json'
|
|
236
316
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
globalName: '__APP_VERSION__'
|
|
317
|
+
async function checkVersion() {
|
|
318
|
+
try {
|
|
319
|
+
const response = await fetch(VERSION_URL, {
|
|
320
|
+
cache: 'no-store'
|
|
242
321
|
})
|
|
243
|
-
|
|
244
|
-
|
|
322
|
+
const latestPayload = await response.json()
|
|
323
|
+
const currentPayload = window.__VERSION__
|
|
324
|
+
|
|
325
|
+
if (currentPayload && latestPayload.time !== currentPayload.time) {
|
|
326
|
+
const shouldReload = window.confirm('检测到新版本,是否刷新页面?')
|
|
327
|
+
|
|
328
|
+
if (shouldReload) {
|
|
329
|
+
window.location.reload()
|
|
330
|
+
return
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
} catch (error) {
|
|
334
|
+
console.warn('check version failed', error)
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
window.setTimeout(checkVersion, CHECK_INTERVAL)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
checkVersion()
|
|
245
341
|
```
|
|
246
342
|
|
|
247
|
-
|
|
343
|
+
建议:
|
|
248
344
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
345
|
+
- 通常比较 `payload.time` 即可
|
|
346
|
+
- 请求 `version.json` 时使用 `cache: 'no-store'`
|
|
347
|
+
- 轮询间隔不要过短,通常 1 分钟或更长
|
|
348
|
+
- 弹窗、通知、静默刷新等策略放在业务项目里
|
|
349
|
+
- 请求失败后继续下一轮检查,避免一次失败中断流程
|
|
350
|
+
|
|
351
|
+
## 开发态行为
|
|
352
|
+
|
|
353
|
+
开发态下,插件不会向业务项目目录写入文件。
|
|
354
|
+
|
|
355
|
+
它会通过 Vite dev server 直接返回 JSON:
|
|
356
|
+
|
|
357
|
+
- 不污染 `public/`
|
|
358
|
+
- 不需要生成临时文件
|
|
359
|
+
- 修改插件配置后重启 dev server 即可生效
|
|
360
|
+
|
|
361
|
+
## 本地开发
|
|
362
|
+
|
|
363
|
+
仓库提供了两个调试用示例项目:
|
|
364
|
+
|
|
365
|
+
- 普通 Vite / Vue 3:`debug/fixture-app`
|
|
366
|
+
- VitePress:`debug/vitepress-app`
|
|
367
|
+
- 引用方式:直接引用根目录 `dist/index.mjs`
|
|
368
|
+
|
|
369
|
+
这意味着示例项目测试的是打包后的真实产物。
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
pnpm install
|
|
373
|
+
pnpm build
|
|
374
|
+
pnpm dev:fixture
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
调试 VitePress 示例项目:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
pnpm dev:vitepress
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
构建示例项目:
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
pnpm build:fixture
|
|
387
|
+
pnpm build:vitepress
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## 发布
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
pnpm build
|
|
394
|
+
pnpm build:fixture
|
|
395
|
+
pnpm build:vitepress
|
|
396
|
+
npm publish --access public
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
发布前建议确认:
|
|
400
|
+
|
|
401
|
+
- `dist/index.mjs` 已生成
|
|
402
|
+
- `dist/index.cjs` 已生成
|
|
403
|
+
- `dist/index.d.ts` 已生成
|
|
404
|
+
- `debug/fixture-app` 可以正常构建
|
|
405
|
+
- `debug/vitepress-app` 可以正常构建
|
|
406
|
+
- `version.json` 输出正常
|
|
407
|
+
- 普通 Vite HTML 注入正常
|
|
408
|
+
- VitePress `transformHtml` 接入后注入正常
|
|
409
|
+
|
|
410
|
+
查看最终发包内容:
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
npm pack
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
正常发布包应只包含:
|
|
417
|
+
|
|
418
|
+
- `dist`
|
|
419
|
+
- `README.md`
|
|
420
|
+
- `LICENSE`
|
|
421
|
+
- `package.json`
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
# English
|
|
426
|
+
|
|
427
|
+
`vite-plugin-build-version-file` is a build metadata plugin for Vite projects.
|
|
428
|
+
|
|
429
|
+
It exposes one consistent version payload in development and production:
|
|
430
|
+
|
|
431
|
+
- serves `version.json` through the Vite dev server
|
|
432
|
+
- emits `version.json` into the build output directory
|
|
433
|
+
- injects `window["__VERSION__"]` into normal Vite HTML
|
|
434
|
+
- supports VitePress through its top-level `transformHtml` hook
|
|
435
|
+
- supports custom versions, filenames, global variable names, time zones, and extra payload fields
|
|
436
|
+
|
|
437
|
+
The plugin only generates and exposes version metadata. It does not decide how your app should check for updates or refresh the page.
|
|
438
|
+
|
|
439
|
+
It intentionally does not include:
|
|
440
|
+
|
|
441
|
+
- polling logic
|
|
442
|
+
- update prompts
|
|
443
|
+
- retry rules
|
|
444
|
+
- reload timing
|
|
445
|
+
|
|
446
|
+
Those behaviors should stay in your application code.
|
|
447
|
+
|
|
448
|
+
## Compatibility
|
|
449
|
+
|
|
450
|
+
- Vite projects
|
|
451
|
+
- Vue 3 + Vite projects
|
|
452
|
+
- VitePress projects
|
|
453
|
+
- `vite >= 5`
|
|
454
|
+
- Node.js `>= 18`
|
|
455
|
+
|
|
456
|
+
## Installation
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
pnpm add vite-plugin-build-version-file
|
|
252
460
|
```
|
|
253
461
|
|
|
254
|
-
|
|
462
|
+
Or:
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
npm install vite-plugin-build-version-file
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
## Quick Start
|
|
469
|
+
|
|
470
|
+
### Vite / Vue 3
|
|
255
471
|
|
|
256
472
|
```ts
|
|
257
473
|
import { defineConfig } from 'vite'
|
|
@@ -261,168 +477,275 @@ import buildVersionPlugin from 'vite-plugin-build-version-file'
|
|
|
261
477
|
export default defineConfig({
|
|
262
478
|
plugins: [
|
|
263
479
|
vue(),
|
|
264
|
-
buildVersionPlugin(
|
|
265
|
-
injectToHtml: false
|
|
266
|
-
})
|
|
480
|
+
buildVersionPlugin()
|
|
267
481
|
]
|
|
268
482
|
})
|
|
269
483
|
```
|
|
270
484
|
|
|
271
|
-
###
|
|
485
|
+
### VitePress
|
|
272
486
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
487
|
+
VitePress does not write production HTML through the same `index.html` flow as a normal Vite app. Reuse one plugin instance and pass its `transformHtml` helper to the top-level VitePress config.
|
|
488
|
+
|
|
489
|
+
```js
|
|
490
|
+
import { defineConfig } from 'vitepress'
|
|
276
491
|
import buildVersionPlugin from 'vite-plugin-build-version-file'
|
|
277
492
|
|
|
493
|
+
const buildVersion = buildVersionPlugin()
|
|
494
|
+
|
|
278
495
|
export default defineConfig({
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
})
|
|
284
|
-
]
|
|
496
|
+
vite: {
|
|
497
|
+
plugins: [buildVersion],
|
|
498
|
+
},
|
|
499
|
+
transformHtml: buildVersion.transformHtml,
|
|
285
500
|
})
|
|
286
501
|
```
|
|
287
502
|
|
|
288
|
-
|
|
503
|
+
Use the same `buildVersion` instance in both places. Calling `buildVersionPlugin()` twice creates two isolated instances, and the VitePress `transformHtml` helper will not receive the payload created during the Vite plugin lifecycle.
|
|
289
504
|
|
|
290
|
-
|
|
291
|
-
|
|
505
|
+
## Default Behavior
|
|
506
|
+
|
|
507
|
+
With default options, the plugin:
|
|
508
|
+
|
|
509
|
+
- serves `/version.json` in development
|
|
510
|
+
- emits `version.json` after build
|
|
511
|
+
- injects `window["__VERSION__"]` into HTML
|
|
512
|
+
- reads the nearest project `package.json`
|
|
513
|
+
- writes `name` as `pkgName`
|
|
514
|
+
- writes `version` as `pkgVersion`
|
|
515
|
+
- uses `0` as the development version
|
|
516
|
+
- uses `YYYYMMDDHHmmss` as the production version
|
|
517
|
+
- uses `Asia/Shanghai` as the default time zone
|
|
518
|
+
|
|
519
|
+
Production payload example:
|
|
520
|
+
|
|
521
|
+
```json
|
|
522
|
+
{
|
|
523
|
+
"pkgName": "your-app-name",
|
|
524
|
+
"pkgVersion": "1.0.0",
|
|
525
|
+
"time": "20260401153045",
|
|
526
|
+
"env": "production"
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
Development payload example:
|
|
531
|
+
|
|
532
|
+
```json
|
|
533
|
+
{
|
|
534
|
+
"pkgName": "your-app-name",
|
|
535
|
+
"pkgVersion": "1.0.0",
|
|
536
|
+
"time": 0,
|
|
537
|
+
"env": "development"
|
|
538
|
+
}
|
|
292
539
|
```
|
|
293
540
|
|
|
294
|
-
|
|
541
|
+
## Options
|
|
295
542
|
|
|
296
543
|
```ts
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
544
|
+
type BuildVersionContext = {
|
|
545
|
+
command: 'serve' | 'build'
|
|
546
|
+
mode: string
|
|
547
|
+
}
|
|
300
548
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
549
|
+
type BuildVersionPluginOptions = {
|
|
550
|
+
filename?: string
|
|
551
|
+
globalName?: string
|
|
552
|
+
injectToHtml?: boolean
|
|
553
|
+
timeZone?: string
|
|
554
|
+
version?: string | number | ((ctx: BuildVersionContext) => string | number)
|
|
555
|
+
data?: Record<string, any>
|
|
556
|
+
log?: (content: any) => string
|
|
557
|
+
payload?: (json: any) => any
|
|
558
|
+
}
|
|
559
|
+
```
|
|
309
560
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
561
|
+
### `filename`
|
|
562
|
+
|
|
563
|
+
- Type: `string`
|
|
564
|
+
- Default: `"version.json"`
|
|
565
|
+
- Controls the dev URL and build output path.
|
|
566
|
+
|
|
567
|
+
```ts
|
|
568
|
+
buildVersionPlugin({
|
|
569
|
+
filename: 'meta/version.json'
|
|
314
570
|
})
|
|
315
571
|
```
|
|
316
572
|
|
|
317
|
-
|
|
573
|
+
Build output:
|
|
574
|
+
|
|
575
|
+
```text
|
|
576
|
+
dist/meta/version.json
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Development URL:
|
|
580
|
+
|
|
581
|
+
```text
|
|
582
|
+
/meta/version.json
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
If your project configures Vite `base`, the URL follows that base.
|
|
586
|
+
|
|
587
|
+
### `globalName`
|
|
588
|
+
|
|
589
|
+
- Type: `string`
|
|
590
|
+
- Default: `"__VERSION__"`
|
|
591
|
+
- Controls the property name injected on `window`.
|
|
592
|
+
|
|
593
|
+
Default injection:
|
|
594
|
+
|
|
595
|
+
```html
|
|
596
|
+
<script>
|
|
597
|
+
window["__VERSION__"] = { "time": "20260401153045", "env": "production" };
|
|
598
|
+
</script>
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
The injected value is the full payload object, not a single version string.
|
|
602
|
+
|
|
603
|
+
### `injectToHtml`
|
|
604
|
+
|
|
605
|
+
- Type: `boolean`
|
|
606
|
+
- Default: `true`
|
|
607
|
+
- Controls whether the plugin injects `window["__VERSION__"]`.
|
|
608
|
+
|
|
609
|
+
When set to `false`, `version.json` is still served and emitted.
|
|
610
|
+
|
|
611
|
+
### `timeZone`
|
|
612
|
+
|
|
613
|
+
- Type: `string`
|
|
614
|
+
- Default: `"Asia/Shanghai"`
|
|
615
|
+
- Controls the time zone used by the default production timestamp.
|
|
616
|
+
|
|
617
|
+
This only affects the default `time`. If you pass `version`, your custom logic wins.
|
|
618
|
+
|
|
619
|
+
### `version`
|
|
620
|
+
|
|
621
|
+
- Type: `string | number | ((ctx) => string | number)`
|
|
622
|
+
- Default: `0` in development, current timestamp in production
|
|
623
|
+
- Provides custom version generation.
|
|
318
624
|
|
|
319
625
|
```ts
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
626
|
+
buildVersionPlugin({
|
|
627
|
+
version: ({ command, mode }) => {
|
|
628
|
+
if (command === 'serve') {
|
|
629
|
+
return 0
|
|
630
|
+
}
|
|
323
631
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
vue(),
|
|
327
|
-
buildVersionPlugin({
|
|
328
|
-
timeZone: 'Asia/Shanghai'
|
|
329
|
-
})
|
|
330
|
-
]
|
|
632
|
+
return `${mode}-20260401153045`
|
|
633
|
+
}
|
|
331
634
|
})
|
|
332
635
|
```
|
|
333
636
|
|
|
334
|
-
###
|
|
637
|
+
### `data`
|
|
335
638
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
import buildVersionPlugin from 'vite-plugin-build-version-file'
|
|
639
|
+
- Type: `Record<string, any>`
|
|
640
|
+
- Default: `{}`
|
|
641
|
+
- Adds custom fields to the final payload.
|
|
340
642
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
commitSha: 'abc1234'
|
|
349
|
-
}
|
|
350
|
-
})
|
|
351
|
-
]
|
|
643
|
+
```ts
|
|
644
|
+
buildVersionPlugin({
|
|
645
|
+
data: {
|
|
646
|
+
appName: 'admin',
|
|
647
|
+
gitBranch: 'release/2026-04',
|
|
648
|
+
commitSha: 'abc1234'
|
|
649
|
+
}
|
|
352
650
|
})
|
|
353
651
|
```
|
|
354
652
|
|
|
355
|
-
|
|
653
|
+
Example output:
|
|
356
654
|
|
|
357
655
|
```json
|
|
358
656
|
{
|
|
359
657
|
"appName": "admin",
|
|
360
658
|
"gitBranch": "release/2026-04",
|
|
361
659
|
"commitSha": "abc1234",
|
|
660
|
+
"pkgName": "your-app-name",
|
|
661
|
+
"pkgVersion": "1.0.0",
|
|
362
662
|
"time": "20260401153045",
|
|
363
663
|
"env": "production"
|
|
364
664
|
}
|
|
365
665
|
```
|
|
366
666
|
|
|
367
|
-
|
|
667
|
+
Merge order:
|
|
368
668
|
|
|
369
|
-
|
|
669
|
+
- `data` is written first
|
|
670
|
+
- `pkgName` and `pkgVersion` from `package.json` override matching fields
|
|
671
|
+
- `time` and `env` from the plugin override matching fields
|
|
672
|
+
- `payload` can rewrite the final object
|
|
370
673
|
|
|
371
|
-
###
|
|
674
|
+
### `payload`
|
|
372
675
|
|
|
373
|
-
|
|
374
|
-
|
|
676
|
+
- Type: `(json: any) => any`
|
|
677
|
+
- Rewrites the final payload.
|
|
375
678
|
|
|
376
|
-
|
|
377
|
-
|
|
679
|
+
Use it to trim fields, rename fields, or keep compatibility with an older contract.
|
|
680
|
+
|
|
681
|
+
```ts
|
|
682
|
+
buildVersionPlugin({
|
|
683
|
+
payload: (json) => ({
|
|
684
|
+
version: json.time,
|
|
685
|
+
env: json.env,
|
|
686
|
+
name: json.pkgName
|
|
687
|
+
})
|
|
688
|
+
})
|
|
378
689
|
```
|
|
379
690
|
|
|
380
|
-
|
|
691
|
+
Returning an object is recommended so application reads stay stable.
|
|
381
692
|
|
|
382
|
-
|
|
383
|
-
- 这里读到的是完整对象,不是单独字符串
|
|
384
|
-
- 如果配置了 `data`,这里也可以直接读取对应字段
|
|
693
|
+
### `log`
|
|
385
694
|
|
|
386
|
-
|
|
695
|
+
- Type: `(content: any) => string`
|
|
696
|
+
- Customizes the build-complete console output.
|
|
387
697
|
|
|
388
698
|
```ts
|
|
389
|
-
|
|
390
|
-
|
|
699
|
+
buildVersionPlugin({
|
|
700
|
+
log: (payload) => `build version: ${payload.time}`
|
|
701
|
+
})
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
## Reading Version Metadata
|
|
705
|
+
|
|
706
|
+
### Read the injected global
|
|
707
|
+
|
|
708
|
+
```ts
|
|
709
|
+
const payload = window['__VERSION__']
|
|
391
710
|
|
|
392
711
|
console.log(payload.time)
|
|
393
712
|
console.log(payload.env)
|
|
394
713
|
```
|
|
395
714
|
|
|
396
|
-
|
|
715
|
+
Use this when you need the version of the currently loaded page.
|
|
397
716
|
|
|
398
|
-
|
|
717
|
+
### Read `version.json`
|
|
399
718
|
|
|
400
|
-
|
|
719
|
+
```ts
|
|
720
|
+
const response = await fetch('/version.json', {
|
|
721
|
+
cache: 'no-store'
|
|
722
|
+
})
|
|
723
|
+
const payload = await response.json()
|
|
401
724
|
|
|
402
|
-
|
|
403
|
-
|
|
725
|
+
console.log(payload.time)
|
|
726
|
+
console.log(payload.env)
|
|
727
|
+
```
|
|
404
728
|
|
|
405
|
-
|
|
729
|
+
Use this when you need to compare the current page against the latest deployed version.
|
|
406
730
|
|
|
407
|
-
|
|
731
|
+
## Checking for Updates
|
|
408
732
|
|
|
409
|
-
|
|
733
|
+
The plugin does not include update-checking UI. Keep that logic in your app.
|
|
410
734
|
|
|
411
735
|
```js
|
|
412
736
|
const CHECK_INTERVAL = 60 * 1000
|
|
413
|
-
const VERSION_URL =
|
|
737
|
+
const VERSION_URL = '/version.json'
|
|
414
738
|
|
|
415
739
|
async function checkVersion() {
|
|
416
740
|
try {
|
|
417
741
|
const response = await fetch(VERSION_URL, {
|
|
418
742
|
cache: 'no-store'
|
|
419
743
|
})
|
|
420
|
-
|
|
421
|
-
const payload = await response.json()
|
|
744
|
+
const latestPayload = await response.json()
|
|
422
745
|
const currentPayload = window.__VERSION__
|
|
423
746
|
|
|
424
|
-
if (currentPayload &&
|
|
425
|
-
const shouldReload =
|
|
747
|
+
if (currentPayload && latestPayload.time !== currentPayload.time) {
|
|
748
|
+
const shouldReload = window.confirm('A new version is available. Reload now?')
|
|
426
749
|
|
|
427
750
|
if (shouldReload) {
|
|
428
751
|
window.location.reload()
|
|
@@ -433,126 +756,86 @@ async function checkVersion() {
|
|
|
433
756
|
console.warn('check version failed', error)
|
|
434
757
|
}
|
|
435
758
|
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
function scheduleNextCheck() {
|
|
440
|
-
setTimeout(checkVersion, CHECK_INTERVAL)
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
function showUpdatePrompt() {
|
|
444
|
-
// 这里替换成你自己的弹窗、消息组件或确认框
|
|
445
|
-
return Promise.resolve(window.confirm('检测到新版本,是否刷新页面?'))
|
|
759
|
+
window.setTimeout(checkVersion, CHECK_INTERVAL)
|
|
446
760
|
}
|
|
447
761
|
|
|
448
762
|
checkVersion()
|
|
449
763
|
```
|
|
450
764
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
- 版本比较只判断 `payload.time` 和当前页面里的 `window.__VERSION__.time` 是否一致
|
|
454
|
-
- 提示方式由业务项目自己决定,可以是弹窗、消息条、通知或静默刷新
|
|
455
|
-
- 轮询间隔不要过短,通常用 1 分钟或更长更合适
|
|
456
|
-
- 请求失败后继续下一轮检查,避免一次失败后整个流程中断
|
|
457
|
-
|
|
458
|
-
上面这段逻辑故意没有放进插件里,因为不同项目通常会有不同要求:
|
|
765
|
+
Recommendations:
|
|
459
766
|
|
|
460
|
-
-
|
|
461
|
-
-
|
|
462
|
-
-
|
|
463
|
-
-
|
|
464
|
-
-
|
|
767
|
+
- Compare `payload.time` in most cases.
|
|
768
|
+
- Fetch `version.json` with `cache: 'no-store'`.
|
|
769
|
+
- Avoid very short polling intervals. One minute or longer is usually enough.
|
|
770
|
+
- Keep prompts, notifications, silent reloads, and retry rules in application code.
|
|
771
|
+
- Continue polling after failed requests.
|
|
465
772
|
|
|
466
|
-
##
|
|
773
|
+
## Development Behavior
|
|
467
774
|
|
|
468
|
-
|
|
775
|
+
In development, the plugin does not write files into your project directory.
|
|
469
776
|
|
|
470
|
-
|
|
777
|
+
It serves JSON directly through the Vite dev server:
|
|
471
778
|
|
|
472
|
-
-
|
|
473
|
-
-
|
|
474
|
-
-
|
|
779
|
+
- no `public/` pollution
|
|
780
|
+
- no temporary file generation
|
|
781
|
+
- restart the dev server after changing plugin options
|
|
475
782
|
|
|
476
|
-
|
|
783
|
+
## Local Development
|
|
477
784
|
|
|
478
|
-
|
|
785
|
+
The repository contains two fixture apps:
|
|
479
786
|
|
|
480
|
-
|
|
787
|
+
- Vite / Vue 3: `debug/fixture-app`
|
|
788
|
+
- VitePress: `debug/vitepress-app`
|
|
789
|
+
- They import the built package from `dist/index.mjs`
|
|
481
790
|
|
|
482
|
-
|
|
483
|
-
- 引用方式:直接引用根目录 `dist/index.mjs`
|
|
484
|
-
|
|
485
|
-
这意味着它测试的是“打包后的真实产物”,而不是源码直连。
|
|
486
|
-
|
|
487
|
-
### 安装依赖
|
|
791
|
+
This verifies the real build output instead of importing source files directly.
|
|
488
792
|
|
|
489
793
|
```bash
|
|
490
794
|
pnpm install
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
### 构建插件
|
|
494
|
-
|
|
495
|
-
```bash
|
|
496
795
|
pnpm build
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
### 启动测试项目
|
|
500
|
-
|
|
501
|
-
```bash
|
|
502
796
|
pnpm dev:fixture
|
|
503
797
|
```
|
|
504
798
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
- `window["__VERSION__"]`
|
|
508
|
-
- `/version.json` 的返回结果
|
|
509
|
-
|
|
510
|
-
### 构建测试项目
|
|
799
|
+
Run the VitePress fixture:
|
|
511
800
|
|
|
512
801
|
```bash
|
|
513
|
-
pnpm
|
|
802
|
+
pnpm dev:vitepress
|
|
514
803
|
```
|
|
515
804
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
## 发布到 npm
|
|
519
|
-
|
|
520
|
-
### 1. 登录 npm
|
|
805
|
+
Build fixture apps:
|
|
521
806
|
|
|
522
807
|
```bash
|
|
523
|
-
|
|
808
|
+
pnpm build:fixture
|
|
809
|
+
pnpm build:vitepress
|
|
524
810
|
```
|
|
525
811
|
|
|
526
|
-
|
|
812
|
+
## Publishing
|
|
527
813
|
|
|
528
814
|
```bash
|
|
529
815
|
pnpm build
|
|
530
816
|
pnpm build:fixture
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
### 3. 发布公开包
|
|
534
|
-
|
|
535
|
-
```bash
|
|
817
|
+
pnpm build:vitepress
|
|
536
818
|
npm publish --access public
|
|
537
819
|
```
|
|
538
820
|
|
|
539
|
-
|
|
821
|
+
Before publishing, check:
|
|
540
822
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
- `dist/index.
|
|
544
|
-
-
|
|
545
|
-
-
|
|
546
|
-
-
|
|
547
|
-
-
|
|
823
|
+
- `dist/index.mjs`
|
|
824
|
+
- `dist/index.cjs`
|
|
825
|
+
- `dist/index.d.ts`
|
|
826
|
+
- fixture app build
|
|
827
|
+
- VitePress fixture build
|
|
828
|
+
- `version.json` output
|
|
829
|
+
- normal Vite HTML injection
|
|
830
|
+
- VitePress `transformHtml` injection
|
|
548
831
|
|
|
549
|
-
|
|
832
|
+
Inspect the publish package:
|
|
550
833
|
|
|
551
834
|
```bash
|
|
552
835
|
npm pack
|
|
553
836
|
```
|
|
554
837
|
|
|
555
|
-
|
|
838
|
+
The package should contain:
|
|
556
839
|
|
|
557
840
|
- `dist`
|
|
558
841
|
- `README.md`
|
package/dist/index.cjs
CHANGED
|
@@ -129,6 +129,19 @@ function serializePayload(payload) {
|
|
|
129
129
|
return `${JSON.stringify(payload, null, 2)}
|
|
130
130
|
`;
|
|
131
131
|
}
|
|
132
|
+
function createInjectScript(globalName, payload) {
|
|
133
|
+
return `window[${JSON.stringify(globalName)}] = ${JSON.stringify(payload)};`;
|
|
134
|
+
}
|
|
135
|
+
function injectScriptToHead(code, script) {
|
|
136
|
+
const scriptTag = `<script>${script}</script>`;
|
|
137
|
+
if (code.includes(script)) {
|
|
138
|
+
return code;
|
|
139
|
+
}
|
|
140
|
+
if (code.includes("</head>")) {
|
|
141
|
+
return code.replace("</head>", `${scriptTag}</head>`);
|
|
142
|
+
}
|
|
143
|
+
return `${scriptTag}${code}`;
|
|
144
|
+
}
|
|
132
145
|
function parsePathname(requestUrl) {
|
|
133
146
|
if (!requestUrl) {
|
|
134
147
|
return "/";
|
|
@@ -171,7 +184,13 @@ function buildVersionPlugin(options = {}) {
|
|
|
171
184
|
const timeZone = normalizeTimeZone(options.timeZone ?? DEFAULT_TIME_ZONE);
|
|
172
185
|
const data = normalizeData(options.data);
|
|
173
186
|
let payload;
|
|
174
|
-
|
|
187
|
+
const transformHtml = (code, ..._args) => {
|
|
188
|
+
if (!injectToHtml || !payload) {
|
|
189
|
+
return void 0;
|
|
190
|
+
}
|
|
191
|
+
return injectScriptToHead(code, createInjectScript(globalName, payload));
|
|
192
|
+
};
|
|
193
|
+
const plugin = {
|
|
175
194
|
name: PLUGIN_NAME,
|
|
176
195
|
configResolved(config) {
|
|
177
196
|
const context = {
|
|
@@ -207,7 +226,7 @@ function buildVersionPlugin(options = {}) {
|
|
|
207
226
|
{
|
|
208
227
|
tag: "script",
|
|
209
228
|
injectTo: "head",
|
|
210
|
-
children:
|
|
229
|
+
children: createInjectScript(globalName, payload)
|
|
211
230
|
}
|
|
212
231
|
];
|
|
213
232
|
return tags;
|
|
@@ -229,6 +248,10 @@ function buildVersionPlugin(options = {}) {
|
|
|
229
248
|
}
|
|
230
249
|
}
|
|
231
250
|
};
|
|
251
|
+
Object.defineProperty(plugin, "transformHtml", {
|
|
252
|
+
value: transformHtml
|
|
253
|
+
});
|
|
254
|
+
return plugin;
|
|
232
255
|
}
|
|
233
256
|
var index_default = buildVersionPlugin;
|
|
234
257
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.d.cts
CHANGED
|
@@ -19,6 +19,9 @@ interface BuildVersionPluginOptions {
|
|
|
19
19
|
log?: (content: any) => string;
|
|
20
20
|
payload?: (json: any) => any;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
type BuildVersionPlugin = Plugin & {
|
|
23
|
+
transformHtml: (code: string, ...args: unknown[]) => string | undefined;
|
|
24
|
+
};
|
|
25
|
+
declare function buildVersionPlugin(options?: BuildVersionPluginOptions): BuildVersionPlugin;
|
|
23
26
|
|
|
24
|
-
export { type BuildVersionContext, type BuildVersionPayload, type BuildVersionPluginOptions, buildVersionPlugin, buildVersionPlugin as default };
|
|
27
|
+
export { type BuildVersionContext, type BuildVersionPayload, type BuildVersionPlugin, type BuildVersionPluginOptions, buildVersionPlugin, buildVersionPlugin as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,9 @@ interface BuildVersionPluginOptions {
|
|
|
19
19
|
log?: (content: any) => string;
|
|
20
20
|
payload?: (json: any) => any;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
type BuildVersionPlugin = Plugin & {
|
|
23
|
+
transformHtml: (code: string, ...args: unknown[]) => string | undefined;
|
|
24
|
+
};
|
|
25
|
+
declare function buildVersionPlugin(options?: BuildVersionPluginOptions): BuildVersionPlugin;
|
|
23
26
|
|
|
24
|
-
export { type BuildVersionContext, type BuildVersionPayload, type BuildVersionPluginOptions, buildVersionPlugin, buildVersionPlugin as default };
|
|
27
|
+
export { type BuildVersionContext, type BuildVersionPayload, type BuildVersionPlugin, type BuildVersionPluginOptions, buildVersionPlugin, buildVersionPlugin as default };
|
package/dist/index.mjs
CHANGED
|
@@ -104,6 +104,19 @@ function serializePayload(payload) {
|
|
|
104
104
|
return `${JSON.stringify(payload, null, 2)}
|
|
105
105
|
`;
|
|
106
106
|
}
|
|
107
|
+
function createInjectScript(globalName, payload) {
|
|
108
|
+
return `window[${JSON.stringify(globalName)}] = ${JSON.stringify(payload)};`;
|
|
109
|
+
}
|
|
110
|
+
function injectScriptToHead(code, script) {
|
|
111
|
+
const scriptTag = `<script>${script}</script>`;
|
|
112
|
+
if (code.includes(script)) {
|
|
113
|
+
return code;
|
|
114
|
+
}
|
|
115
|
+
if (code.includes("</head>")) {
|
|
116
|
+
return code.replace("</head>", `${scriptTag}</head>`);
|
|
117
|
+
}
|
|
118
|
+
return `${scriptTag}${code}`;
|
|
119
|
+
}
|
|
107
120
|
function parsePathname(requestUrl) {
|
|
108
121
|
if (!requestUrl) {
|
|
109
122
|
return "/";
|
|
@@ -146,7 +159,13 @@ function buildVersionPlugin(options = {}) {
|
|
|
146
159
|
const timeZone = normalizeTimeZone(options.timeZone ?? DEFAULT_TIME_ZONE);
|
|
147
160
|
const data = normalizeData(options.data);
|
|
148
161
|
let payload;
|
|
149
|
-
|
|
162
|
+
const transformHtml = (code, ..._args) => {
|
|
163
|
+
if (!injectToHtml || !payload) {
|
|
164
|
+
return void 0;
|
|
165
|
+
}
|
|
166
|
+
return injectScriptToHead(code, createInjectScript(globalName, payload));
|
|
167
|
+
};
|
|
168
|
+
const plugin = {
|
|
150
169
|
name: PLUGIN_NAME,
|
|
151
170
|
configResolved(config) {
|
|
152
171
|
const context = {
|
|
@@ -182,7 +201,7 @@ function buildVersionPlugin(options = {}) {
|
|
|
182
201
|
{
|
|
183
202
|
tag: "script",
|
|
184
203
|
injectTo: "head",
|
|
185
|
-
children:
|
|
204
|
+
children: createInjectScript(globalName, payload)
|
|
186
205
|
}
|
|
187
206
|
];
|
|
188
207
|
return tags;
|
|
@@ -204,6 +223,10 @@ function buildVersionPlugin(options = {}) {
|
|
|
204
223
|
}
|
|
205
224
|
}
|
|
206
225
|
};
|
|
226
|
+
Object.defineProperty(plugin, "transformHtml", {
|
|
227
|
+
value: transformHtml
|
|
228
|
+
});
|
|
229
|
+
return plugin;
|
|
207
230
|
}
|
|
208
231
|
var index_default = buildVersionPlugin;
|
|
209
232
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-build-version-file",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "A Vite plugin that emits version.json and injects version metadata into HTML.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "tsup --config tsup.config.ts",
|
|
25
25
|
"build:fixture": "pnpm build && vite build --config debug/fixture-app/vite.config.ts",
|
|
26
|
+
"build:vitepress": "pnpm build && vitepress build debug/vitepress-app",
|
|
26
27
|
"dev:fixture": "pnpm build && vite --config debug/fixture-app/vite.config.ts",
|
|
28
|
+
"dev:vitepress": "pnpm build && vitepress dev debug/vitepress-app",
|
|
27
29
|
"prepublishOnly": "pnpm build:fixture"
|
|
28
30
|
},
|
|
29
31
|
"keywords": [
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
"tsup": "^8.0.0",
|
|
50
52
|
"typescript": "^5.0.0",
|
|
51
53
|
"vite": "^5.0.0",
|
|
54
|
+
"vitepress": "^1.6.4",
|
|
52
55
|
"vue": "^3.4.0"
|
|
53
56
|
}
|
|
54
57
|
}
|