vite-plugin-build-version-file 0.1.6 → 0.1.8
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 +38 -35
- package/dist/index.cjs +58 -47
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +58 -47
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
- 构建产物中生成 `version.json`
|
|
8
8
|
- 可选地向 HTML 注入 `window["__VERSION__"]`
|
|
9
|
-
- 通过 `import.meta.env.__VERSION__` 在代码中直接读取版本号
|
|
10
9
|
- 支持自定义版本号、文件名、全局变量名和额外数据
|
|
11
10
|
|
|
12
11
|
这个插件只负责产出和暴露版本信息。
|
|
@@ -107,7 +106,7 @@ export default defineConfig({
|
|
|
107
106
|
|
|
108
107
|
如果你的项目要做“检测到新版本后提示刷新”,推荐做法是:
|
|
109
108
|
|
|
110
|
-
- 用 `
|
|
109
|
+
- 用 `window["__VERSION__"]` 读取当前页面版本
|
|
111
110
|
- 请求 `version.json` 读取服务端版本
|
|
112
111
|
- 在业务项目里自行决定提示方式和刷新时机
|
|
113
112
|
|
|
@@ -123,6 +122,7 @@ type BuildVersionPluginOptions = {
|
|
|
123
122
|
filename?: string
|
|
124
123
|
globalName?: string
|
|
125
124
|
injectToHtml?: boolean
|
|
125
|
+
timeZone?: string
|
|
126
126
|
version?: string | number | ((ctx: BuildVersionContext) => string | number)
|
|
127
127
|
data?: Record<string, any>
|
|
128
128
|
}
|
|
@@ -182,6 +182,18 @@ type BuildVersionPluginOptions = {
|
|
|
182
182
|
}
|
|
183
183
|
```
|
|
184
184
|
|
|
185
|
+
### `timeZone`
|
|
186
|
+
|
|
187
|
+
- 类型:`string`
|
|
188
|
+
- 默认值:`"Asia/Shanghai"`
|
|
189
|
+
- 作用:控制默认时间按哪个时区生成
|
|
190
|
+
|
|
191
|
+
说明:
|
|
192
|
+
|
|
193
|
+
- 只影响插件默认生成的 `time`
|
|
194
|
+
- 如果构建环境是 UTC,也会按设置的时区输出
|
|
195
|
+
- 如果传了 `version`,则以你自己的 `version` 逻辑为准
|
|
196
|
+
|
|
185
197
|
### `data`
|
|
186
198
|
|
|
187
199
|
- 类型:`Record<string, any>`
|
|
@@ -302,7 +314,24 @@ export default defineConfig({
|
|
|
302
314
|
})
|
|
303
315
|
```
|
|
304
316
|
|
|
305
|
-
### 6.
|
|
317
|
+
### 6. 指定时区生成时间
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
import { defineConfig } from 'vite'
|
|
321
|
+
import vue from '@vitejs/plugin-vue'
|
|
322
|
+
import buildVersionPlugin from 'vite-plugin-build-version-file'
|
|
323
|
+
|
|
324
|
+
export default defineConfig({
|
|
325
|
+
plugins: [
|
|
326
|
+
vue(),
|
|
327
|
+
buildVersionPlugin({
|
|
328
|
+
timeZone: 'Asia/Shanghai'
|
|
329
|
+
})
|
|
330
|
+
]
|
|
331
|
+
})
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### 7. 追加自定义数据
|
|
306
335
|
|
|
307
336
|
```ts
|
|
308
337
|
import { defineConfig } from 'vite'
|
|
@@ -337,36 +366,9 @@ export default defineConfig({
|
|
|
337
366
|
|
|
338
367
|
## 在项目中读取版本
|
|
339
368
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
### 方式一:通过 `import.meta.env` 读取(推荐)
|
|
343
|
-
|
|
344
|
-
版本号会被注入到 `import.meta.env` 中,可以直接在代码中使用:
|
|
345
|
-
|
|
346
|
-
```ts
|
|
347
|
-
const version = import.meta.env.__VERSION__
|
|
348
|
-
console.log(version) // '20260401153045' 或 '1.2.3'
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
**优势:**
|
|
352
|
-
- 无需等待页面加载或发起请求
|
|
353
|
-
- 类型安全,可在 `vite-env.d.ts` 中声明类型
|
|
354
|
-
- 适合在应用初始化时读取版本
|
|
355
|
-
|
|
356
|
-
**TypeScript 类型声明:**
|
|
357
|
-
|
|
358
|
-
```ts
|
|
359
|
-
// vite-env.d.ts
|
|
360
|
-
interface ImportMetaEnv {
|
|
361
|
-
readonly __VERSION__: string
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
interface ImportMeta {
|
|
365
|
-
readonly env: ImportMetaEnv
|
|
366
|
-
}
|
|
367
|
-
```
|
|
369
|
+
插件提供两种方式读取版本号,可根据场景选择:
|
|
368
370
|
|
|
369
|
-
###
|
|
371
|
+
### 方式一:读取注入的全局变量
|
|
370
372
|
|
|
371
373
|
```ts
|
|
372
374
|
const payload = window['__VERSION__']
|
|
@@ -381,7 +383,7 @@ console.log(payload.env)
|
|
|
381
383
|
- 这里读到的是完整对象,不是单独字符串
|
|
382
384
|
- 如果配置了 `data`,这里也可以直接读取对应字段
|
|
383
385
|
|
|
384
|
-
###
|
|
386
|
+
### 方式二:读取 `version.json`
|
|
385
387
|
|
|
386
388
|
```ts
|
|
387
389
|
const response = await fetch('/version.json')
|
|
@@ -417,8 +419,9 @@ async function checkVersion() {
|
|
|
417
419
|
})
|
|
418
420
|
|
|
419
421
|
const payload = await response.json()
|
|
422
|
+
const currentPayload = window.__VERSION__
|
|
420
423
|
|
|
421
|
-
if (payload.time !==
|
|
424
|
+
if (currentPayload && payload.time !== currentPayload.time) {
|
|
422
425
|
const shouldReload = await showUpdatePrompt()
|
|
423
426
|
|
|
424
427
|
if (shouldReload) {
|
|
@@ -447,7 +450,7 @@ checkVersion()
|
|
|
447
450
|
|
|
448
451
|
建议:
|
|
449
452
|
|
|
450
|
-
- 版本比较只判断 `payload.time`
|
|
453
|
+
- 版本比较只判断 `payload.time` 和当前页面里的 `window.__VERSION__.time` 是否一致
|
|
451
454
|
- 提示方式由业务项目自己决定,可以是弹窗、消息条、通知或静默刷新
|
|
452
455
|
- 轮询间隔不要过短,通常用 1 分钟或更长更合适
|
|
453
456
|
- 请求失败后继续下一轮检查,避免一次失败后整个流程中断
|
package/dist/index.cjs
CHANGED
|
@@ -29,19 +29,32 @@ var import_node_path = require("path");
|
|
|
29
29
|
var PLUGIN_NAME = "vite-plugin-build-version-file";
|
|
30
30
|
var DEFAULT_FILENAME = "version.json";
|
|
31
31
|
var DEFAULT_GLOBAL_NAME = "__VERSION__";
|
|
32
|
-
|
|
32
|
+
var DEFAULT_TIME_ZONE = "Asia/Shanghai";
|
|
33
|
+
function createDefaultVersion(command, timeZone) {
|
|
33
34
|
if (command === "serve") {
|
|
34
35
|
return 0;
|
|
35
36
|
}
|
|
36
|
-
const
|
|
37
|
-
|
|
37
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
38
|
+
timeZone,
|
|
39
|
+
year: "numeric",
|
|
40
|
+
month: "2-digit",
|
|
41
|
+
day: "2-digit",
|
|
42
|
+
hour: "2-digit",
|
|
43
|
+
minute: "2-digit",
|
|
44
|
+
second: "2-digit",
|
|
45
|
+
hour12: false,
|
|
46
|
+
hourCycle: "h23"
|
|
47
|
+
}).formatToParts(/* @__PURE__ */ new Date());
|
|
48
|
+
const getPartValue = (type) => {
|
|
49
|
+
return parts.find((part) => part.type === type)?.value ?? "";
|
|
50
|
+
};
|
|
38
51
|
return [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
getPartValue("year"),
|
|
53
|
+
getPartValue("month"),
|
|
54
|
+
getPartValue("day"),
|
|
55
|
+
getPartValue("hour"),
|
|
56
|
+
getPartValue("minute"),
|
|
57
|
+
getPartValue("second")
|
|
45
58
|
].join("");
|
|
46
59
|
}
|
|
47
60
|
function normalizeFileName(filename) {
|
|
@@ -57,6 +70,18 @@ function normalizeGlobalName(globalName) {
|
|
|
57
70
|
}
|
|
58
71
|
return globalName;
|
|
59
72
|
}
|
|
73
|
+
function normalizeTimeZone(timeZone) {
|
|
74
|
+
const normalized = timeZone.trim();
|
|
75
|
+
if (!normalized) {
|
|
76
|
+
throw new Error(`[${PLUGIN_NAME}] "timeZone" cannot be empty.`);
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
new Intl.DateTimeFormat("en-US", { timeZone: normalized }).format(/* @__PURE__ */ new Date());
|
|
80
|
+
} catch {
|
|
81
|
+
throw new Error(`[${PLUGIN_NAME}] "timeZone" is invalid.`);
|
|
82
|
+
}
|
|
83
|
+
return normalized;
|
|
84
|
+
}
|
|
60
85
|
function normalizeData(data) {
|
|
61
86
|
if (data === void 0) {
|
|
62
87
|
return {};
|
|
@@ -116,59 +141,45 @@ function toRequestPath(base, fileName) {
|
|
|
116
141
|
const baseWithoutTrailingSlash = withLeadingSlash.endsWith("/") ? withLeadingSlash.slice(0, -1) : withLeadingSlash;
|
|
117
142
|
return `${baseWithoutTrailingSlash}/${fileName}`.replace(/\/{2,}/g, "/");
|
|
118
143
|
}
|
|
144
|
+
function resolveVersion(options, context, timeZone) {
|
|
145
|
+
if (typeof options.version === "function") {
|
|
146
|
+
return options.version(context);
|
|
147
|
+
}
|
|
148
|
+
if (options.version !== void 0) {
|
|
149
|
+
return options.version;
|
|
150
|
+
}
|
|
151
|
+
return createDefaultVersion(context.command, timeZone);
|
|
152
|
+
}
|
|
153
|
+
function createPayload(options, context, data, timeZone, packageInfo = {}) {
|
|
154
|
+
let nextPayload = {
|
|
155
|
+
...data,
|
|
156
|
+
...packageInfo,
|
|
157
|
+
time: resolveVersion(options, context, timeZone),
|
|
158
|
+
env: context.mode
|
|
159
|
+
};
|
|
160
|
+
if (options.payload) {
|
|
161
|
+
nextPayload = options.payload(nextPayload);
|
|
162
|
+
}
|
|
163
|
+
return nextPayload;
|
|
164
|
+
}
|
|
119
165
|
function buildVersionPlugin(options = {}) {
|
|
120
166
|
const fileName = normalizeFileName(options.filename ?? DEFAULT_FILENAME);
|
|
121
167
|
const globalName = normalizeGlobalName(
|
|
122
168
|
options.globalName ?? DEFAULT_GLOBAL_NAME
|
|
123
169
|
);
|
|
124
170
|
const injectToHtml = options.injectToHtml ?? true;
|
|
171
|
+
const timeZone = normalizeTimeZone(options.timeZone ?? DEFAULT_TIME_ZONE);
|
|
125
172
|
const data = normalizeData(options.data);
|
|
126
|
-
let packageInfo = {};
|
|
127
173
|
let payload;
|
|
128
174
|
return {
|
|
129
175
|
name: PLUGIN_NAME,
|
|
130
|
-
config(config, { command }) {
|
|
131
|
-
const context = {
|
|
132
|
-
command,
|
|
133
|
-
mode: config.mode || "development"
|
|
134
|
-
};
|
|
135
|
-
let version;
|
|
136
|
-
if (typeof options.version === "function") {
|
|
137
|
-
version = options.version(context);
|
|
138
|
-
} else if (options.version !== void 0) {
|
|
139
|
-
version = options.version;
|
|
140
|
-
} else {
|
|
141
|
-
version = createDefaultVersion(context.command);
|
|
142
|
-
}
|
|
143
|
-
return {
|
|
144
|
-
define: {
|
|
145
|
-
[`import.meta.env.${globalName}`]: JSON.stringify(version)
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
},
|
|
149
176
|
configResolved(config) {
|
|
150
|
-
packageInfo = readPackageInfo(config.root);
|
|
151
177
|
const context = {
|
|
152
178
|
command: config.command,
|
|
153
179
|
mode: config.mode
|
|
154
180
|
};
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
version = options.version(context);
|
|
158
|
-
} else if (options.version !== void 0) {
|
|
159
|
-
version = options.version;
|
|
160
|
-
} else {
|
|
161
|
-
version = createDefaultVersion(context.command);
|
|
162
|
-
}
|
|
163
|
-
payload = {
|
|
164
|
-
...data,
|
|
165
|
-
...packageInfo,
|
|
166
|
-
time: version,
|
|
167
|
-
env: config.mode
|
|
168
|
-
};
|
|
169
|
-
if (options.payload) {
|
|
170
|
-
payload = options.payload(payload);
|
|
171
|
-
}
|
|
181
|
+
const packageInfo = readPackageInfo(config.root);
|
|
182
|
+
payload = createPayload(options, context, data, timeZone, packageInfo);
|
|
172
183
|
},
|
|
173
184
|
configureServer(server) {
|
|
174
185
|
const requestPath = toRequestPath(server.config.base, fileName);
|
package/dist/index.d.cts
CHANGED
|
@@ -13,6 +13,7 @@ interface BuildVersionPluginOptions {
|
|
|
13
13
|
filename?: string;
|
|
14
14
|
globalName?: string;
|
|
15
15
|
injectToHtml?: boolean;
|
|
16
|
+
timeZone?: string;
|
|
16
17
|
version?: string | number | ((ctx: BuildVersionContext) => string | number);
|
|
17
18
|
data?: Record<string, any>;
|
|
18
19
|
log?: (content: any) => string;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ interface BuildVersionPluginOptions {
|
|
|
13
13
|
filename?: string;
|
|
14
14
|
globalName?: string;
|
|
15
15
|
injectToHtml?: boolean;
|
|
16
|
+
timeZone?: string;
|
|
16
17
|
version?: string | number | ((ctx: BuildVersionContext) => string | number);
|
|
17
18
|
data?: Record<string, any>;
|
|
18
19
|
log?: (content: any) => string;
|
package/dist/index.mjs
CHANGED
|
@@ -4,19 +4,32 @@ import { dirname, join } from "path";
|
|
|
4
4
|
var PLUGIN_NAME = "vite-plugin-build-version-file";
|
|
5
5
|
var DEFAULT_FILENAME = "version.json";
|
|
6
6
|
var DEFAULT_GLOBAL_NAME = "__VERSION__";
|
|
7
|
-
|
|
7
|
+
var DEFAULT_TIME_ZONE = "Asia/Shanghai";
|
|
8
|
+
function createDefaultVersion(command, timeZone) {
|
|
8
9
|
if (command === "serve") {
|
|
9
10
|
return 0;
|
|
10
11
|
}
|
|
11
|
-
const
|
|
12
|
-
|
|
12
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
13
|
+
timeZone,
|
|
14
|
+
year: "numeric",
|
|
15
|
+
month: "2-digit",
|
|
16
|
+
day: "2-digit",
|
|
17
|
+
hour: "2-digit",
|
|
18
|
+
minute: "2-digit",
|
|
19
|
+
second: "2-digit",
|
|
20
|
+
hour12: false,
|
|
21
|
+
hourCycle: "h23"
|
|
22
|
+
}).formatToParts(/* @__PURE__ */ new Date());
|
|
23
|
+
const getPartValue = (type) => {
|
|
24
|
+
return parts.find((part) => part.type === type)?.value ?? "";
|
|
25
|
+
};
|
|
13
26
|
return [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
27
|
+
getPartValue("year"),
|
|
28
|
+
getPartValue("month"),
|
|
29
|
+
getPartValue("day"),
|
|
30
|
+
getPartValue("hour"),
|
|
31
|
+
getPartValue("minute"),
|
|
32
|
+
getPartValue("second")
|
|
20
33
|
].join("");
|
|
21
34
|
}
|
|
22
35
|
function normalizeFileName(filename) {
|
|
@@ -32,6 +45,18 @@ function normalizeGlobalName(globalName) {
|
|
|
32
45
|
}
|
|
33
46
|
return globalName;
|
|
34
47
|
}
|
|
48
|
+
function normalizeTimeZone(timeZone) {
|
|
49
|
+
const normalized = timeZone.trim();
|
|
50
|
+
if (!normalized) {
|
|
51
|
+
throw new Error(`[${PLUGIN_NAME}] "timeZone" cannot be empty.`);
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
new Intl.DateTimeFormat("en-US", { timeZone: normalized }).format(/* @__PURE__ */ new Date());
|
|
55
|
+
} catch {
|
|
56
|
+
throw new Error(`[${PLUGIN_NAME}] "timeZone" is invalid.`);
|
|
57
|
+
}
|
|
58
|
+
return normalized;
|
|
59
|
+
}
|
|
35
60
|
function normalizeData(data) {
|
|
36
61
|
if (data === void 0) {
|
|
37
62
|
return {};
|
|
@@ -91,59 +116,45 @@ function toRequestPath(base, fileName) {
|
|
|
91
116
|
const baseWithoutTrailingSlash = withLeadingSlash.endsWith("/") ? withLeadingSlash.slice(0, -1) : withLeadingSlash;
|
|
92
117
|
return `${baseWithoutTrailingSlash}/${fileName}`.replace(/\/{2,}/g, "/");
|
|
93
118
|
}
|
|
119
|
+
function resolveVersion(options, context, timeZone) {
|
|
120
|
+
if (typeof options.version === "function") {
|
|
121
|
+
return options.version(context);
|
|
122
|
+
}
|
|
123
|
+
if (options.version !== void 0) {
|
|
124
|
+
return options.version;
|
|
125
|
+
}
|
|
126
|
+
return createDefaultVersion(context.command, timeZone);
|
|
127
|
+
}
|
|
128
|
+
function createPayload(options, context, data, timeZone, packageInfo = {}) {
|
|
129
|
+
let nextPayload = {
|
|
130
|
+
...data,
|
|
131
|
+
...packageInfo,
|
|
132
|
+
time: resolveVersion(options, context, timeZone),
|
|
133
|
+
env: context.mode
|
|
134
|
+
};
|
|
135
|
+
if (options.payload) {
|
|
136
|
+
nextPayload = options.payload(nextPayload);
|
|
137
|
+
}
|
|
138
|
+
return nextPayload;
|
|
139
|
+
}
|
|
94
140
|
function buildVersionPlugin(options = {}) {
|
|
95
141
|
const fileName = normalizeFileName(options.filename ?? DEFAULT_FILENAME);
|
|
96
142
|
const globalName = normalizeGlobalName(
|
|
97
143
|
options.globalName ?? DEFAULT_GLOBAL_NAME
|
|
98
144
|
);
|
|
99
145
|
const injectToHtml = options.injectToHtml ?? true;
|
|
146
|
+
const timeZone = normalizeTimeZone(options.timeZone ?? DEFAULT_TIME_ZONE);
|
|
100
147
|
const data = normalizeData(options.data);
|
|
101
|
-
let packageInfo = {};
|
|
102
148
|
let payload;
|
|
103
149
|
return {
|
|
104
150
|
name: PLUGIN_NAME,
|
|
105
|
-
config(config, { command }) {
|
|
106
|
-
const context = {
|
|
107
|
-
command,
|
|
108
|
-
mode: config.mode || "development"
|
|
109
|
-
};
|
|
110
|
-
let version;
|
|
111
|
-
if (typeof options.version === "function") {
|
|
112
|
-
version = options.version(context);
|
|
113
|
-
} else if (options.version !== void 0) {
|
|
114
|
-
version = options.version;
|
|
115
|
-
} else {
|
|
116
|
-
version = createDefaultVersion(context.command);
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
define: {
|
|
120
|
-
[`import.meta.env.${globalName}`]: JSON.stringify(version)
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
},
|
|
124
151
|
configResolved(config) {
|
|
125
|
-
packageInfo = readPackageInfo(config.root);
|
|
126
152
|
const context = {
|
|
127
153
|
command: config.command,
|
|
128
154
|
mode: config.mode
|
|
129
155
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
version = options.version(context);
|
|
133
|
-
} else if (options.version !== void 0) {
|
|
134
|
-
version = options.version;
|
|
135
|
-
} else {
|
|
136
|
-
version = createDefaultVersion(context.command);
|
|
137
|
-
}
|
|
138
|
-
payload = {
|
|
139
|
-
...data,
|
|
140
|
-
...packageInfo,
|
|
141
|
-
time: version,
|
|
142
|
-
env: config.mode
|
|
143
|
-
};
|
|
144
|
-
if (options.payload) {
|
|
145
|
-
payload = options.payload(payload);
|
|
146
|
-
}
|
|
156
|
+
const packageInfo = readPackageInfo(config.root);
|
|
157
|
+
payload = createPayload(options, context, data, timeZone, packageInfo);
|
|
147
158
|
},
|
|
148
159
|
configureServer(server) {
|
|
149
160
|
const requestPath = toRequestPath(server.config.base, fileName);
|