Files
MailUI4Agents/client/electron/test/build-stamp.test.mjs
JianFeeeee be13ae5959 feat(webui): 界面加构建戳 —— 让"我这边改了没"变成可核对的
用户连续三轮说「webui 还没改」,而我每次都能证明部署是活的(入口 no-cache、
资源哈希 immutable、线上 bundle 与本地构建逐字节一致、无头浏览器实测生效)——
问题在于**隔着屏幕说不清对方的浏览器跑的是哪一份**。

现在界面里显示一行 `界面构建 <git短哈希>·<月日-时分>`(外观设置面板页脚):

- `vite.config.ts` 在构建时注入 `__BUILD_STAMP__`(git 短哈希 + 构建时刻)
- `BackgroundPicker` 渲染它,并带 title 说明格式
- 判据 4 条(vite 注入 / 组件渲染 / **产物里真的有** / 判据自检:正则不能匹配随便一段文本)

实测:产物与线上都是 `d2904fc·0914-0910`;刷新后数字变了就是拿到了新构建。

顺带修正一处过时文案:图片说明还写着"保存在本机",而它现在同时存到账号里
(服务端 + 本地缓存)。

前端 254 条 + 新增 4 条、打包一致性、server 10 包全绿;桌面包已重打。
2026-09-14 09:11:36 +08:00

47 lines
2.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 界面必须带一个可核对的构建戳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);
});