如何在Playwright中使用page.setContent渲染React组件?
在Playwright中使用page.setContent渲染React组件失败的解决方法
问题核心原因
你的HTML在浏览器单独运行正常,但Playwright环境下失效,主要是这几个问题导致:
- JSX无法被解析:Playwright默认上下文没有加载Babel解析器,
<script type="text/babel">里的JSX代码无法被执行。 - DOM节点引用错误:
createRoot(window.root)试图获取不存在的window.root属性,正确的根节点是id="root"的div元素。 - ImportMap与JSX配置不匹配:
@jsxImportSource配置不符合规范,缺少JSX编译所需的注解。 - 冗余无效脚本:
<script type="module" src="https://esm.sh/run"></script>无实际作用,可能干扰代码执行。
修复后的完整代码
调整后的HTML代码
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <style> body { margin: 0; overflow: hidden; background-color: #535bf2; } canvas { display: block; height: 1000px; } </style> <script type="importmap"> { "imports": { "react": "https://esm.sh/react@18.2", "react-dom/client": "https://esm.sh/react-dom@18.2/client" } } </script> <title>Document</title> </head> <body> <div id="root"></div> <script type="module"> /** @jsxImportSource react */ import {createRoot} from 'react-dom/client'; function App() { return ( <h1>Hello World!</h1> ); } const rootNode = document.getElementById('root'); createRoot(rootNode).render(<App />); </script> </body> </html>
优化后的Playwright代码
替换硬编码延迟为精准的渲染完成等待,更可靠:
await page.setContent(finalHtml, { waitUntil: "domcontentloaded" }); // 等待React渲染后的目标元素出现,确认渲染完成 await page.waitForSelector('#root h1'); const buffer = await page.screenshot({ omitBackground: true, });
关键修复点说明
- 替换脚本类型并添加JSX注解:把
<script type="text/babel">改为<script type="module">,并添加/** @jsxImportSource react */注释,让浏览器原生支持JSX解析(esm.sh的React包已适配该特性)。 - 修正DOM节点获取逻辑:用
document.getElementById('root')正确获取根容器,避免无效的window.root引用。 - 清理冗余脚本:移除无意义的
https://esm.sh/run脚本,减少网络请求和潜在干扰。 - 用等待选择器替代固定延迟:
page.waitForSelector可以精准等待React渲染完成,比固定sleep更适配不同环境的加载速度。
内容的提问来源于stack exchange,提问作者The Prenx
相关产品推荐
相关产品推荐

