2026/9/23 · 工程实践
安装器工程化踩坑:原生模块 ABI 必须和运行 Node 严格匹配
做桌面安装器时,我们踩过一个反复出现的坑:better-sqlite3 在启动时报
was compiled against a different Node.js version (NODE_MODULE_VERSION 127),而目标 Node 是 24(ABI 137)。
根因
原生模块是按 Node ABI 分文件预编译的。装错版本就加载失败。更隐蔽的是:require('better-sqlite3') 只加载 JS,不构造 Database 就不会加载 .node 文件——所以冒烟测试用 require 是假阳性。
修复铁律
- 主命令用目标 Node 绝对路径,杜绝误用工具链里的另一个 Node。
- 子进程也要净化 PATH:npm/node-gyp 的子进程会从 PATH 第一个 node 解析,必须把目标 Node 目录插到最前。
- 严格冒烟:直接
require('<绝对路径>/better_sqlite3.node')加载原生文件,确认不再抛 ABI 错。
这套”PATH 净化 + 严格冒烟 + DETACHED 启动”组合拳,让真机安装从”偶尔崩”变成”稳定 HTTP 200”。