使用Playwright调用reportWebVitals获取Web Vitals指标报错:_reportWebVitals未定义
解决Playwright调用reportWebVitals时的ReferenceError问题
问题原因
Playwright的page.evaluate()代码运行在浏览器的JavaScript沙箱环境中,你在测试代码里导入的reportWebVitals属于Node.js环境的模块,浏览器环境根本无法识别这个函数;同时你定义的getVitals回调也是Node环境的变量,浏览器同样访问不到,所以会触发ReferenceError。
解决方案
方案1:直接在浏览器环境中加载web-vitals并收集指标
不需要依赖本地的reportWebVitals模块,直接在evaluate中通过CDN加载web-vitals,同时通过console.log将指标传递回Node环境:
test.only('Performance Checks using web-vitals library', async ({ browser }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(HOME_PAGE_URL, { waitUntil: 'networkidle' }); // 存储收集到的性能指标 const collectedVitals = []; // 在浏览器环境中加载web-vitals并注册收集逻辑 await page.evaluate(async () => { // 从CDN加载web-vitals ES模块 const { getCLS, getFID, getFCP, getLCP, getTTFB } = await import('https://unpkg.com/web-vitals@3/dist/web-vitals.esm.js'); // 定义回调:将指标序列化为JSON后打印,供Node环境捕获 const sendMetric = (metric) => { console.log(JSON.stringify({ type: 'WEB_VITAL', data: metric })); }; // 注册所有指标的收集 getCLS(sendMetric); getFID(sendMetric); getFCP(sendMetric); getLCP(sendMetric); getTTFB(sendMetric); }); // 监听浏览器的console输出,提取指标数据 page.on('console', (msg) => { if (msg.type() === 'log') { const logText = msg.text(); try { const parsedData = JSON.parse(logText); if (parsedData.type === 'WEB_VITAL') { collectedVitals.push(parsedData.data); } } catch (err) { // 忽略非指标相关的日志 } } }); // 等待足够时间确保所有指标收集完成(可根据页面实际情况调整) await page.waitForTimeout(3000); console.log('最终收集到的Web Vitals:', collectedVitals); });
方案2:注入自定义的reportWebVitals函数到浏览器
如果你想复用本地的reportWebVitals逻辑,可以将函数代码转换为字符串注入到浏览器环境:
// 把reportWebVitals转换为可注入的代码字符串(替换Node式import为CDN加载) const reportWebVitalsInjectCode = ` function reportWebVitals(onPerfEntry) { if (onPerfEntry && typeof onPerfEntry === 'function') { import('https://unpkg.com/web-vitals@3/dist/web-vitals.esm.js').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { getCLS(onPerfEntry); getFID(onPerfEntry); getFCP(onPerfEntry); getLCP(onPerfEntry); getTTFB(onPerfEntry); }); } } `; test.only('Performance Checks using web-vitals library', async ({ browser }) => { const context = await browser.newContext(); const page = await context.newPage(); // 将自定义函数注入到浏览器全局环境 await page.addScriptTag({ content: reportWebVitalsInjectCode }); await page.goto(HOME_PAGE_URL, { waitUntil: 'networkidle' }); const collectedVitals = []; // 在浏览器环境中调用注入的reportWebVitals await page.evaluate(() => { const sendMetric = (metric) => { console.log(JSON.stringify({ type: 'WEB_VITAL', data: metric })); }; reportWebVitals(sendMetric); }); // 同样监听console提取指标 page.on('console', (msg) => { if (msg.type() === 'log') { const logText = msg.text(); try { const parsedData = JSON.parse(logText); if (parsedData.type === 'WEB_VITAL') { collectedVitals.push(parsedData.data); } } catch (err) {} } }); await page.waitForTimeout(3000); console.log('最终收集到的Web Vitals:', collectedVitals); });
关键注意点
page.evaluate()的代码完全独立于Node.js环境,不能直接引用外部变量/函数,必须通过序列化数据(如JSON)的方式传递信息。- 浏览器环境无法加载Node.js的本地模块,因此需要通过CDN加载web-vitals。
内容的提问来源于stack exchange,提问作者KnightCrawler
相关产品推荐
相关产品推荐

