# [BUG]在Chromium版本<122时,Web shell无法启动:ui-sidebar-documentpreview中的eagerly-evaluated pdf.js会中止插件加载 #6362
Replies: 2 comments
|
「eagerly evaluated」的说法与源码吻合:pdf.js 是静态导入进客户端模块的 —— ui-sidebar-documentpreview/src/client/index.ts:37(import { apply as registerPdf } from './pdf/index.ts')→ pdf/runtime.ts:2(import { getDocument, PDFWorker } from 'pdfjs-dist')→ pdf/assets.ts:2(?raw 打包 worker 源码)。没有任何 dynamic import,即模块一被求值,pdf.js 就在加载路径上。 Chromium <122 的具体失败我在本机复现不了(无该版本浏览器);但「按需加载(预览首次打开时再动态 import)」的修法方向与这份静态导入链的现状一致,风险低。(基于 0.1.5-rc.2 源码核对。) |
独立数据点:iOS 16 Safari 真机命中同一条静态求值链真机报错(iOS 16 Safari,DSH 与本文一致: 同一"eager 路径依赖新 API"主题还有一处值得一起看:宿主 HTML 末尾的启动握手内联脚本 桥侧兜底(2.10.12 上线,可作参考):在反向代理注入 HTML 时、于宿主所有脚本之前补齐 |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
你家小肥鱼建议我给你们建议,连反馈本身都是小肥鱼写的,不关我事儿
概述
在任何 JS 引擎缺少
Iterator全局对象(Chromium < 122、Safari < 18.4、Firefox < 131)的浏览器上,Web 界面完全无法启动。外壳中止插件加载并渲染:
抛出异常的这行代码本身并不是本仓库的代码——它来自第三方依赖
pdfjs-dist@6.3.289中一处未加守卫的全局引用。这里要反馈的缺陷在集成层:
dsh-web-approster 一同发布的插件以静态导入方式引入,因此每次 Web 界面启动时都会被求值。
也因此完全无法使用应用。
browserslist,也没有任何受支持浏览器的要求文档),受影响的用户无从得知需要 Chromium ≥ 122。
关于范围需要明确说明:这不是要求修改 pdf.js。pdf.js 有意面向较新的基线
(见 mozilla/pdf.js#16321),对于一个 PDF 渲染器来说这是合理选择。
我们的诉求是:不要让一个可选功能成为整个应用的致命故障。
环境
dsh0.1.5-rc.2,profileweb@deepseek-ai/dsh-client-ui-sidebar-documentpreview0.1.5-rc.2pdfjs-dist6.3.289(声明于packages/client/ui-sidebar-documentpreview/package.json)Mozilla/5.0 (Linux; U; Android 16; zh-cn; PKB110 Build/BP2A.250605.015) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.168 Mobile Safari/537.36 HeyTapBrowser/—— Chromium 115
Mozilla/5.0 (Linux; Android 16; PKB110 Build/BP2A.250605.015; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/121.0.6167.71 MQQBrowser/6.2 TBS/047935 Mobile Safari/53—— Chromium 121
这两个失败的浏览器都是主流 Android 设备的预装或常用浏览器,并非罕见配置。
复现步骤
dsh --profile web),使其可被移动端浏览器访问(例如经 Cloudflare Tunnel)。Iterator全局的浏览器打开 Web 界面。稳定复现;不涉及会话、权限或数据状态。同一部署下的桌面版 Chrome 加载正常。
预期行为
Web 界面正常启动。最差情况下文档/PDF 预览不可用,最好附上明确的"浏览器不受支持"提示。
实际行为
外壳整体中止插件加载并渲染
Failed to load plugins,该设备上应用完全不可用。根因
内置的 pdf.js 在模块导入阶段就被求值,而它开头的语句解引用了一个在旧引擎上不存在的全局对象。
已发布包中的
lib/client.js:3394:上游源码 ——
pdfjs-dist@6.3.289的build/pdf.mjs:797(pdf.worker.mjs与pdf.image_decoders.mjs中文本相同):typeof守卫的是方法,但Iterator.prototype在typeof生效之前就被解引用了。因此在没有
Iterator全局的引擎上,这会在模块求值阶段抛出ReferenceError: Iterator is not defined。它之所以被提前触达,是因为 pdf.js 是该插件的静态顶层导入:
src/client/pdf/runtime.ts:2→import { getDocument, PDFWorker } from 'pdfjs-dist'src/client/pdf/assets.ts:2→import workerSource from 'pdfjs-dist/build/pdf.worker.min.mjs?raw'因此
lib/client.js一被导入,pdf.js 主线程包与以字符串内联的 worker 源码都会立即被求值——这发生在
apply()之前。插件自身无法做特性检测或降级处理,这个抛错从插件内部无法避免。以下事实说明这是随发布默认开启的问题,而非本地改动或第三方改动所致:
(SHA-256
DAC2E99F7952BF1704FA7496CF26D3E26BCF39F53D299DCF7E7D0CA170784290,6,888,390 字节)。packages/bundle/web-app/cordis.patch.yml的默认 roster 中列有ui-sidebar-documentpreview,因此每一次 Web 安装都会加载它。
browserslist,也没有任何浏览器要求文档。建议修复
主要 —— 让 pdf.js 懒加载。 把静态导入改为在
openPdf()/createPdfBinaryDataFactory()内部使用动态
await import('pdfjs-dist')。这符合仓库已有的约定:session-query-sqlite行的openAt: never就是为启动开销而延迟node:sqlite的导入。改为懒加载后,缺少Iterator的引擎会降级为"PDF 预览不可用",而不再是"应用无法启动"。
辅助 —— 在插件内做特性检测。 改为懒加载后,
apply()可检查typeof Iterator === "undefined",据此跳过注册 PDF 文档类型,或通过现有的failure-line.ts机制给出明确提示(该机制本就用于单个文档的失败呈现)。另可考虑:
而不是让整个启动失败。这样可以把任何"基线高于外壳"的依赖都限制在自身范围内。
browserslist,和/或一份受支持浏览器的说明)。外壳已通过webserver/index-inject注入 head 脚本,因此技术上可以加Iteratorpolyfill,但一份正确的 iterator-helpers polyfill 面积大得多,更可能是上述方案的补充而非替代。
影响
任何 Chromium 内核低于 122 的移动端用户,都会看到一个没有任何内容、也没有可操作错误信息的外壳,
且完全无法使用应用。由于桌面版 Chrome 不受影响,该症状很容易被误读为"Web 界面在手机上不好用",
并被误判为网络或配置问题——我们在检查 bundle 之前也正是这样误判的。
All reactions