🐞 Electron + Puppeteer 打包后报错:Could not find Chrome?一文彻底解决!

918 阅读3分钟

在使用 Electron + Puppeteer 开发桌面应用时,我们常常会用 electron-builder 将项目打包成 exe 文件。然而,很多人在打包后运行应用时遇到了如下报错:

❌ Could not find Chrome (ver. 115.0.5790.98).
This can occur if either

  1. you did not perform an installation before running the script (e.g. npm install) or
  2. your cache path is incorrectly configured (which is: C:\Users\Administrator.cache\puppeteer)

这个报错看似是 Puppeteer 的问题,实则和打包配置密切相关。本文将带你深入理解这个问题的本质,并提供一套稳定可靠的解决方案,确保你的 Electron 应用打包后能顺利运行 Puppeteer。


📌 问题复现

我们在 Electron 项目中使用 Puppeteer,如下:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

开发环境运行一切正常,但使用 electron-builder 打包后,双击 exe 文件运行,报如下错误:

Error: Could not find Chrome (ver. 115.0.5790.98).
This can occur if either
 1. you did not perform an installation before running the script (e.g. npm install) or
 2. your cache path is incorrectly configured (which is: C:\Users\Administrator\.cache\puppeteer)

🧠 问题分析

Puppeteer 默认在安装时会自动下载 Chromium 浏览器,并缓存到如下路径:

  • Windows: C:\Users\用户名.cache\puppeteer
  • macOS: ~/Library/Caches/puppeteer

但 electron-builder 打包时,并不会自动将这个缓存目录打包进 exe 文件。

也就是说,打包后的应用在运行时无法访问 Puppeteer 所需的 Chromium 浏览器,就会报错 “Could not find Chrome”。

所以,我们的目标是:

✅ 在打包时,将 Chromium 浏览器一并打包进应用中
✅ 在代码中手动指定 Chromium 的路径,避免使用默认缓存路径


✅ 解决方案:使用 puppeteer-core + 自定义 Chromium 路径

推荐使用 puppeteer-core,它是 Puppeteer 的轻量版本,不会自动下载 Chromium,需要你手动指定路径,更适合打包到 Electron 应用中。

步骤 1:卸载 puppeteer,安装 puppeteer-core

npm uninstall puppeteer
npm install puppeteer-core

两者的 API 是一致的,迁移成本非常低。

步骤 2:手动下载 Chromium 浏览器

你可以通过 Puppeteer 提供的命令下载 Chromium:

npx puppeteer browsers install chrome@115.0.5790.98

下载完成后,在缓存目录找到对应的 chrome 可执行文件:

Windows 示例路径:

C:\Users\你的用户名\.cache\puppeteer\chrome\win64-115.0.5790.98\chrome-win64\chrome.exe

将整个 chrome-win64 文件夹复制到你的项目中,例如:

/public/chrome-win64/chrome.exe

步骤 3:在代码中指定 Chromium 路径

使用 puppeteer-core 启动浏览器时,手动指定 executablePath:

const puppeteer = require('puppeteer-core');
const path = require('path');
const isDev = require('electron-is-dev');
// 注意要安装npm install electron-is-dev@1.2.0  ,只有1.2.0版本以下的才支持cmj导入

function getChromiumPath() {
  if (isDev) {
    // 开发环境下路径
    return path.join(__dirname, 'chrome-win64', 'chrome.exe');
  } else {
    // 打包后路径
    return path.join(process.resourcesPath, 'chrome-win64', 'chrome.exe');
  }
}

(async () => {
  const browser = await puppeteer.launch({
    executablePath: getChromiumPath(),
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

步骤 4:配置 electron-builder,打包 Chromium

在 package.json 中添加 build 配置,确保将 Chromium 一并打包:

"build": {
  "extraResources": [
    {
      "from": "public/chrome-win64",
      "to": "chromium"
    }
  ]
}

这样打包后,Chromium 会被复制到 app/resources/chromium 目录下,代码中指定的路径就能正确找到它。


🧪 可选方案:设置环境变量(不推荐)

你也可以设置环境变量 PUPPETEER_EXECUTABLE_PATH 来指定 Chromium 路径:

process.env.PUPPETEER_EXECUTABLE_PATH = path.join(...);

但 puppeteer 本体仍然可能访问默认缓存目录,容易出错。推荐使用 puppeteer-core。


📦 打包测试

完成上述配置后,运行打包命令:

npm run build

electron-builder --win

打包后的 exe 文件运行时就不会再报 “Could not find Chrome” 的错误啦!


📚 总结

Electron + Puppeteer 打包后运行报错 “Could not find Chrome”,是因为 puppeteer 默认使用缓存路径查找 Chromium,但打包时并未将 Chromium 一并打包。

推荐方案是使用 puppeteer-core,并手动指定 Chromium 路径,同时通过 electron-builder 的 extraResources 配置将其打包进去。

✅ puppeteer-core 不会下载 Chromium,适合打包
✅ 自定义 executablePath 更灵活
✅ extraResources 确保 Chromium 被打包进应用


🔗 参考资料