vite-plugin-build-version-file 0.1.17 → 0.2.0

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/dist/client.cjs CHANGED
@@ -20,123 +20,46 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/client.ts
21
21
  var client_exports = {};
22
22
  __export(client_exports, {
23
- clearUrlCache: () => clearUrlCache
23
+ clearUrlCache: () => clearUrlCache,
24
+ redirectToLoading: () => redirectToLoading
24
25
  });
25
26
  module.exports = __toCommonJS(client_exports);
26
- var CACHE_BUST_PARAM = "_";
27
- var IFRAME_ID = "vite-plugin-build-version-file-cache-iframe";
28
- var LOADING_ID = "vite-plugin-build-version-file-loading";
29
- var IFRAME_TIMEOUT = 5e3;
30
- var DEFAULT_REFRESH_TIME = 5;
31
- function showLoading(time) {
32
- document.getElementById(LOADING_ID)?.remove();
33
- const loading = document.createElement("div");
34
- const spinner = document.createElement("div");
35
- const text = document.createElement("div");
36
- const deadline = Date.now() + time * 1e3;
37
- loading.id = LOADING_ID;
38
- loading.style.cssText = "position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.65);color:#fff;font:14px/1.5 sans-serif;";
39
- spinner.style.cssText = "width:36px;height:36px;margin-bottom:16px;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:vite-build-version-loading .8s linear infinite;";
40
- text.textContent = `\u8BF7\u7A0D\u7B49\uFF0C\u6B63\u5728\u68C0\u6D4B\u66F4\u65B0...\uFF08${Math.ceil(time)}\u79D2\uFF09`;
41
- const style = document.createElement("style");
42
- style.textContent = "@keyframes vite-build-version-loading{to{transform:rotate(360deg)}}";
43
- loading.append(style, spinner, text);
44
- document.documentElement.appendChild(loading);
45
- const countdown = window.setInterval(() => {
46
- const seconds = Math.max(0, Math.ceil((deadline - Date.now()) / 1e3));
47
- text.textContent = `\u8BF7\u7A0D\u7B49\uFF0C\u6B63\u5728\u68C0\u6D4B\u66F4\u65B0...\uFF08${seconds}\u79D2\uFF09`;
48
- }, 1e3);
49
- return () => {
50
- window.clearInterval(countdown);
51
- loading.remove();
52
- };
27
+ var DEFAULT_LOADING_FILENAME = "loading.html";
28
+ function createRandomParamKey() {
29
+ return Math.random().toString(36).slice(2);
53
30
  }
54
- function createCacheBustedUrl(url) {
55
- const targetUrl = new URL(url, window.location.href);
56
- const hash = targetUrl.hash;
57
- targetUrl.hash = "";
58
- targetUrl.searchParams.set(
59
- CACHE_BUST_PARAM,
60
- `${Date.now()}-${Math.random().toString(36).slice(2)}`
31
+ function createLoadingUrl(options) {
32
+ const loadingUrl = new URL(
33
+ options.filename ?? DEFAULT_LOADING_FILENAME,
34
+ window.location.href
61
35
  );
62
- targetUrl.hash = hash;
63
- return targetUrl.href;
64
- }
65
- function createIndexUrl(url) {
66
- const targetUrl = new URL(url);
67
- if (!targetUrl.pathname.endsWith("/")) {
68
- targetUrl.pathname += "/";
36
+ const defaultUrl = window.location.origin + window.location.pathname;
37
+ const indexUrl = defaultUrl.endsWith("/") ? `${defaultUrl}index.html` : `${defaultUrl}/index.html`;
38
+ const urls = options.urls && options.urls.length > 0 ? options.urls : [defaultUrl, indexUrl];
39
+ const payload = {
40
+ urls,
41
+ redirectUrl: options.redirectUrl ?? window.location.href
42
+ };
43
+ if (options.time !== void 0) {
44
+ payload.time = options.time;
69
45
  }
70
- targetUrl.pathname += "index.html";
71
- return targetUrl.href;
72
- }
73
- function loadIframe(url) {
74
- return new Promise((resolve) => {
75
- document.getElementById(IFRAME_ID)?.remove();
76
- const iframe = document.createElement("iframe");
77
- let completed = false;
78
- const complete = () => {
79
- if (completed) {
80
- return;
81
- }
82
- completed = true;
83
- window.clearTimeout(timeout);
84
- resolve();
85
- };
86
- const timeout = window.setTimeout(complete, IFRAME_TIMEOUT);
87
- iframe.hidden = true;
88
- iframe.id = IFRAME_ID;
89
- iframe.addEventListener("load", complete, { once: true });
90
- iframe.addEventListener("error", complete, { once: true });
91
- iframe.src = url;
92
- document.documentElement.appendChild(iframe);
93
- });
46
+ if (options.times !== void 0) {
47
+ payload.times = options.times;
48
+ }
49
+ if (options.title) {
50
+ payload.title = options.title;
51
+ }
52
+ loadingUrl.searchParams.set(createRandomParamKey(), JSON.stringify(payload));
53
+ return loadingUrl.href;
94
54
  }
95
- async function clearTargetUrlCache(url) {
96
- const targetUrl = new URL(url, window.location.href).href;
97
- console.info(`[vite-plugin-build-version] Clear cache for ${targetUrl}`);
98
- await Promise.allSettled([
99
- fetch(createCacheBustedUrl(targetUrl), { cache: "no-store" }).then(
100
- (response) => response.arrayBuffer()
101
- ),
102
- fetch(targetUrl, { cache: "reload" }).then(
103
- (response) => response.arrayBuffer()
104
- )
105
- ]);
106
- await loadIframe(createCacheBustedUrl(targetUrl));
55
+ function redirectToLoading(options = {}) {
56
+ window.location.href = createLoadingUrl(options);
107
57
  }
108
- async function clearUrlCache(options = {}) {
109
- const defaultUrl = window.location.origin + window.location.pathname;
110
- const urls = options.urls ?? [defaultUrl, createIndexUrl(defaultUrl)];
111
- const configuredTime = options.time;
112
- const time = typeof configuredTime === "number" && Number.isFinite(configuredTime) && configuredTime > 0 ? configuredTime : DEFAULT_REFRESH_TIME;
113
- const redirectUrl = new URL(
114
- options.redirectUrl ?? urls[0] ?? defaultUrl,
115
- window.location.href
116
- ).href;
117
- const hideLoading = showLoading(time);
118
- let refreshTimeout = 0;
119
- try {
120
- await Promise.race([
121
- (async () => {
122
- for (const url of urls) {
123
- try {
124
- await clearTargetUrlCache(url);
125
- } catch {
126
- }
127
- }
128
- })(),
129
- new Promise((resolve) => {
130
- refreshTimeout = window.setTimeout(resolve, time * 1e3);
131
- })
132
- ]);
133
- } finally {
134
- window.clearTimeout(refreshTimeout);
135
- hideLoading();
136
- window.location.replace(createCacheBustedUrl(redirectUrl));
137
- }
58
+ function clearUrlCache(options = {}) {
59
+ redirectToLoading(options);
138
60
  }
139
61
  // Annotate the CommonJS export names for ESM import in node:
140
62
  0 && (module.exports = {
141
- clearUrlCache
63
+ clearUrlCache,
64
+ redirectToLoading
142
65
  });
package/dist/client.d.cts CHANGED
@@ -1,8 +1,12 @@
1
- interface ClearUrlCacheOptions {
1
+ interface RedirectToLoadingOptions {
2
2
  urls?: string[];
3
3
  redirectUrl?: string;
4
4
  time?: number;
5
+ times?: number;
6
+ title?: string;
7
+ filename?: string;
5
8
  }
6
- declare function clearUrlCache(options?: ClearUrlCacheOptions): Promise<void>;
9
+ declare function redirectToLoading(options?: RedirectToLoadingOptions): void;
10
+ declare function clearUrlCache(options?: RedirectToLoadingOptions): void;
7
11
 
8
- export { type ClearUrlCacheOptions, clearUrlCache };
12
+ export { type RedirectToLoadingOptions, clearUrlCache, redirectToLoading };
package/dist/client.d.ts CHANGED
@@ -1,8 +1,12 @@
1
- interface ClearUrlCacheOptions {
1
+ interface RedirectToLoadingOptions {
2
2
  urls?: string[];
3
3
  redirectUrl?: string;
4
4
  time?: number;
5
+ times?: number;
6
+ title?: string;
7
+ filename?: string;
5
8
  }
6
- declare function clearUrlCache(options?: ClearUrlCacheOptions): Promise<void>;
9
+ declare function redirectToLoading(options?: RedirectToLoadingOptions): void;
10
+ declare function clearUrlCache(options?: RedirectToLoadingOptions): void;
7
11
 
8
- export { type ClearUrlCacheOptions, clearUrlCache };
12
+ export { type RedirectToLoadingOptions, clearUrlCache, redirectToLoading };
package/dist/client.mjs CHANGED
@@ -1,117 +1,39 @@
1
1
  // src/client.ts
2
- var CACHE_BUST_PARAM = "_";
3
- var IFRAME_ID = "vite-plugin-build-version-file-cache-iframe";
4
- var LOADING_ID = "vite-plugin-build-version-file-loading";
5
- var IFRAME_TIMEOUT = 5e3;
6
- var DEFAULT_REFRESH_TIME = 5;
7
- function showLoading(time) {
8
- document.getElementById(LOADING_ID)?.remove();
9
- const loading = document.createElement("div");
10
- const spinner = document.createElement("div");
11
- const text = document.createElement("div");
12
- const deadline = Date.now() + time * 1e3;
13
- loading.id = LOADING_ID;
14
- loading.style.cssText = "position:fixed;inset:0;z-index:2147483647;display:flex;flex-direction:column;align-items:center;justify-content:center;background:rgba(0,0,0,.65);color:#fff;font:14px/1.5 sans-serif;";
15
- spinner.style.cssText = "width:36px;height:36px;margin-bottom:16px;border:3px solid rgba(255,255,255,.35);border-top-color:#fff;border-radius:50%;animation:vite-build-version-loading .8s linear infinite;";
16
- text.textContent = `\u8BF7\u7A0D\u7B49\uFF0C\u6B63\u5728\u68C0\u6D4B\u66F4\u65B0...\uFF08${Math.ceil(time)}\u79D2\uFF09`;
17
- const style = document.createElement("style");
18
- style.textContent = "@keyframes vite-build-version-loading{to{transform:rotate(360deg)}}";
19
- loading.append(style, spinner, text);
20
- document.documentElement.appendChild(loading);
21
- const countdown = window.setInterval(() => {
22
- const seconds = Math.max(0, Math.ceil((deadline - Date.now()) / 1e3));
23
- text.textContent = `\u8BF7\u7A0D\u7B49\uFF0C\u6B63\u5728\u68C0\u6D4B\u66F4\u65B0...\uFF08${seconds}\u79D2\uFF09`;
24
- }, 1e3);
25
- return () => {
26
- window.clearInterval(countdown);
27
- loading.remove();
28
- };
2
+ var DEFAULT_LOADING_FILENAME = "loading.html";
3
+ function createRandomParamKey() {
4
+ return Math.random().toString(36).slice(2);
29
5
  }
30
- function createCacheBustedUrl(url) {
31
- const targetUrl = new URL(url, window.location.href);
32
- const hash = targetUrl.hash;
33
- targetUrl.hash = "";
34
- targetUrl.searchParams.set(
35
- CACHE_BUST_PARAM,
36
- `${Date.now()}-${Math.random().toString(36).slice(2)}`
6
+ function createLoadingUrl(options) {
7
+ const loadingUrl = new URL(
8
+ options.filename ?? DEFAULT_LOADING_FILENAME,
9
+ window.location.href
37
10
  );
38
- targetUrl.hash = hash;
39
- return targetUrl.href;
40
- }
41
- function createIndexUrl(url) {
42
- const targetUrl = new URL(url);
43
- if (!targetUrl.pathname.endsWith("/")) {
44
- targetUrl.pathname += "/";
11
+ const defaultUrl = window.location.origin + window.location.pathname;
12
+ const indexUrl = defaultUrl.endsWith("/") ? `${defaultUrl}index.html` : `${defaultUrl}/index.html`;
13
+ const urls = options.urls && options.urls.length > 0 ? options.urls : [defaultUrl, indexUrl];
14
+ const payload = {
15
+ urls,
16
+ redirectUrl: options.redirectUrl ?? window.location.href
17
+ };
18
+ if (options.time !== void 0) {
19
+ payload.time = options.time;
45
20
  }
46
- targetUrl.pathname += "index.html";
47
- return targetUrl.href;
48
- }
49
- function loadIframe(url) {
50
- return new Promise((resolve) => {
51
- document.getElementById(IFRAME_ID)?.remove();
52
- const iframe = document.createElement("iframe");
53
- let completed = false;
54
- const complete = () => {
55
- if (completed) {
56
- return;
57
- }
58
- completed = true;
59
- window.clearTimeout(timeout);
60
- resolve();
61
- };
62
- const timeout = window.setTimeout(complete, IFRAME_TIMEOUT);
63
- iframe.hidden = true;
64
- iframe.id = IFRAME_ID;
65
- iframe.addEventListener("load", complete, { once: true });
66
- iframe.addEventListener("error", complete, { once: true });
67
- iframe.src = url;
68
- document.documentElement.appendChild(iframe);
69
- });
21
+ if (options.times !== void 0) {
22
+ payload.times = options.times;
23
+ }
24
+ if (options.title) {
25
+ payload.title = options.title;
26
+ }
27
+ loadingUrl.searchParams.set(createRandomParamKey(), JSON.stringify(payload));
28
+ return loadingUrl.href;
70
29
  }
71
- async function clearTargetUrlCache(url) {
72
- const targetUrl = new URL(url, window.location.href).href;
73
- console.info(`[vite-plugin-build-version] Clear cache for ${targetUrl}`);
74
- await Promise.allSettled([
75
- fetch(createCacheBustedUrl(targetUrl), { cache: "no-store" }).then(
76
- (response) => response.arrayBuffer()
77
- ),
78
- fetch(targetUrl, { cache: "reload" }).then(
79
- (response) => response.arrayBuffer()
80
- )
81
- ]);
82
- await loadIframe(createCacheBustedUrl(targetUrl));
30
+ function redirectToLoading(options = {}) {
31
+ window.location.href = createLoadingUrl(options);
83
32
  }
84
- async function clearUrlCache(options = {}) {
85
- const defaultUrl = window.location.origin + window.location.pathname;
86
- const urls = options.urls ?? [defaultUrl, createIndexUrl(defaultUrl)];
87
- const configuredTime = options.time;
88
- const time = typeof configuredTime === "number" && Number.isFinite(configuredTime) && configuredTime > 0 ? configuredTime : DEFAULT_REFRESH_TIME;
89
- const redirectUrl = new URL(
90
- options.redirectUrl ?? urls[0] ?? defaultUrl,
91
- window.location.href
92
- ).href;
93
- const hideLoading = showLoading(time);
94
- let refreshTimeout = 0;
95
- try {
96
- await Promise.race([
97
- (async () => {
98
- for (const url of urls) {
99
- try {
100
- await clearTargetUrlCache(url);
101
- } catch {
102
- }
103
- }
104
- })(),
105
- new Promise((resolve) => {
106
- refreshTimeout = window.setTimeout(resolve, time * 1e3);
107
- })
108
- ]);
109
- } finally {
110
- window.clearTimeout(refreshTimeout);
111
- hideLoading();
112
- window.location.replace(createCacheBustedUrl(redirectUrl));
113
- }
33
+ function clearUrlCache(options = {}) {
34
+ redirectToLoading(options);
114
35
  }
115
36
  export {
116
- clearUrlCache
37
+ clearUrlCache,
38
+ redirectToLoading
117
39
  };
package/dist/index.cjs CHANGED
@@ -26,8 +26,216 @@ __export(index_exports, {
26
26
  module.exports = __toCommonJS(index_exports);
27
27
  var import_node_fs = require("fs");
28
28
  var import_node_path = require("path");
29
+
30
+ // src/loading.html
31
+ var loading_default = `<!doctype html>
32
+ <html lang="zh-CN">
33
+ <head>
34
+ <meta charset="UTF-8" />
35
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
36
+ <title>Loading</title>
37
+ <style>
38
+ html,
39
+ body {
40
+ margin: 0;
41
+ height: 100%;
42
+ }
43
+
44
+ #vite-build-version-loading {
45
+ position: fixed;
46
+ inset: 0;
47
+ z-index: 2147483647;
48
+ display: flex;
49
+ flex-direction: column;
50
+ align-items: center;
51
+ justify-content: center;
52
+ gap: 16px;
53
+ color: #333333;
54
+ font: 14px/1.5 sans-serif;
55
+ }
56
+
57
+ #vite-build-version-loading .spinner {
58
+ width: 36px;
59
+ height: 36px;
60
+ border: 3px solid rgba(0, 0, 0, 0.15);
61
+ border-top-color: rgba(0, 0, 0, 0.6);
62
+ border-radius: 50%;
63
+ animation: vite-build-version-loading 0.8s linear infinite;
64
+ }
65
+
66
+ @keyframes vite-build-version-loading {
67
+ to {
68
+ transform: rotate(360deg);
69
+ }
70
+ }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <div id="vite-build-version-loading">
75
+ <div class="spinner"></div>
76
+ </div>
77
+ <script>
78
+ ;(function () {
79
+ var IFRAME_ID = 'vite-plugin-build-version-file-cache-iframe'
80
+ var IFRAME_TIMEOUT = 5000
81
+ var DEFAULT_REFRESH_TIME = 5
82
+ var DEFAULT_CLEAR_TIMES = 2
83
+
84
+ var params = new URLSearchParams(window.location.search)
85
+ // \u53C2\u6570\u540D\u968F\u673A\u751F\u6210\uFF0Cloading \u9875\u6309\u503C\u89E3\u6790\uFF1A\u4EFB\u4F55\u503C\u662F JSON \u7684\u53C2\u6570\u90FD\u89C6\u4E3A\u6E05\u7406\u914D\u7F6E\u3002
86
+ var config = (function () {
87
+ var entries = Array.from(params.entries())
88
+
89
+ for (var i = 0; i < entries.length; i++) {
90
+ try {
91
+ var value = JSON.parse(entries[i][1])
92
+
93
+ if (value && typeof value === 'object' && Array.isArray(value.urls)) {
94
+ return value
95
+ }
96
+ } catch (error) {
97
+ // \u975E JSON \u53C2\u6570\uFF08\u4F8B\u5982\u81EA\u5B9A\u4E49 query\uFF09\u76F4\u63A5\u8DF3\u8FC7\u3002
98
+ }
99
+ }
100
+
101
+ return {}
102
+ })()
103
+ // \u9ED8\u8BA4\u628A\u672C\u9875\u9762\u6240\u5728\u76EE\u5F55\u5F53\u4F5C\u5E94\u7528\u6839\u8DEF\u5F84\u3002
104
+ var directoryUrl = new URL('.', window.location.href).href
105
+ var urls = Array.isArray(config.urls)
106
+ ? config.urls.filter(Boolean)
107
+ : []
108
+ var time = Number(config.time)
109
+ var times = Math.floor(Number(config.times))
110
+ var redirectUrl = config.redirectUrl || directoryUrl
111
+ var title = config.title
112
+
113
+ if (urls.length === 0) {
114
+ urls = [directoryUrl, new URL('index.html', directoryUrl).href]
115
+ }
116
+
117
+ if (!Number.isFinite(time) || time <= 0) {
118
+ time = DEFAULT_REFRESH_TIME
119
+ }
120
+
121
+ if (!Number.isFinite(times) || times < 1) {
122
+ times = DEFAULT_CLEAR_TIMES
123
+ }
124
+
125
+ if (title) {
126
+ var titleElement = document.createElement('div')
127
+ titleElement.textContent = title
128
+ document.getElementById('vite-build-version-loading').appendChild(titleElement)
129
+ }
130
+
131
+ function createCacheBustKey() {
132
+ // \u53C2\u6570\u540D\u968F\u673A\uFF0C\u907F\u514D\u670D\u52A1\u5668\u6216 CDN \u9488\u5BF9\u56FA\u5B9A\u53C2\u6570\u540D\uFF08\u5982 _\u3001t\uFF09\u505A\u7F13\u5B58\u5904\u7406\u3002
133
+ return Date.now().toString(36) + Math.random().toString(36).slice(2, 8)
134
+ }
135
+
136
+ function createCacheBustedUrl(url) {
137
+ var targetUrl = new URL(url, window.location.href)
138
+ var hash = targetUrl.hash
139
+
140
+ // hash \u4E0D\u53C2\u4E0E HTTP \u8BF7\u6C42\uFF0C\u5148\u4FDD\u7559\u4E1A\u52A1\u8DEF\u7531\uFF0C\u518D\u5411\u771F\u5B9E\u8BF7\u6C42 URL \u5199\u5165\u7F13\u5B58\u6233\u3002
141
+ targetUrl.hash = ''
142
+ targetUrl.searchParams.set(
143
+ createCacheBustKey(),
144
+ Date.now() + '-' + Math.random().toString(36).slice(2)
145
+ )
146
+ targetUrl.hash = hash
147
+
148
+ return targetUrl.href
149
+ }
150
+
151
+ function loadIframe(url) {
152
+ return new Promise(function (resolve) {
153
+ // \u540C\u4E00\u9875\u9762\u53EA\u4FDD\u7559\u4E00\u4E2A\u7F13\u5B58\u5237\u65B0 iframe\uFF0C\u521B\u5EFA\u524D\u5148\u9500\u6BC1\u65E7\u5B9E\u4F8B\u3002
154
+ var existing = document.getElementById(IFRAME_ID)
155
+
156
+ if (existing) {
157
+ existing.remove()
158
+ }
159
+
160
+ var iframe = document.createElement('iframe')
161
+ var frameTimeout = 0
162
+ var completed = false
163
+
164
+ function complete() {
165
+ if (completed) {
166
+ return
167
+ }
168
+
169
+ completed = true
170
+ window.clearTimeout(frameTimeout)
171
+ resolve()
172
+ }
173
+
174
+ frameTimeout = window.setTimeout(complete, IFRAME_TIMEOUT)
175
+
176
+ iframe.hidden = true
177
+ iframe.id = IFRAME_ID
178
+ iframe.addEventListener('load', complete, { once: true })
179
+ iframe.addEventListener('error', complete, { once: true })
180
+ iframe.src = url
181
+ document.documentElement.appendChild(iframe)
182
+ })
183
+ }
184
+
185
+ function clearTargetUrlCache(url) {
186
+ var targetUrl = new URL(url, window.location.href).href
187
+ console.info('[vite-plugin-build-version] Clear cache for ' + targetUrl)
188
+
189
+ // \u968F\u673A URL \u7ED5\u8FC7\u65E7\u7F13\u5B58\uFF0C\u539F URL \u4F7F\u7528 reload \u6A21\u5F0F\u5237\u65B0\u5BF9\u5E94\u7F13\u5B58\u6761\u76EE\u3002
190
+ // \u7B49\u5F85\u54CD\u5E94\u4F53\u5B8C\u6574\u8BFB\u53D6\uFF0C\u907F\u514D\u540E\u7EED\u8DF3\u8F6C\u63D0\u524D\u53D6\u6D88\u7F13\u5B58\u5237\u65B0\u8BF7\u6C42\u3002
191
+ return Promise.allSettled([
192
+ fetch(createCacheBustedUrl(targetUrl), { cache: 'no-store' }).then(
193
+ function (response) {
194
+ return response.arrayBuffer()
195
+ }
196
+ ),
197
+ fetch(targetUrl, { cache: 'reload' }).then(function (response) {
198
+ return response.arrayBuffer()
199
+ })
200
+ ]).then(function () {
201
+ // iframe \u518D\u89E6\u53D1\u4E00\u6B21\u9875\u9762\u8D44\u6E90\u52A0\u8F7D\uFF0C\u8D85\u65F6\u6216\u5931\u8D25\u7531\u5916\u5C42\u7EE7\u7EED\u5904\u7406\u540E\u7EED URL\u3002
202
+ return loadIframe(createCacheBustedUrl(targetUrl))
203
+ })
204
+ }
205
+
206
+ var refreshTimeoutId = 0
207
+ var clearAllDone = (async function () {
208
+ // \u6574\u5957\u6E05\u7406\u64CD\u4F5C\u6309 times \u91CD\u590D\u6267\u884C\uFF0C\u9ED8\u8BA4 2 \u6B21\u3002
209
+ for (var round = 0; round < times; round++) {
210
+ for (var i = 0; i < urls.length; i++) {
211
+ try {
212
+ await clearTargetUrlCache(urls[i])
213
+ } catch (error) {
214
+ // \u5355\u7EC4\u5931\u8D25\u4E0D\u963B\u65AD\u540E\u7EED URL\uFF0C\u4FDD\u8BC1\u914D\u7F6E\u7684\u68C0\u6D4B\u7EC4\u90FD\u80FD\u6267\u884C\u3002
215
+ }
216
+ }
217
+ }
218
+ })()
219
+ var limitReached = new Promise(function (resolve) {
220
+ // \u5230\u8FBE\u603B\u7B49\u5F85\u65F6\u9650\u540E\u76F4\u63A5\u8DF3\u8F6C\uFF0C\u4E0D\u53D7\u7F13\u5B58\u8BF7\u6C42\u72B6\u6001\u5F71\u54CD\u3002
221
+ refreshTimeoutId = window.setTimeout(resolve, time * 1000)
222
+ })
223
+
224
+ Promise.race([clearAllDone, limitReached]).then(function () {
225
+ window.clearTimeout(refreshTimeoutId)
226
+ // \u6700\u7EC8\u8DF3\u8F6C\u539F\u6837\u4F7F\u7528\u76EE\u6807\u5730\u5740\uFF0C\u4E0D\u9644\u52A0\u7F13\u5B58\u6233\u3002
227
+ window.location.replace(redirectUrl)
228
+ })
229
+ })()
230
+ </script>
231
+ </body>
232
+ </html>
233
+ `;
234
+
235
+ // src/index.ts
29
236
  var PLUGIN_NAME = "vite-plugin-build-version-file";
30
237
  var DEFAULT_FILENAME = "version.json";
238
+ var DEFAULT_LOADING_PAGE = "loading";
31
239
  var DEFAULT_GLOBAL_NAME = "__VERSION__";
32
240
  var DEFAULT_DEFINE_NAME = "__VERSION__";
33
241
  var DEFAULT_TIME_ZONE = "Asia/Shanghai";
@@ -65,6 +273,16 @@ function normalizeFileName(filename) {
65
273
  }
66
274
  return normalized;
67
275
  }
276
+ function normalizeLoadingPage(loadingPage) {
277
+ if (loadingPage === false) {
278
+ return false;
279
+ }
280
+ const normalized = (loadingPage ?? DEFAULT_LOADING_PAGE).trim().replace(/^\/+/, "");
281
+ if (!normalized) {
282
+ throw new Error(`[${PLUGIN_NAME}] "loadingPage" cannot be empty.`);
283
+ }
284
+ return normalized.endsWith(".html") ? normalized : `${normalized}.html`;
285
+ }
68
286
  function normalizeGlobalName(globalName) {
69
287
  if (!globalName.trim()) {
70
288
  throw new Error(`[${PLUGIN_NAME}] "globalName" cannot be empty.`);
@@ -142,6 +360,9 @@ function serializePayload(payload) {
142
360
  function createInjectScript(globalName, payload) {
143
361
  return `window[${JSON.stringify(globalName)}] = ${JSON.stringify(payload)};`;
144
362
  }
363
+ function createInjectScriptTag(globalName, payload) {
364
+ return `<script>${createInjectScript(globalName, payload)}</script>`;
365
+ }
145
366
  function injectScriptToHead(code, script) {
146
367
  const scriptTag = `<script>${script}</script>`;
147
368
  if (code.includes(script)) {
@@ -164,6 +385,13 @@ function toRequestPath(base, fileName) {
164
385
  const baseWithoutTrailingSlash = withLeadingSlash.endsWith("/") ? withLeadingSlash.slice(0, -1) : withLeadingSlash;
165
386
  return `${baseWithoutTrailingSlash}/${fileName}`.replace(/\/{2,}/g, "/");
166
387
  }
388
+ function resolveNuxtFileName(config, fileName) {
389
+ if (config.appType !== "custom" || config.build.copyPublicDir !== false) {
390
+ return fileName;
391
+ }
392
+ const assetDir = normalizeFileName(config.build.assetsDir);
393
+ return assetDir === "." || fileName.startsWith(`${assetDir}/`) ? fileName : `${assetDir}/${fileName}`;
394
+ }
167
395
  function resolveProjectRoot(root) {
168
396
  return root ? (0, import_node_path.resolve)(process.cwd(), root) : process.cwd();
169
397
  }
@@ -190,6 +418,7 @@ function createPayload(options, context, data, timeZone, packageInfo = {}) {
190
418
  }
191
419
  function buildVersionPlugin(options = {}) {
192
420
  const fileName = normalizeFileName(options.filename ?? DEFAULT_FILENAME);
421
+ const loadingPage = normalizeLoadingPage(options.loadingPage);
193
422
  const globalName = normalizeGlobalName(
194
423
  options.globalName ?? DEFAULT_GLOBAL_NAME
195
424
  );
@@ -201,12 +430,20 @@ function buildVersionPlugin(options = {}) {
201
430
  const data = normalizeData(options.data);
202
431
  let payload;
203
432
  let skipBundleEmit = false;
433
+ let bundleFileName = fileName;
434
+ let bundleLoadingFileName = loadingPage;
204
435
  const transformHtml = (code, ..._args) => {
205
436
  if (!injectToHtml || !payload) {
206
437
  return void 0;
207
438
  }
208
439
  return injectScriptToHead(code, createInjectScript(globalName, payload));
209
440
  };
441
+ const headScript = () => {
442
+ if (!injectToHtml || !payload) {
443
+ return "";
444
+ }
445
+ return createInjectScriptTag(globalName, payload);
446
+ };
210
447
  const plugin = {
211
448
  name: PLUGIN_NAME,
212
449
  config(userConfig, env) {
@@ -229,6 +466,10 @@ function buildVersionPlugin(options = {}) {
229
466
  },
230
467
  configResolved(config) {
231
468
  skipBundleEmit = Boolean(config.build.ssr) && !config.build.ssrEmitAssets;
469
+ bundleFileName = resolveNuxtFileName(config, fileName);
470
+ if (loadingPage) {
471
+ bundleLoadingFileName = resolveNuxtFileName(config, loadingPage);
472
+ }
232
473
  if (payload) {
233
474
  return;
234
475
  }
@@ -241,11 +482,21 @@ function buildVersionPlugin(options = {}) {
241
482
  },
242
483
  configureServer(server) {
243
484
  const requestPath = toRequestPath(server.config.base, fileName);
485
+ const loadingRequestPath = loadingPage ? toRequestPath(server.config.base, loadingPage) : void 0;
244
486
  server.middlewares.use((request, response, next) => {
245
487
  if (request.method !== "GET" && request.method !== "HEAD") {
246
488
  next();
247
489
  return;
248
490
  }
491
+ if (loadingRequestPath && parsePathname(request.url) === loadingRequestPath) {
492
+ response.statusCode = 200;
493
+ response.setHeader("Content-Type", "text/html; charset=utf-8");
494
+ response.setHeader("Cache-Control", "no-cache");
495
+ response.end(
496
+ request.method === "HEAD" ? void 0 : loading_default
497
+ );
498
+ return;
499
+ }
249
500
  if (parsePathname(request.url) !== requestPath || !payload) {
250
501
  next();
251
502
  return;
@@ -276,9 +527,16 @@ function buildVersionPlugin(options = {}) {
276
527
  }
277
528
  this.emitFile({
278
529
  type: "asset",
279
- fileName,
530
+ fileName: bundleFileName,
280
531
  source: serializePayload(payload)
281
532
  });
533
+ if (bundleLoadingFileName) {
534
+ this.emitFile({
535
+ type: "asset",
536
+ fileName: bundleLoadingFileName,
537
+ source: loading_default
538
+ });
539
+ }
282
540
  if (options.log) {
283
541
  console.log(options.log(payload));
284
542
  } else {
@@ -290,6 +548,9 @@ function buildVersionPlugin(options = {}) {
290
548
  Object.defineProperty(plugin, "transformHtml", {
291
549
  value: transformHtml
292
550
  });
551
+ Object.defineProperty(plugin, "headScript", {
552
+ value: headScript
553
+ });
293
554
  return plugin;
294
555
  }
295
556
  var index_default = buildVersionPlugin;