pnpm 10 跳过 isolated-vm 构建,启动找不到 out/isolated_vm
安装跳过isolated-vm脚本,启动又缺少原生文件;分开检查pnpm10许可、构建工具链及最终镜像产物。
Docker 镜像构建退出成功,安装日志却提示 Ignored build scripts: isolated-vm@5.0.3;容器启动时又报 Cannot find module './out/isolated_vm'。这时要检查原生依赖的构建产物,而不是仅确认 node_modules 中存在包目录。
本文针对使用 pnpm 10 安装依赖、需要 isolated-vm 原生模块的场景。Directus 自定义镜像中也可能遇到这种组合:基于 directus/directus:11.14.1 添加扩展,安装时跳过脚本,运行扩展相关入口时找不到原生文件。它不能概括成所有 Directus 11 升级都会失败,缺少原生文件也可能有其他原因。
安装完成不等于原生模块已经生成
pnpm 10 默认限制依赖的安装脚本执行。原生包需要脚本下载预编译文件或调用工具链编译时,包的 JavaScript 和清单可能已经落盘,所需的 .node 产物仍未生成。
对照三项信息:运行栈指向的实际包版本、对应安装步骤的 ignored build scripts 提示,以及当前包目录内是否有它要加载的原生文件。检查的必须是最终镜像里的依赖,不能用另一个构建阶段或开发机的目录代替。
若没有跳过脚本的证据,继续查看构建日志和打包过程。架构、Node ABI、libc 不匹配,产物没有复制到运行阶段,或者运行的依赖版本不是刚才构建的版本,也可能导致原生模块加载失败。不能仅看到 Cannot find module 就认定审批是唯一原因。
只允许已经核对过的依赖脚本
先核对包版本、脚本内容与来源,再调整项目的构建许可。审批允许依赖执行代码,不能为了省事放开所有直接和间接依赖,也不能把包加入 ignoredBuiltDependencies 后当作修复:后者只是继续阻止脚本,并隐藏相应提示。
pnpm 10.26.0 起可以用 allowBuilds 记录许可。对于已经确认采用 pnpm 10.27.0 的项目,下面是合入现有 pnpm-workspace.yaml 的片段:
allowBuilds:
isolated-vm: true
保留已有工作区成员和其他审批项,不要用这个片段覆盖整份文件。它允许名为 isolated-vm 的包执行脚本,仍应通过锁文件固定并审核实际版本。更早的 pnpm 10 需要按对应版本采用其支持的配置,不能复制一个尚未加入的字段。
pnpm 10.1.0 起也提供交互式 pnpm approve-builds。这适合在受控环境中审查待构建依赖,随后检查并保存审批配置;不能在非交互的镜像构建中假定它会自动选中所需包。不同 pnpm 主版本的配置规则有变化,先固定实际包管理器,再选择方案。
获准执行后,还要有正确的构建环境
审批完成不会补齐编译器。Directus 11.14.1 的正式 Dockerfile 在 builder 阶段安装了 Python 和构建工具,runtime 阶段则从 Node Alpine 镜像重新开始。基于最终运行镜像追加扩展,不能假定上一个阶段的工具链也还在。
把原生依赖构建放在项目已有的受控构建阶段,确认 Node、架构和 libc 与运行环境兼容,并正确交付生成的文件。保留安装步骤的 USER、WORKDIR 和目录所有权要求;不应仅为权限方便把整个应用改成 root 运行。
已有依赖确实因脚本被阻止而缺少产物时,可以在具备许可与工具链的项目目录重建指定包:
pnpm rebuild isolated-vm
这条命令会执行该包的构建脚本。先保存锁文件和审批配置,并在受控构建环境使用;它不是只读检查。继续阅读退出状态和完整构建错误,审批通过不保证预编译文件能下载,也不保证本地编译一定成功。
最后重新生成镜像,用原来的应用和扩展入口检查原生模块是否真正加载。镜像构建退出为零、安装警告消失,都不能单独算恢复。若仍缺文件,核对构建阶段产物与 runtime 复制结果;若错误变成 ABI 或动态库加载失败,则继续处理兼容性。撤回时恢复此前审定的镜像、依赖锁文件和许可配置,不保留一套靠运行容器内手工安装才可用的状态。


