fix(web): ignore a missing documentElement when marking the home screen revealed
This commit is contained in:
+17
-1
@@ -12250,7 +12250,7 @@
|
||||
- 修复:根 layout 增加一段与 bundle 无关的内联经典脚本。13 秒后,若仍有 `.app-loading` 且 `<html data-hydrated>` 不是 `"1"`,把加载内容换成「这个页面没能加载完」和只在点击时刷新的「重新加载」。揭幕成功后由首页装配 hook 写 `data-hydrated="1"`,正常路径不闪这一屏。匿名标记只留类别、构建标识和耗时,不留异常原文或请求体。接口超时仍走 bundle 里原来的「连接云端服务超时」,不并进这一屏。本仓断句的后行断言另见 BUG-998,那一项不能把 Next 运行时的语法下限降到 Safari 16.4 以下。
|
||||
- 验证:`frontend/tests/first-paint-fallback-contract.test.ts` 锁定 ES5、超时大于 8000+4000、未揭幕才替换、按钮才刷新,以及 hydrate 超时 / chunk 404 / 解析失败 / 旧缓存 / 弱网 / 接口错误六类不互相冒充。未在 iPhone Safari 或断 chunk 的浏览器里走查。
|
||||
- 防复发:首屏不得把「出错了」的唯一出口放在可能失败的模块 bundle 里。不得自动刷新。见 `docs/tasks/TASK-home-bootstrap-reliability-20260922.md` 与 `docs/testing/home-bootstrap-reliability-20260922.md`。
|
||||
- 相关记录:BUG-716(`/chart` 白屏 45 秒,另一条链路)、BUG-998
|
||||
- 相关记录:BUG-716(`/chart` 白屏 45 秒,另一条链路)、BUG-998、BUG-1002
|
||||
- 复发自:无
|
||||
- 修复版本:未发布(本分支未推送,不得声称 staging 已部署)
|
||||
|
||||
@@ -13279,3 +13279,19 @@
|
||||
- 相关记录:BUG-997
|
||||
- 复发自:无
|
||||
- 修复版本:本分支 `fix(chat): choose the chart person before the first message`(未推送,未部署)
|
||||
|
||||
## BUG-1002 | 首屏揭幕标记在没有 documentElement 时抛错,外壳注册测试整组失败
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-22
|
||||
- 最近更新:2026-09-22
|
||||
- 影响面:`useHomeShellRegistration` 的揭幕标记;`frontend/tests/session-list-lifecycle.test.tsx`
|
||||
- 用户现象:无单独的用户界面现象。门禁 [run 1445](https://git.copse.top/root/Jyotisha/actions/runs/2848) 在 `6d06fca0` 变红,发布因此停在 `1bc6a954`。随后 [run 1448](https://git.copse.top/root/Jyotisha/actions/runs/2852) 在 `3fed71ab` 同样失败。
|
||||
- 触发条件:外壳测试挂载这个 hook 时 `document` 存在,但 `document.documentElement` 不存在。
|
||||
- 根因:BUG-936 的揭幕标记写在独立 effect 里,只判断了 `document`,然后直接读 `document.documentElement.dataset`。测试环境没有 `documentElement`,effect 抛 `TypeError`,同文件的外壳注册用例整组失败。真实浏览器有 `documentElement`,这条不是那 7 条后来才出现的 CSS 断点 / composer 失败。
|
||||
- 修复:没有 `documentElement` 时直接返回,不写标记,也不抛错。有根节点时仍写 `data-hydrated="1"`。
|
||||
- 验证:`session-list-lifecycle.test.tsx` 里原先抛错的四条(home registration 两种 StrictMode、shell callbacks、401 signed-out)恢复通过;`first-paint-fallback-contract.test.ts` 锁住「没有 documentElement 就返回」。
|
||||
- 防复发:揭幕标记不得在 `documentElement` 缺失时抛错。源码合同要求先判断 `!document.documentElement`。
|
||||
- 相关记录:BUG-936
|
||||
- 复发自:无
|
||||
- 修复版本:本分支,尚未部署
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# 进度 · 首屏揭幕标记不再打断外壳注册(2026-09-22)
|
||||
|
||||
- 基线:`c6d421ed`(`origin/staging`)。门禁 run 1445 红在 `6d06fca0`,部署仍是 `1bc6a954`。
|
||||
- 根因:`useHomeShellRegistration` 在 `document` 存在但没有 `documentElement` 时写 `dataset`,抛 `TypeError`。外壳生命周期四条测试因此失败。
|
||||
- 修复:没有 `documentElement` 就返回。标记赋值那一行还在。
|
||||
- 没有改 CSS 断点、composer、或别的会话后来加的用例。
|
||||
- 验证见同轮测试输出。未跑全量 `npm test` / `next build`。未部署。
|
||||
@@ -82,7 +82,9 @@ export function useHomeShellRegistration(params: HomeShellRegistrationParams) {
|
||||
|
||||
useEffect(() => {
|
||||
// The inline dead-screen script stands down only after the app has revealed.
|
||||
if (!hydrated || typeof document === "undefined") return;
|
||||
// Shell tests mount this hook without a documentElement; missing it must not
|
||||
// throw, or the registration effect never gets to run.
|
||||
if (!hydrated || typeof document === "undefined" || !document.documentElement) return;
|
||||
document.documentElement.dataset.hydrated = "1";
|
||||
}, [hydrated]);
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ test("fallback script is classic ES5 and waits past the bootstrap budgets", () =
|
||||
|
||||
assert.match(layout, /firstPaintFallbackBootScript\(\)/);
|
||||
assert.doesNotMatch(layout, /firstPaintFallbackBootScript\(\)[\s\S]{0,80}type\s*=\s*["']module["']/);
|
||||
assert.match(hook, /!document\.documentElement\) return/);
|
||||
assert.match(hook, /document\.documentElement\.dataset\.hydrated = "1"/);
|
||||
assert.equal(page.includes("dataset.hydrated"), false);
|
||||
assert.match(page, /连接云端服务超时/);
|
||||
|
||||
Reference in New Issue
Block a user