vite-plugin-build-version-file 0.1.18 → 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/README.md +170 -24
- package/dist/client.cjs +32 -109
- package/dist/client.d.cts +7 -3
- package/dist/client.d.ts +7 -3
- package/dist/client.mjs +30 -108
- package/dist/index.cjs +250 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +250 -1
- package/package.json +9 -10
package/README.md
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
它负责在开发态和构建产物中暴露统一的版本信息:
|
|
6
6
|
|
|
7
7
|
- 开发态通过 dev server 提供 `version.json`
|
|
8
|
+
- 开发态通过 dev server 提供 `loading.html`,便于本地调试
|
|
8
9
|
- 构建后在输出目录生成 `version.json`
|
|
10
|
+
- 构建后生成与 `index.html` 同级的 `loading.html` 缓存清理页
|
|
9
11
|
- 普通 Vite HTML 自动注入 `window["__VERSION__"]`
|
|
10
12
|
- 可选通过 `define` 将同一份 payload 编译进 JS 产物
|
|
11
13
|
- VitePress 可通过顶层 `transformHtml` 注入同一份版本信息
|
|
@@ -107,7 +109,7 @@ export default defineNuxtConfig({
|
|
|
107
109
|
|
|
108
110
|
`headScript()` 返回完整的 `<script>...</script>` 片段;`injectToHtml: false` 时、或 payload 还没生成时返回空字符串(不抛错),所以直接 `push` 是安全的。
|
|
109
111
|
|
|
110
|
-
|
|
112
|
+
插件会自动识别 Nuxt 的构建资产目录,并把 `version.json` emit 到该目录,因此 Nuxt 打包后的静态产物会包含这个文件。默认文件路径为 `/_nuxt/version.json`;如果需要固定使用根路径 `/version.json`,请将文件复制到 Nuxt `public` 目录,或在构建后自行复制。
|
|
111
113
|
|
|
112
114
|
## 默认行为
|
|
113
115
|
|
|
@@ -115,6 +117,7 @@ export default defineNuxtConfig({
|
|
|
115
117
|
|
|
116
118
|
- 开发态访问 `/version.json` 时返回版本信息
|
|
117
119
|
- 构建后输出 `version.json`
|
|
120
|
+
- 构建后输出 `loading.html`
|
|
118
121
|
- 向 HTML 注入 `window["__VERSION__"]`
|
|
119
122
|
- 自动读取业务项目最近的 `package.json`
|
|
120
123
|
- 将 `package.json` 的 `name` 写入 `pkgName`
|
|
@@ -155,6 +158,7 @@ type BuildVersionContext = {
|
|
|
155
158
|
|
|
156
159
|
type BuildVersionPluginOptions = {
|
|
157
160
|
filename?: string
|
|
161
|
+
loadingPage?: string | false
|
|
158
162
|
globalName?: string
|
|
159
163
|
defineName?: string | false
|
|
160
164
|
injectToHtml?: boolean
|
|
@@ -194,6 +198,30 @@ dist/meta/version.json
|
|
|
194
198
|
|
|
195
199
|
如果项目配置了 Vite `base`,访问路径会自动跟随 `base`。
|
|
196
200
|
|
|
201
|
+
### `loadingPage`
|
|
202
|
+
|
|
203
|
+
- 类型:`string | false`
|
|
204
|
+
- 默认值:`"loading"`
|
|
205
|
+
- 作用:控制构建产物中缓存清理页的文件名
|
|
206
|
+
|
|
207
|
+
默认输出 `loading.html`,与 `index.html` 同级。值不带后缀时会自动补 `.html`,也支持子路径:
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
buildVersionPlugin({
|
|
211
|
+
loadingPage: 'cache/loading'
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
构建后输出:
|
|
216
|
+
|
|
217
|
+
```text
|
|
218
|
+
dist/cache/loading.html
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
传 `false` 时不生成该页面。
|
|
222
|
+
|
|
223
|
+
Nuxt 下与 `version.json` 使用同一规则,默认输出到 `_nuxt/loading.html`;如果需要固定使用根路径 `/loading.html`,请将文件复制到 Nuxt `public` 目录,或在构建后自行复制。
|
|
224
|
+
|
|
197
225
|
### `globalName`
|
|
198
226
|
|
|
199
227
|
- 类型:`string`
|
|
@@ -465,48 +493,92 @@ void checkVersion()
|
|
|
465
493
|
## 刷新指定项目缓存
|
|
466
494
|
|
|
467
495
|
```ts
|
|
468
|
-
import {
|
|
496
|
+
import { redirectToLoading } from 'vite-plugin-build-version-file/client'
|
|
469
497
|
|
|
470
|
-
|
|
498
|
+
redirectToLoading({
|
|
471
499
|
urls: ['/vue-app/', '/vue-app/index.html'],
|
|
472
500
|
redirectUrl: '/vue-app/',
|
|
473
|
-
time: 5
|
|
501
|
+
time: 5,
|
|
502
|
+
times: 2,
|
|
503
|
+
title: '正在清理缓存',
|
|
504
|
+
filename: 'loading.html'
|
|
474
505
|
})
|
|
475
506
|
```
|
|
476
507
|
|
|
477
|
-
|
|
508
|
+
`redirectToLoading` 只负责携带参数跳转到构建产物中的 `loading.html`,不向当前页面注入任何 DOM,也不在主页面执行清理逻辑。缓存清理与跳转全部发生在 `loading.html` 内:
|
|
509
|
+
|
|
510
|
+
- 打开后立即执行清理,并显示全屏 loading
|
|
511
|
+
- 缓存处理提前完成时会立即跳转;到达 `time` 时限(单位秒,默认 `5`)后无论调用结果如何都会跳转
|
|
512
|
+
- 跳转发生在 `loading.html` 内,主页面代码无需等待
|
|
478
513
|
|
|
479
|
-
|
|
514
|
+
参数对象可省略:
|
|
515
|
+
|
|
516
|
+
```ts
|
|
517
|
+
redirectToLoading()
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
无参时按顺序检测以下两组 URL:
|
|
480
521
|
|
|
481
522
|
1. `location.origin + location.pathname`
|
|
482
523
|
2. 第一组 URL 拼接 `index.html`
|
|
483
524
|
|
|
484
|
-
|
|
525
|
+
完成后跳转回 `window.location.href`(query 与 hash 原样保留,不追加缓存戳)。
|
|
526
|
+
|
|
527
|
+
参数说明:
|
|
528
|
+
|
|
529
|
+
- `urls`:需要清理缓存的 URL 列表,可传多个。默认如上两条
|
|
530
|
+
- `redirectUrl`:清理完成或超时后跳转的目标 URL。默认为调用时的 `window.location.href`
|
|
531
|
+
- `time`:最长等待秒数,默认 `5`
|
|
532
|
+
- `times`:整套清理操作重复执行的次数,默认 `2`
|
|
533
|
+
- `title`:传入后在 loading 页中心显示该文案;不传只显示 loading 图标
|
|
534
|
+
- `filename`:`loading.html` 的路径,默认 `loading.html`,相对当前页面解析
|
|
535
|
+
|
|
536
|
+
除 `filename` 外的参数会合并成一个 JSON 对象,写在随机参数名的 query 参数下;loading 页按参数值解析,不依赖参数名。
|
|
537
|
+
|
|
538
|
+
loading 页默认透明背景,不遮挡页面底色;`title` 传了才显示文字。
|
|
539
|
+
|
|
540
|
+
仍然可以用旧名调用,行为一致:
|
|
485
541
|
|
|
486
542
|
```ts
|
|
487
|
-
|
|
543
|
+
import { clearUrlCache } from 'vite-plugin-build-version-file/client'
|
|
544
|
+
|
|
545
|
+
clearUrlCache({ urls: ['/vue-app/'] })
|
|
488
546
|
```
|
|
489
547
|
|
|
490
|
-
Vue hash
|
|
548
|
+
Vue hash 路由会原样保留。缓存戳只加在 loading 页内部的 fetch / iframe 请求上,用于绕过旧缓存;最终跳转地址原样使用,不附加任何参数:
|
|
491
549
|
|
|
492
550
|
```text
|
|
493
|
-
https://xxxx/pc
|
|
551
|
+
调用页:https://xxxx/pc/#/login?redirect=/dashboard/analysis
|
|
552
|
+
清理请求:https://xxxx/pc/?随机参数名=随机值
|
|
553
|
+
最终跳转:https://xxxx/pc/#/login?redirect=/dashboard/analysis
|
|
494
554
|
```
|
|
495
555
|
|
|
496
|
-
|
|
556
|
+
`loading.html` 内仅支持同源 URL。它会绕过缓存请求 URL、强制刷新原 URL、通过隐藏 iframe 再次加载页面,最后跳转到目标 URL(不附加缓存戳)。创建 iframe 前会销毁同一页面中已有的缓存刷新 iframe。单次请求或 iframe 加载失败不会阻断最终跳转。
|
|
497
557
|
|
|
498
558
|
受浏览器限制,前端代码无法直接删除指定 URL 下的全部 HTTP 缓存;该方法只能尽可能刷新对应 Vue 项目的缓存。
|
|
499
559
|
|
|
560
|
+
直接打开 `loading.html` 且不带 query 时,默认以 `loading.html` 所在目录作为应用根路径执行同一套清理。
|
|
561
|
+
|
|
500
562
|
## 开发态行为
|
|
501
563
|
|
|
502
564
|
开发态下,插件不会向业务项目目录写入文件。
|
|
503
565
|
|
|
504
|
-
它会通过 Vite dev server
|
|
566
|
+
它会通过 Vite dev server 直接返回,不落文件:
|
|
505
567
|
|
|
568
|
+
- `version.json`:版本信息 JSON
|
|
569
|
+
- `loading.html`:与构建态同路径规则(可用 `loadingPage` 调整),可直接在浏览器打开调试清理与跳转流程
|
|
506
570
|
- 不污染 `public/`
|
|
507
571
|
- 不需要生成临时文件
|
|
508
572
|
- 修改插件配置后重启 dev server 即可生效
|
|
509
573
|
|
|
574
|
+
调试 loading 页时,query 参数与构建态一致:参数名随机,值是包含 `urls` 的 JSON,例如:
|
|
575
|
+
|
|
576
|
+
```text
|
|
577
|
+
http://localhost:5173/loading.html?x7k2q9={"urls":["http://localhost:5173/","http://localhost:5173/index.html"],"redirectUrl":"http://localhost:5173/","time":5,"times":2,"title":"调试"}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
也可以直接打开 `http://localhost:5173/loading.html`,按所在目录执行默认清理。
|
|
581
|
+
|
|
510
582
|
## 本地开发
|
|
511
583
|
|
|
512
584
|
仓库提供了两个调试用示例项目:
|
|
@@ -548,6 +620,7 @@ npm pack --dry-run
|
|
|
548
620
|
建议检查:
|
|
549
621
|
|
|
550
622
|
- `debug/fixture-app/dist/version.json` 包含 `time`、`env`、`pkgName`、`pkgVersion`
|
|
623
|
+
- `debug/fixture-app/dist/loading.html` 与 `index.html` 同级生成
|
|
551
624
|
- `debug/fixture-app/dist/index.html` 只注入一次 `window["__VERSION__"]`
|
|
552
625
|
- `debug/vitepress-app/.vitepress/dist/meta/version.json` 包含 `fixture`、`time`、`env`
|
|
553
626
|
- VitePress 每个 HTML 只注入一次 `window["__VERSION__"]`
|
|
@@ -596,7 +669,9 @@ npm pack
|
|
|
596
669
|
It exposes one consistent version payload in development and production:
|
|
597
670
|
|
|
598
671
|
- serves `version.json` through the Vite dev server
|
|
672
|
+
- serves `loading.html` through the Vite dev server for local debugging
|
|
599
673
|
- emits `version.json` into the build output directory
|
|
674
|
+
- emits a `loading.html` cache-clearing page next to `index.html`
|
|
600
675
|
- injects `window["__VERSION__"]` into normal Vite HTML
|
|
601
676
|
- supports VitePress through its top-level `transformHtml` hook
|
|
602
677
|
- supports custom versions, filenames, global variable names, time zones, and extra payload fields
|
|
@@ -697,7 +772,7 @@ export default defineNuxtConfig({
|
|
|
697
772
|
|
|
698
773
|
`headScript()` returns a complete `<script>...</script>` snippet. It returns an empty string when `injectToHtml: false` or when the payload has not been created yet, so pushing it directly is safe.
|
|
699
774
|
|
|
700
|
-
|
|
775
|
+
The plugin automatically detects Nuxt's build assets directory and emits `version.json` there, so Nuxt's static output includes the file. The default URL is `/_nuxt/version.json`; if the file must stay at `/version.json`, copy it into Nuxt's `public` directory or copy it after the build.
|
|
701
776
|
|
|
702
777
|
## Default Behavior
|
|
703
778
|
|
|
@@ -705,6 +780,7 @@ With default options, the plugin:
|
|
|
705
780
|
|
|
706
781
|
- serves `/version.json` in development
|
|
707
782
|
- emits `version.json` after build
|
|
783
|
+
- emits `loading.html` after build
|
|
708
784
|
- injects `window["__VERSION__"]` into HTML
|
|
709
785
|
- reads the nearest project `package.json`
|
|
710
786
|
- writes `name` as `pkgName`
|
|
@@ -745,6 +821,7 @@ type BuildVersionContext = {
|
|
|
745
821
|
|
|
746
822
|
type BuildVersionPluginOptions = {
|
|
747
823
|
filename?: string
|
|
824
|
+
loadingPage?: string | false
|
|
748
825
|
globalName?: string
|
|
749
826
|
injectToHtml?: boolean
|
|
750
827
|
timeZone?: string
|
|
@@ -781,6 +858,30 @@ Development URL:
|
|
|
781
858
|
|
|
782
859
|
If your project configures Vite `base`, the URL follows that base.
|
|
783
860
|
|
|
861
|
+
### `loadingPage`
|
|
862
|
+
|
|
863
|
+
- Type: `string | false`
|
|
864
|
+
- Default: `"loading"`
|
|
865
|
+
- Controls the filename of the cache-clearing page in the build output.
|
|
866
|
+
|
|
867
|
+
The default emits `loading.html` next to `index.html`. When the value has no suffix, `.html` is appended; sub-paths are supported:
|
|
868
|
+
|
|
869
|
+
```ts
|
|
870
|
+
buildVersionPlugin({
|
|
871
|
+
loadingPage: 'cache/loading'
|
|
872
|
+
})
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
Build output:
|
|
876
|
+
|
|
877
|
+
```text
|
|
878
|
+
dist/cache/loading.html
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
Pass `false` to skip emitting the page.
|
|
882
|
+
|
|
883
|
+
Nuxt uses the same rule as `version.json` and emits `_nuxt/loading.html` by default. If the file must stay at `/loading.html`, copy it into Nuxt's `public` directory or copy it after the build.
|
|
884
|
+
|
|
784
885
|
### `globalName`
|
|
785
886
|
|
|
786
887
|
- Type: `string`
|
|
@@ -1022,48 +1123,92 @@ The example uses native `window.confirm`, so it has no UI framework dependency.
|
|
|
1022
1123
|
## Refreshing a Project Cache
|
|
1023
1124
|
|
|
1024
1125
|
```ts
|
|
1025
|
-
import {
|
|
1126
|
+
import { redirectToLoading } from 'vite-plugin-build-version-file/client'
|
|
1026
1127
|
|
|
1027
|
-
|
|
1128
|
+
redirectToLoading({
|
|
1028
1129
|
urls: ['/vue-app/', '/vue-app/index.html'],
|
|
1029
1130
|
redirectUrl: '/vue-app/',
|
|
1030
|
-
time: 5
|
|
1131
|
+
time: 5,
|
|
1132
|
+
times: 2,
|
|
1133
|
+
title: 'Clearing cache',
|
|
1134
|
+
filename: 'loading.html'
|
|
1031
1135
|
})
|
|
1032
1136
|
```
|
|
1033
1137
|
|
|
1034
|
-
|
|
1138
|
+
`redirectToLoading` only builds the query string and navigates to the `loading.html` emitted by the build. It injects nothing into the current page and runs no cleanup logic there. Cache clearing and navigation both happen inside `loading.html`:
|
|
1139
|
+
|
|
1140
|
+
- cleanup starts as soon as the page opens, with a full-screen loading mask
|
|
1141
|
+
- navigation happens as soon as cleanup finishes; once `time` seconds (default `5`) elapse, it happens regardless of the result
|
|
1142
|
+
- navigation is triggered inside `loading.html`, so the host page does not wait
|
|
1035
1143
|
|
|
1036
|
-
The options object is optional
|
|
1144
|
+
The options object is optional:
|
|
1145
|
+
|
|
1146
|
+
```ts
|
|
1147
|
+
redirectToLoading()
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
Without arguments, the following URL groups are checked in order:
|
|
1037
1151
|
|
|
1038
1152
|
1. `location.origin + location.pathname`
|
|
1039
1153
|
2. The first URL with `index.html` appended
|
|
1040
1154
|
|
|
1041
|
-
After both groups complete,
|
|
1155
|
+
After both groups complete, navigation goes back to the caller's `window.location.href`; query and hash are preserved and no cache-busting parameter is appended.
|
|
1156
|
+
|
|
1157
|
+
Options:
|
|
1158
|
+
|
|
1159
|
+
- `urls`: cache-clearing targets; multiple URLs are supported
|
|
1160
|
+
- `redirectUrl`: target after cleanup or timeout; defaults to `window.location.href` at call time
|
|
1161
|
+
- `time`: maximum wait in seconds, default `5`
|
|
1162
|
+
- `times`: how many times the whole cleanup pass runs, default `2`
|
|
1163
|
+
- `title`: when provided, shows that text in the loading page center; when omitted, only the loading icon is shown
|
|
1164
|
+
- `filename`: path of the loading page, default `loading.html`, resolved against the current page
|
|
1165
|
+
|
|
1166
|
+
Every value except `filename` is merged into a single JSON object placed under a randomly named query parameter; the loading page parses values, not parameter names.
|
|
1167
|
+
|
|
1168
|
+
The loading page uses a transparent background by default, and only shows text when `title` is provided.
|
|
1169
|
+
|
|
1170
|
+
The old name still works and behaves the same:
|
|
1042
1171
|
|
|
1043
1172
|
```ts
|
|
1044
|
-
|
|
1173
|
+
import { clearUrlCache } from 'vite-plugin-build-version-file/client'
|
|
1174
|
+
|
|
1175
|
+
clearUrlCache({ urls: ['/vue-app/'] })
|
|
1045
1176
|
```
|
|
1046
1177
|
|
|
1047
|
-
Vue hash routes are preserved.
|
|
1178
|
+
Vue hash routes are preserved. Cache-busting parameters are added only to the fetch / iframe requests made by the loading page; the final navigation target stays exactly as given:
|
|
1048
1179
|
|
|
1049
1180
|
```text
|
|
1050
|
-
https://xxx.cn/pc
|
|
1181
|
+
caller: https://xxx.cn/pc/#/login?redirect=/dashboard/analysis
|
|
1182
|
+
cleanup request: https://xxx.cn/pc/?random-key=random-value
|
|
1183
|
+
final navigation: https://xxx.cn/pc/#/login?redirect=/dashboard/analysis
|
|
1051
1184
|
```
|
|
1052
1185
|
|
|
1053
|
-
|
|
1186
|
+
`loading.html` only supports same-origin URLs. It bypasses the cached URL, forces a refresh of the original URL, loads the page again in a hidden iframe, and finally navigates to the target URL without any cache-busting parameter. Any existing cache-refresh iframe created by this method is removed before a new one is created. A failed request or iframe load does not prevent the final navigation.
|
|
1054
1187
|
|
|
1055
1188
|
Browser code cannot directly delete every HTTP cache entry under a specific URL. This method refreshes the corresponding Vue application cache on a best-effort basis.
|
|
1056
1189
|
|
|
1190
|
+
Opening `loading.html` directly without a query string treats the page's own directory as the application root and runs the same cleanup flow.
|
|
1191
|
+
|
|
1057
1192
|
## Development Behavior
|
|
1058
1193
|
|
|
1059
1194
|
In development, the plugin does not write files into your project directory.
|
|
1060
1195
|
|
|
1061
|
-
It serves
|
|
1196
|
+
It serves content directly through the Vite dev server without writing files:
|
|
1062
1197
|
|
|
1198
|
+
- `version.json`: the version payload as JSON
|
|
1199
|
+
- `loading.html`: the same cache-clearing page as the build output (path configured by `loadingPage`), so you can open it directly in the browser to debug the cleanup and navigation flow
|
|
1063
1200
|
- no `public/` pollution
|
|
1064
1201
|
- no temporary file generation
|
|
1065
1202
|
- restart the dev server after changing plugin options
|
|
1066
1203
|
|
|
1204
|
+
The loading page accepts the same query parameters in development: the parameter name is random and the value is JSON containing `urls`, for example:
|
|
1205
|
+
|
|
1206
|
+
```text
|
|
1207
|
+
http://localhost:5173/loading.html?x7k2q9={"urls":["http://localhost:5173/","http://localhost:5173/index.html"],"redirectUrl":"http://localhost:5173/","time":5,"times":2,"title":"debug"}
|
|
1208
|
+
```
|
|
1209
|
+
|
|
1210
|
+
You can also open `http://localhost:5173/loading.html` directly to run the default cleanup for its own directory.
|
|
1211
|
+
|
|
1067
1212
|
## Local Development
|
|
1068
1213
|
|
|
1069
1214
|
The repository contains two fixture apps:
|
|
@@ -1105,6 +1250,7 @@ npm pack --dry-run
|
|
|
1105
1250
|
Check:
|
|
1106
1251
|
|
|
1107
1252
|
- `debug/fixture-app/dist/version.json` contains `time`, `env`, `pkgName`, and `pkgVersion`
|
|
1253
|
+
- `debug/fixture-app/dist/loading.html` is emitted next to `index.html`
|
|
1108
1254
|
- `debug/fixture-app/dist/index.html` injects `window["__VERSION__"]` once
|
|
1109
1255
|
- `debug/vitepress-app/.vitepress/dist/meta/version.json` contains `fixture`, `time`, and `env`
|
|
1110
1256
|
- each VitePress HTML file injects `window["__VERSION__"]` once
|
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
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
96
|
-
|
|
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
|
-
|
|
109
|
-
|
|
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
|
|
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
|
|
9
|
+
declare function redirectToLoading(options?: RedirectToLoadingOptions): void;
|
|
10
|
+
declare function clearUrlCache(options?: RedirectToLoadingOptions): void;
|
|
7
11
|
|
|
8
|
-
export { type
|
|
12
|
+
export { type RedirectToLoadingOptions, clearUrlCache, redirectToLoading };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
interface
|
|
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
|
|
9
|
+
declare function redirectToLoading(options?: RedirectToLoadingOptions): void;
|
|
10
|
+
declare function clearUrlCache(options?: RedirectToLoadingOptions): void;
|
|
7
11
|
|
|
8
|
-
export { type
|
|
12
|
+
export { type RedirectToLoadingOptions, clearUrlCache, redirectToLoading };
|