copy-pdf-worker.mjs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/env node
  2. /**
  3. * 把 pdf.js 的 worker 复制到 public/。
  4. *
  5. * ## 为什么要这一步
  6. *
  7. * pdf.js 需要 worker 文件从**同源**加载(`/pdf.worker.js`),
  8. * 但它只有新版 `.min.mjs`,而开发服务器对 `public/` 下的 `.mjs` 不解析,
  9. * 因此复制成 `.js`。
  10. *
  11. * ## 为什么不进 git
  12. *
  13. * 1.3 MB 的构建产物,随 pdfjs 版本变化,没理由占仓库空间。
  14. * 由 `postinstall` 自动生成,克隆后 `npm install` 即得。
  15. */
  16. import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
  17. import { dirname, resolve } from 'node:path';
  18. import { fileURLToPath } from 'node:url';
  19. const here = dirname(fileURLToPath(import.meta.url));
  20. const root = resolve(here, '..');
  21. const src = resolve(root, 'node_modules/pdfjs-dist/build/pdf.worker.min.mjs');
  22. const dest = resolve(root, 'public/pdf.worker.js');
  23. if (!existsSync(src)) {
  24. // 未安装 pdfjs-dist(如只装了部分依赖)时静默跳过,不阻塞 npm install
  25. console.log('[copy-pdf-worker] 跳过:未找到 pdfjs-dist');
  26. process.exit(0);
  27. }
  28. mkdirSync(dirname(dest), { recursive: true });
  29. copyFileSync(src, dest);
  30. /*
  31. * 🔴 复制后**必须校验**(2026-11-15 真机事故后新增)
  32. *
  33. * ## 为什么
  34. *
  35. * 这个坑已经踩了**两次**:
  36. * ① 2026-11-13:降级 pdfjs 后没重跑本脚本 → 线上是 6.4 的 worker
  37. * ② 2026-11-15:同样的事又从真机 App 上冒出来 ——
  38. * 主包 4.10.38,而 APK 里的 worker 是旧版 6.4.299(1,264,342 字节,
  39. * 正确值应为 1,375,838),pdfjs 的 fake-worker fallback 失败后
  40. * `getDocument().promise` **既不 resolve 也不 reject**,
  41. * 用户看到的是「一直转圈,永远加载不出来」。
  42. *
  43. * ## 本脚本只在 postinstall 跑
  44. *
  45. * 而 `npm run build` / `npx cap sync` 不会重跑它,只是把 public/ 下的
  46. * **旧文件**一路拷进 APK。所以「文件存在但内容过期」是常态而非意外。
  47. *
  48. * 现在:复制完立刻比对大小,不一致就报错退出,把问题挡在构建期,
  49. * 而不是等用户装完 App 发现打不开 PDF。
  50. */
  51. const srcSize = statSync(src).size;
  52. const destSize = statSync(dest).size;
  53. if (srcSize !== destSize) {
  54. console.error(
  55. `[copy-pdf-worker] 🔴 复制结果不一致:src=${srcSize} dest=${destSize}\n` +
  56. ` 这会导致 pdfjs 主包与 worker 版本不匹配,PDF 永远转圈。`,
  57. );
  58. process.exit(1);
  59. }
  60. console.log(`[copy-pdf-worker] 已生成 public/pdf.worker.js(${destSize} 字节,已校验)`);
  61. /*
  62. * 同时生成 pdfjs 版本常量(2026-11-13)。
  63. *
  64. * ## 为什么需要
  65. *
  66. * `pdf-preview.ts` 用版本号做 worker 的缓存键。之前是手写常量,
  67. * pdfjs 从 6.4 降到 4.10 时忘了改 → 浏览器命中缓存的旧 worker
  68. * → 主包与 worker 版本不匹配 → PDF 永远卡在「正在加载」。
  69. *
  70. * 现在由本脚本把 `node_modules/pdfjs-dist/package.json` 的 version 写进源码,
  71. * 依赖一变缓存键就变,不可能再忘。
  72. */
  73. const versionFile = resolve(root, 'src/app/components/preview/pdf-preview/pdfjs-version.generated.ts');
  74. const pkgPath = resolve(root, 'node_modules/pdfjs-dist/package.json');
  75. if (existsSync(pkgPath)) {
  76. const { version } = JSON.parse(readFileSync(pkgPath, 'utf8'));
  77. writeFileSync(
  78. versionFile,
  79. `/* 由 scripts/copy-pdf-worker.mjs 自动生成,请勿手改。 */\n` +
  80. `export const PDFJS_VERSION = '${version}';\n`,
  81. 'utf8',
  82. );
  83. console.log(`[copy-pdf-worker] 已生成 pdfjs 版本常量:${version}`);
  84. }