fix(build): 修好 npm install 挂掉 (postinstall 只重建 better-sqlite3)

`npm install` 在 postinstall 阶段直接失败退出:

    node-hid 编译报错 -> node-addon-api/napi.h:2477 expected unqualified-id

根因不是 node-hid 坏了, 是重建范围错了:

1. postinstall 跑的是 `electron-builder install-app-deps`, 它重建**所有**原生模块;
2. 它给子进程传 `npm_config_build_from_source=false` —— 但这是**字符串** "false",
   npm 11 对未知的 npm_config_* 不做布尔转换;
3. pkg-prebuilds-verify 用 `if (process.env.npm_config_build_from_source)` 判断,
   字符串 "false" 在 JS 里是真值 -> 直接 exit 1 -> 强制源码编译;
4. node-hid 于是去编译它自带的 node-addon-api 3.2.1, 和现代 Node 头文件不兼容 -> 编译失败
   -> 整个 npm install 挂掉。

而 node-hid 根本不需要编译 —— 它自带 N-API 预编译产物, 任何 ABI 都能加载。

真正需要按 Electron ABI 重编的只有 better-sqlite3 (非 N-API, 绑死 V8/ABI,
Electron 32 -> node ABI 128); 其余 (@lydell/node-pty / node-hid /
@serialport/bindings-cpp / usb) 都是 N-API 预编译, 重编既没必要又有害。

改动:

- postinstall 换成 `node scripts/postinstall.js`:
  只重建 better-sqlite3, 装完**在 Electron 下真跑一次读写校验**, 失败就 exit 1
  —— 把"启动即崩"提前到 install 阶段暴露
- package.json 加 `allowScripts` 白名单 (npm 11 新机制, 目前只提醒不拦截,
  但迟早会拦; 顺便让 npm install 输出干净)
- AGENTS.md 坑 #3 改写成新规矩 + 完整根因链
- docs/windows-compat.md / docs/remote-terminal-forward-usb.md 里过时的
  "postinstall 走 install-app-deps" 表述一并纠正

验证:

- npm run build            ✅
- npm run typecheck        ✅ node + web
- npm run selftest         ✅ 64 通过 / 0 失败
- npm run selftest:sync    ✅ 全部通过
- npm run package:linux    ✅ 新 deb
- npm run selftest:package ✅ 4/4 (从 app.asar 真实 spawn pty)
This commit is contained in:
2026-10-21 09:32:32 +08:00
parent 4fc86edd4e
commit d854c95ee6
5 changed files with 186 additions and 4 deletions
+1 -1
View File
@@ -550,7 +550,7 @@ CREATE INDEX idx_audit_ts ON audit_log(ts DESC);
|---|---|
| #1 `chat-client` 必带 `'error'` 监听 | 新增帧引入不影响;已有 on('error') 已稳 |
| #2 drag-drop file path | 不涉及 |
| #3 native rebuild | `@lydell/node-pty`、`usb`、`node-hid`、`serialport` 都是 native,必须走现有 `postinstall` 的 `electron-builder install-app-deps`;CI 加 `npm rebuild --runtime=electron` 兜底 |
| #3 native rebuild | `@lydell/node-pty`、`usb`、`node-hid`、`serialport` 都是 N-API 预编译,**不需要**按 Electron 重编;只有 `better-sqlite3`(非 N-API)要编,由 `postinstall` 的 `scripts/postinstall.js` 单独重建并在 Electron 下自校验。**别用 `electron-builder install-app-deps`**(会把 N-API 模块也拖进源码编译,node-hid 编译失败,根因见 AGENTS.md 坑 #3)。CI 兜底直接 `npm ci`(会触发 postinstall → `scripts/postinstall.js`),或手动 `node scripts/postinstall.js` |
| #4 dist-Electron 路径 | 不动 |
| #5 nsis oneClick false | 不动 |
| #6 dragenter/dragleave 深度计数 | 不涉及 |