React用Puppeteer@21.3.8遇模块找不到错误,求解决方案
问题根源
Puppeteer从v19.x开始重构了内部模块结构,移除了puppeteer-core/internal这类旧路径,但Jest 24.x的模块解析逻辑无法适配新的文件结构,导致测试时抛出模块找不到的错误。
具体修复方法
1. 用Jest Mock绕过真实Puppeteer加载(推荐,不改动依赖版本)
测试PDF生成逻辑时,不需要启动真实浏览器,直接模拟Puppeteer的核心方法即可。在测试文件顶部或Jest全局setup文件中添加以下代码:
jest.mock('puppeteer', () => { // 模拟页面实例 const mockPage = { setContent: jest.fn().mockResolvedValue(), pdf: jest.fn().mockResolvedValue(Buffer.from('mock-pdf-content')), close: jest.fn().mockResolvedValue() }; // 模拟浏览器实例 const mockBrowser = { newPage: jest.fn().mockResolvedValue(mockPage), close: jest.fn().mockResolvedValue() }; return { launch: jest.fn().mockResolvedValue(mockBrowser), executablePath: jest.fn().mockReturnValue('fake-browser-path') }; });
这样测试会直接使用模拟对象,不会去加载真实的Puppeteer内部模块,彻底避开路径问题。
2. 升级Jest到兼容版本(长期解决方案)
Jest 24.x是非常老旧的版本,完全无法适配新版Puppeteer的模块系统。如果项目允许,升级到Jest 29.x(当前稳定版):
npm install jest@latest @testing-library/react@latest --save-dev
升级后需要同步调整测试配置(比如jest.config.js中的语法、测试环境设置),但能彻底解决依赖兼容性问题,同时获得更好的测试性能和特性。
3. 切换使用puppeteer-core并指定浏览器路径
新版Puppeteer默认包含浏览器下载器,而puppeteer-core仅提供核心API,模块结构更稳定。修改项目中的Puppeteer导入代码:
import puppeteer from 'puppeteer-core'; import { executablePath } from 'puppeteer'; // 启动浏览器时指定路径 const browser = await puppeteer.launch({ executablePath: executablePath(), // 其他配置项 });
同时确保安装对应版本的依赖:
npm install puppeteer@21.3.8 puppeteer-core@21.3.8 --save
4. 配置Jest模块映射(临时适配)
如果不想改动代码或依赖,可以通过Jest的moduleNameMapper将旧路径映射到新版Puppeteer的实际文件位置。首先找到node_modules/puppeteer-core中puppeteer-core.js的实际路径(通常是lib/cjs/puppeteer/puppeteer-core.js),然后在jest.config.js中添加:
module.exports = { // 其他配置 moduleNameMapper: { '^puppeteer-core/internal/puppeteer-core.js$': '<rootDir>/node_modules/puppeteer-core/lib/cjs/puppeteer/puppeteer-core.js' } };
注意:这个路径可能随Puppeteer版本变化,需要根据实际安装的包结构调整。
内容的提问来源于stack exchange,提问作者gabrielhult

