如何从vercel/pkg打包的.exe中读取或复制资源文件?
从Vercel/pkg打包的exe中提取资源的最优方法
你完全可以不用把文件转成字符串再写入磁盘——pkg在运行时会模拟文件系统,让你直接用Node.js的fs模块访问打包的资源,直接复制即可。以下是两种实用方案:
方案一:直接读取并复制单个资源
pkg会将打包的assets目录映射到运行时的虚拟路径,你可以用原生fs的复制方法直接处理,无需转换格式(尤其适合二进制文件,避免转字符串损坏内容):
const fs = require('fs'); const path = require('path'); // 源路径:对应你打包时的assets文件路径,pkg会自动解析到临时目录的实际文件 const sourceFile = path.join(__dirname, 'assets', 'your-resource.png'); // 目标路径:你要导出到的本地位置,比如当前工作目录 const targetFile = path.join(process.cwd(), 'exported-resource.png'); // 同步复制文件,也可以用fs.copyFile做异步操作 fs.copyFileSync(sourceFile, targetFile);
方案二:批量导出所有资源(带命令行触发)
如果需要一次性导出所有assets下的文件,可以给exe加命令行参数,触发批量导出逻辑。先安装glob包用来匹配文件(npm install glob),然后修改你的脚本:
const fs = require('fs').promises; const path = require('path'); const glob = require('glob'); async function exportAllAssets() { // 匹配所有assets下的文件(排除目录) const assetFiles = glob.sync(path.join(__dirname, 'assets', '**', '*'), { nodir: true }); // 创建导出目录(当前工作目录下的exported-assets文件夹) const exportDir = path.join(process.cwd(), 'exported-assets'); await fs.mkdir(exportDir, { recursive: true }); // 逐个复制文件,保留原目录结构 for (const file of assetFiles) { const relativePath = path.relative(path.join(__dirname, 'assets'), file); const targetPath = path.join(exportDir, relativePath); // 确保目标目录存在 await fs.mkdir(path.dirname(targetPath), { recursive: true }); await fs.copyFile(file, targetPath); } console.log(`所有资源已导出到:${exportDir}`); } // 检测命令行参数,运行exe时加--export-assets就触发导出 if (process.argv.includes('--export-assets')) { exportAllAssets().catch(err => { console.error('导出失败:', err); process.exit(1); }); } else { // 这里放你的应用正常运行逻辑 console.log('启动应用...'); }
重新用pkg打包后,用户只需运行your-app.exe --export-assets,就能把所有资源批量导出到当前目录的exported-assets文件夹中。
关键说明
- pkg在运行时会把打包的资源解压到系统临时目录(比如Windows的
%TEMP%\pkg-cache),但通过__dirname拼接的路径会被pkg自动映射到对应的临时文件,你无需关心具体的临时路径。 - 直接用
fs.copyFile系列方法比转字符串写入高效得多,尤其适合大文件或二进制资源(图片、音频等),避免格式损坏和内存占用过高的问题。
内容的提问来源于stack exchange,提问作者Slbox
相关产品推荐
相关产品推荐

