如何使用pkg打包并执行二进制资源?遇ENOENT错误求解决方案
解决pkg打包后无法执行虚拟文件系统中二进制文件的问题
问题回顾
使用pkg打包Node.js应用后,通过child_process执行打包在虚拟文件系统中的argon2二进制文件时,出现错误:
Error: spawn /snapshot/test-cli/deps/darwin/arm64/argon2 ENOENT
已通过DEBUG_PKG=1确认二进制文件已被打包,但操作系统无法直接访问pkg的虚拟文件系统(/snapshot路径)中的可执行文件。
可行解决方案
方案一:替换为Node.js原生绑定的argon2包(推荐)
直接使用官方提供的Node.js绑定包argon2替代独立二进制文件,彻底绕开外部调用的问题:
- 安装依赖:
npm install argon2 - 重构代码,使用Node.js API调用argon2功能,示例:
const argon2 = require('argon2'); async function hashPassword(password) { try { const hash = await argon2.hash(password); return hash; } catch (err) { console.error(err); } } - pkg会自动处理该包的原生二进制绑定(
.node文件),运行时无需依赖外部可执行文件,自然避免虚拟文件系统的访问问题。
方案二:使用pkg内置的路径解析机制自动提取临时文件
操作系统的exec系统调用必须访问真实文件系统路径,因此无法完全绕开文件提取,但可以利用pkg的内置机制自动处理,无需手动编写复制逻辑:
- 使用
process.pkg.resolve()方法获取二进制文件在真实文件系统中的临时路径,代码示例:const { spawn } = require('child_process'); const path = require('path'); // 确定argon2二进制文件的路径 const argon2Path = process.pkg ? process.pkg.resolve(path.join(__dirname, 'deps/darwin/arm64/argon2')) : path.join(__dirname, 'deps/darwin/arm64/argon2'); // 执行二进制文件 const child = spawn(argon2Path, ['your-arguments']); // 处理子进程输出 child.stdout.on('data', (data) => { console.log(`输出: ${data}`); }); child.stderr.on('data', (data) => { console.error(`错误: ${data}`); }); - pkg会在应用启动时自动将虚拟文件系统中的二进制文件提取到临时目录,
process.pkg.resolve()返回的是真实路径,操作系统可正常执行;应用退出后,临时文件会被自动清理。
内容的提问来源于stack exchange,提问作者sunknudsen
相关产品推荐
相关产品推荐

