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 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
- - 用 `import.meta.env.__VERSION__` 读取当前页面版本
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
- ### 方式三:读取 `version.json`
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 !== import.meta.env.__VERSION__) {
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` 和 `import.meta.env.__VERSION__` 是否一致
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
- function createDefaultVersion(command) {
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 date = /* @__PURE__ */ new Date();
37
- const pad = (value) => value.toString().padStart(2, "0");
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
- date.getFullYear(),
40
- pad(date.getMonth() + 1),
41
- pad(date.getDate()),
42
- pad(date.getHours()),
43
- pad(date.getMinutes()),
44
- pad(date.getSeconds())
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
- let version;
156
- if (typeof options.version === "function") {
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
- function createDefaultVersion(command) {
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 date = /* @__PURE__ */ new Date();
12
- const pad = (value) => value.toString().padStart(2, "0");
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
- date.getFullYear(),
15
- pad(date.getMonth() + 1),
16
- pad(date.getDate()),
17
- pad(date.getHours()),
18
- pad(date.getMinutes()),
19
- pad(date.getSeconds())
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
- let version;
131
- if (typeof options.version === "function") {
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-build-version-file",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "A Vite plugin that emits version.json and injects version metadata into HTML.",
5
5
  "license": "MIT",
6
6
  "type": "module",