Webpack打包的index.html中script本地可运行但Puppeteer中执行失败
Puppeteer加载Webpack打包文件时JS不执行问题解决
问题描述
使用Webpack打包生成了包含<script src="./main.js"></script>引用的index.html文件,期望script标签引入的JS代码可以在Puppeteer浏览器实例中正常执行。但目前仅在本地Chrome浏览器直接打开该HTML文件时,JS代码才会正常运行,通过Puppeteer加载时JS完全不执行。代码逻辑参考官方文档编写,推测问题出在实现方式上。
解决方法
将await page.setContent(buildHTML, { waitUntil: "networkidle0" });修改为await page.goto("file:///Users/user/dev/puppeteer/dist/index.html", { waitUntil: "networkidle0", });
根因说明
使用page.setContent直接注入HTML文本时,页面没有本地文件上下文,无法解析相对路径的main.js资源,改用file协议直接访问本地HTML文件可正确加载相对路径资源。
各文件代码参考
1. ./dist/index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Title</title> </head> <body> <script src="./main.js"></script> <h1>H1</h1> </body> </html>
2. ./src/index.js
import _ from "lodash"; function component() { console.log("component"); const element = document.createElement("div"); element.innerHTML = _.join(["Hello", "webpack"], " "); return element; } // 在本地浏览器打开index.html可正常执行,Puppeteer打开时不执行 document.body.appendChild(component());
3. ./puppeteer.js
var fs = require("fs"); var puppeteer = require("puppeteer"); (async () => { const browser = await puppeteer.launch({ headless: false }); const buildHTML = await fs.readFileSync("./dist/index.html", "utf8"); // 可正常打印文件内容,说明文件路径正确 console.log(buildHTML); const page = await browser.newPage(); try { await page.setContent(buildHTML, { waitUntil: "networkidle0" }); // 永远找不到div元素,因为./src/index.js未执行 await page.waitForSelector("div"); await page.screenshot({ path: `./rendered-img.png`, fullPage: true, }); } catch (err) { console.error(err); throw new Error("page.setContent/waitForSelector执行超时。"); } await browser.close(); })();
4. ./package.json
{ "name": "puppeteer", "version": "1.0.0", "description": "", "private": true, "scripts": { "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "lodash": "^4.17.21", "puppeteer": "^10.4.0" }, "devDependencies": { "webpack": "^5.56.0", "webpack-cli": "^4.8.0" } }
5. ./webpack-config.js
module.exports = { entry: "./src/index.js", output: { filename: "main.js", path: path.resolve(__dirname, "dist"), }, };
内容的提问来源于stack exchange,提问作者saferugdev
相关产品推荐
相关产品推荐

