diff --git a/client/electron/src/components/BackgroundPicker.tsx b/client/electron/src/components/BackgroundPicker.tsx index 196792f..ca8a8fa 100644 --- a/client/electron/src/components/BackgroundPicker.tsx +++ b/client/electron/src/components/BackgroundPicker.tsx @@ -156,7 +156,7 @@ export default function BackgroundPicker() { )}
- 图片会等比缩放到最长边 2560px 后保存在本机(上限约 2.4MB)。 + 图片会等比缩放到最长边 2560px 后保存在账号里(上限约 2.4MB),本地同时留一份缓存。
{error && (@@ -195,6 +195,8 @@ export default function BackgroundPicker() {
)} + ++ 界面构建 {typeof __BUILD_STAMP__ === 'string' ? __BUILD_STAMP__ : 'unknown'} +
+ ); +} + /** * 同步状态徽标。 * diff --git a/client/electron/src/vite-env.d.ts b/client/electron/src/vite-env.d.ts index c9d9958..7afdca2 100644 --- a/client/electron/src/vite-env.d.ts +++ b/client/electron/src/vite-env.d.ts @@ -9,3 +9,6 @@ interface ImportMetaEnv { interface ImportMeta { readonly env: ImportMetaEnv; } + +/** 构建戳(vite define 注入,见 vite.config.ts)。 */ +declare const __BUILD_STAMP__: string; diff --git a/client/electron/test/build-stamp.test.mjs b/client/electron/test/build-stamp.test.mjs new file mode 100644 index 0000000..c104b09 --- /dev/null +++ b/client/electron/test/build-stamp.test.mjs @@ -0,0 +1,46 @@ +/** + * 界面必须带一个可核对的构建戳(2026-09-14)。 + * + * # 为什么 + * + * 用户连续三轮说「webui 还没改」,而我每次都能证明部署是活的:入口页 `no-cache`、 + * 资源哈希 immutable、线上 bundle 与本地构建逐字节一致……但**隔着屏幕谁也说不清 + * 对方的浏览器跑的是哪一份**。这行字把这件事变成可核对的:它在界面设置里显示 + * `git短哈希·月日-时分`,刷新后数字变了就是拿到了新构建。 + * + * 判据落在三处接线:vite 注入 → 组件渲染 → 产物里真的有。 + */ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync, readdirSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const HERE = dirname(fileURLToPath(import.meta.url)); +const read = p => readFileSync(join(HERE, p), 'utf8'); +const STAMP = /[0-9a-f]{7,}·\d{4}-\d{4}/; + +test('vite 注入 __BUILD_STAMP__', () => { + const cfg = read('../vite.config.ts'); + assert.match(cfg, /__BUILD_STAMP__/); + assert.match(cfg, /git rev-parse --short HEAD/, '戳里要有 git 短哈希'); +}); + +test('界面渲染这个戳', () => { + const cmp = read('../src/components/BackgroundPicker.tsx'); + assert.match(cmp, /__BUILD_STAMP__/, '组件必须渲染它,而不是只定义'); + assert.match(cmp, /界面构建/, '文案里要能认出来'); +}); + +test('★ 构建产物里真的带着戳', () => { + const dir = join(HERE, '../dist/assets'); + const js = readdirSync(dir).filter(f => f.startsWith('index-') && f.endsWith('.js')); + assert.ok(js.length > 0, '先跑 npm run build'); + const found = js.some(f => STAMP.test(readFileSync(join(dir, f), 'utf8'))); + assert.ok(found, '产物里没有构建戳 —— 界面上就永远看不出自己跑的是哪一份'); +}); + +test('判据自检:这个正则不能匹配随便一段文本', () => { + assert.equal(STAMP.test('界面构建 index-abcdef.js'), false); + assert.equal(STAMP.test('d2904fc·0914-0910'), true); +}); diff --git a/client/electron/vite.config.ts b/client/electron/vite.config.ts index 7e6c92b..41bd382 100644 --- a/client/electron/vite.config.ts +++ b/client/electron/vite.config.ts @@ -1,8 +1,29 @@ +import { execSync } from 'node:child_process'; import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; +/** + * 构建戳:界面上要能一眼看出"我现在跑的是哪一次构建"。 + * + * 加它的直接原因:用户连续三轮说"webui 还没改",而每次我都能证明部署是活的 —— + * 问题在于浏览器拿的是哪份 bundle,隔着屏幕谁也说不清。有了这行字, + * 看一眼就知道自己是不是旧的那份(配套:入口页 no-cache、资源哈希 immutable)。 + */ +const BUILD_STAMP = (() => { + let sha = 'unknown'; + try { + sha = execSync('git rev-parse --short HEAD', { cwd: __dirname }).toString().trim(); + } catch { + // 无 git(打包环境等):留 unknown,不影响构建 + } + const t = new Date(); + const pad = (n: number) => String(n).padStart(2, '0'); + return `${sha}·${pad(t.getMonth() + 1)}${pad(t.getDate())}-${pad(t.getHours())}${pad(t.getMinutes())}`; +})(); + export default defineConfig({ plugins: [react()], + define: { __BUILD_STAMP__: JSON.stringify(BUILD_STAMP) }, // ★ 必须是相对路径。 // // 同一份 `dist/` 有两个宿主:网关在 `/` 下伺服它(Web),Electron 用