Skip to content

2026-05-09 学习日志

知识点

  • [DRMS] 报告导出 PDF 的三种方案对比(pdfmake / html2canvas / puppeteer)→ 详见 /topics/projects/drms/
  • [puppeteer] 服务端生成 PDF 的四个关键设计:URL 打印模式、业务就绪信号、浏览器单例 + 并发队列、cookie 透传
  • [Next.js] pages/api/ 下静态路径会优先于 [...slug].ts catch-all,新加 API 不需要改 catch-all
  • [Next.js] next/dynamic 会静默吞掉 loader Promise 的 reject,白屏排查必须主动挂 .catch 打印 → 详见 /topics/frontend/next/
  • [DRMS] 合并分支后前端白屏的真凶:src/types/ 聚合导出在 merge 时丢失,UserRole 变 undefined 引发模块顶层 TypeError → 详见 /topics/projects/drms/

问题与解决

  • 问题: pdfmake 方案大报告卡 10s+,html2canvas 无法处理自管理的折叠 UI,两者都有硬伤

  • 解决方向: 切到服务端 puppeteer,真 PDF(文本层、分页、CSS 渲染一致);但要解决并发 OOM 问题

  • 问题: 本地 worktree 启动 npm run devfeatures.toSorted is not a function

  • 原因: Node 18 不支持 Array.prototype.toSorted,Next.js 14+/依赖链在用这个 API

  • 解决: 切到 Node 20+(nvm use 20)后重试

  • 问题: puppeteer 默认每次请求都 launch 会启动新的 Chromium(单实例 300MB~1GB),高并发下直接把 Next.js 主进程 OOM 拖挂

  • 解决: 全局 browserPromise 单例 + MAX_CONCURRENT 信号量队列;browser.on('disconnected') 时重置单例以便下次恢复

  • 问题: feature/merge-tcs2.3.5.0-into-2.3.5.1 分支本地 npm run dev 后页面一直卡在 "页面加载中...",服务端 200,终端只有 SCSS/forwardRef/findDOMNode 一堆 warning,Console 里也没有红色 fatal error,清 ServiceWorker、无痕窗口、锁 tea-component 版本、补 sassOptions 都无效

  • 定位手法: 给 pages/[[...slug]].tsx 里两个 dynamic(() => import(...)) 的 loader 挂 .catch((err) => { console.error('[xxx]', err); throw err }),刷新后 Console 立刻打印 TypeError: Cannot read properties of undefined (reading 'Admin') at ClusterConfigTable/index.tsx:17:31

  • 真因: merge 时 src/types/ 目录下 7 个子类型文件(report/setting/task/region/power/path/host.ts)连同 index.tsexport * from './xxx' re-export 一起被误删,导致 import { UserRole } from '@client/types' 拿到 undefined,模块顶层 [UserRole.Admin] 直接抛 TypeError,被 dynamic import 的 Promise 链静默吞掉

  • 修复: 从 release/tce3.10.12 恢复 7 个类型文件;src/types/index.tsexport * from './xxx' 以及 export { UserRole } from '@config/types'

今日总结

上午继续 puppeteer PDF 方案:在主仓库 ~/Documents/tencent/drms-web 旁边用 git worktree add 新拉了一个 drms-web-worktree(分支 puppeteer-test,基于 origin/release/tce3.10.11),在隔离环境里把 puppeteer 方案的骨架搭出来:新增 pages/api/report/export-pdf.ts(浏览器单例 + 并发队列 + cookie 透传 + __REPORT_READY__ 信号)、ReportSubTaskLogItem 支持 ?print=1 默认展开、ReportDetailPage 数据就绪后广播信号,并在下载按钮旁加了「Puppeteer 导出」测试入口。实机验证阶段被 Node 18 的 toSorted 拦住,明天换 Node 20 继续。

下午排查合并分支后的白屏问题,绕了一大圈(缓存、浏览器 SW、tea-component 版本、sassOptions、tea.css 补丁、Node/Chromium 版本)都没命中,最后靠主动给 dynamic import 挂 .catch 打印一步看到 Console 红字,三分钟定位到 src/types/ re-export 丢失。最大教训:Next.js dynamic() 会把模块顶层错误默默吞掉,"Console 没有红字" ≠ "没有 fatal",这类"LoadingPage 无限转"的白屏以后第一件事就该是挂 .catch

持续学习,每天进步 🚀