Javascript 使用不可序列化参数的Puppeter exposeFunction

Javascript 使用不可序列化参数的Puppeter exposeFunction,javascript,node.js,puppeteer,Javascript,Node.js,Puppeteer,我正在尝试使用第三方库来执行一些复杂的DOM解析: /** * // Simplified for this example * module.exports.parse = (document) => {return document.title; } */ const { parse } = require('./parse.js'); 当我尝试暴露和评估木偶戏中的功能时: const browser = await puppeteer.launch(); const

我正在尝试使用第三方库来执行一些复杂的DOM解析:

/** 
 *  // Simplified for this example
 *  module.exports.parse = (document) => {return document.title; }
 */

const { parse } = require('./parse.js');
当我尝试暴露和评估木偶戏中的功能时:

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://stackoverflow.com', { waitUntil: ['domcontentloaded'] });
await page.exposeFunction('parse', (document) => {
    return parse(document);
});

await page.evaluate(() => {
    return window.parse(window.document);
});
我得到一个错误:

评估失败:类型错误:在窗口的JSON.stringify()\n处将循环结构转换为JSON。(匿名函数)(木偶师评估脚本:13:22)\n在木偶师评估脚本:3:31处


在文档的示例中,它传递一个字符串(可以序列化)。是否有任何已知的方法可以评估node.js方法,这些方法将
窗口
文档
作为其参数?

下面解释的方法有点不同,因此请谨慎使用

我们可以将脚本带到浏览器,而不是将dom带到节点上下文。这是可能的与网页或浏览功能。同样这样,我们不需要序列化任何循环变量

这是最小的网页包配置

const path = require("path");

module.exports = {
  entry: "./browser/src.js",

  output: {
    path: path.resolve("browser"),
    filename: "dist.js",
    libraryTarget: "global"
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        use: "babel-loader"
      }
    ]
  }
};
我们将把浏览器脚本放在
browser/src.js
文件夹中。然后当我们运行
webpack
时,它将生成
browser/dist.js
,我们可以将其注入浏览器

最后我可以用下面的一个来称呼它

await page.addScriptTag({path: "./browser/dist.js"});
await page.evaluate(fs.readFileSync("./browser/dist.js", 'utf8'));
只要我们不使用任何不可能捆绑的本机二进制文件,它就可以完美地工作

为简单起见,以下是其他文件

// browser/src.js
module.exports.parse = window => {
  return window.location.href;
};

// index.js
const fs = require("fs");
const puppeteer = require("puppeteer");
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.evaluate(fs.readFileSync("./browser/dist.js", 'utf8'));
  const data = await page.evaluate(() => {
    return parse(window);
  });

  console.log({ data });
})();

// The result:
{ data: 'about:blank' }