如何将含Puppeteer的TypeScript Node.js项目转为单EXE?
解决带Puppeteer依赖的TypeScript项目打包成单EXE的问题
问题背景
我先将TypeScript项目编译为JavaScript,再尝试转为EXE。试过nexe、pkg、nwjs,但因使用带Chromium依赖的Puppeteer,遇到了以下问题:
pkg打包日志
PS C:\Users\mohammed mehdi\OneDrive\Desktop\myna\Automatic-Scraper\nodepuppeteer\dist> pkg .\main.js -t node18 > pkg@5.8.1 > Fetching base Node.js binaries to PKG_CACHE_PATH fetched-v18.5.0-win-x64 [====================] 100% > Warning Cannot include directory %1 into executable. The directory must be distributed with executable as %2. %1: node_modules\puppeteer\.local-chromium %2: path-to-executable/puppeteer PS C:\Users\mohammed mehdi\OneDrive\Desktop\myna\Automatic-Scraper\nodepuppeteer\dist> .\main-win.exe pkg/prelude/bootstrap.js:1872 throw error; ^ Error: Cannot find module 'C:\snapshot\dist\node_modules\openai\_shims\auto\runtime-node.js' 1) If you want to compile the package/file into executable, please pay attention to compilation warnings and specify a literal in 'require' call. 2) If you don't want to compile the package/file into executable and want to 'require' it from filesystem (likely plugin), specify an absolute path in 'require' call using process.cwd() or process.execPath. at createEsmNotFoundErr (node:internal/modules/cjs/loader:960:15) at finalizeEsmResolution (node:internal/modules/cjs/loader:953:15) at resolveExports (node:internal/modules/cjs/loader:482:14) at Function.Module._findPath (node:internal/modules/cjs/loader:522:31) at Function.Module._resolveFilename (node:internal/modules/cjs/loader:919:27) at Function._resolveFilename (pkg/prelude/bootstrap.js:1951:46) at Function.Module._load (node:internal/modules/cjs/loader:778:27) at Module.require (node:internal/modules/cjs/loader:1005:19) at Module.require (pkg/prelude/bootstrap.js:1851:31) at require (node:internal/modules/cjs/helpers:102:18) { code: 'MODULE_NOT_FOUND', path: 'C:\\snapshot\\dist\\node_modules\\openai\\package.json', pkg: true }
nexe打包日志
nexe main.js --build i nexe 4.0.0-rc.4 √ Node source extracted to: C:\Users\mohammed mehdi\.nexe\16.15.0 √ Compiling Node with arguments: nosign,release,x64 √ Finished in 78.68s Error: vcbuild.bat nosign release x64 exited with code: 1 See nexe -h for usage..
解决方法
针对pkg的问题处理
1. Puppeteer Chromium依赖无法打包的问题
pkg无法将.local-chromium目录直接打包进EXE,需手动处理:
- 复制
node_modules/puppeteer/.local-chromium目录到EXE所在的同目录下,并重命名为puppeteer(匹配警告提示的路径要求)。 - 在代码中动态指定Chromium的执行路径,避免硬编码:
const puppeteer = require('puppeteer'); const path = require('path'); // 获取EXE所在目录 const exeDirectory = path.dirname(process.execPath); // 替换为你实际的Chromium版本目录名(比如win64-118.0.5993.70) const chromiumPath = path.join(exeDirectory, 'puppeteer', 'win64-xxxxxx', 'chrome-win', 'chrome.exe'); const browser = await puppeteer.launch({ executablePath: chromiumPath });
2. openai模块找不到的问题
这是pkg的快照机制无法识别openai的动态导入导致的,解决步骤:
- 在项目的
package.json中添加pkg配置,指定需要包含的资源文件:
{ "pkg": { "assets": [ "node_modules/openai/_shims/**/*" ] } }
- 重新执行pkg打包命令:
pkg .\main.js -t node18
针对nexe的问题处理
nexe的错误是因为编译Node.js源码时缺少必要的编译工具,解决步骤:
- 安装Visual Studio Build Tools,确保勾选「Desktop development with C++」组件,包含MSVC编译器、Windows SDK等核心工具。
- 以管理员身份打开命令提示符,运行
npm install -g windows-build-tools(若系统未安装Python 3.8+,需先安装并添加到系统PATH)。 - 避免使用
--build参数(除非你需要自定义编译Node.js),改用预编译的Node.js版本打包:
nexe main.js -t windows-x64-18.5.0
通用优化建议
- 改用
puppeteer-core替代puppeteer:puppeteer-core不会自动下载Chromium,需要手动指定本地已安装的Chrome/Chromium路径,能大幅降低打包复杂度和体积。 - 编写打包后脚本:可以写一个简单的批处理或Node.js脚本,在pkg/nexe打包完成后,自动将Chromium目录复制到EXE所在目录,减少手动操作。
内容的提问来源于stack exchange,提问作者Mohammed Mehdi
相关产品推荐
相关产品推荐

