繁体   English   中英

未定义的 Puppeteer 启动器错误结果

[英]Puppeteer launcher error results with undefined

在 windows 上测试我的项目后,我将它部署到基于 Ubuntu 的 VM,这就是 Puppeteer 行为让我感到困惑的地方。 我确实安装了所有必需的依赖项,但我觉得我的错误不一定是由于缺乏依赖项而引起的,更多的是关于配置问题。

Function 签名:

 async initPuppeteerBrowser() { if ( this.puppeteerBrowser === null || (await this.puppeteerBrowser.pages()).length === 0 ) { this.puppeteerBrowser = await launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); } return await this.puppeteerBrowser.newPage(); }

结果是:

err: {
      "type": "TypeError",
      "message": "Cannot read properties of undefined (reading '_launcher')",
      "stack":
          TypeError: Cannot read properties of undefined (reading '_launcher')
              at launch (/root/dev/logoex-server/node_modules/puppeteer/lib/cjs/puppeteer/node/Puppeteer.js:125:21)
              at CorporationsScraper.initPuppeteerBrowser (/root/dev/logoex-server/dist/aid/scraper/corporations.scraper.js:33:66)
              at CorporationsScraper.corporationIterator (/root/dev/logoex-server/dist/aid/scraper/corporations.scraper.js:54:37)
              at processTicksAndRejections (node:internal/process/task_queues:96:5)
    }

我不明白我什至如何开始调查这个问题

我的解决方法是从使用切换:

import { launch } from 'puppeteer';
const browser = await launch(...);
import Puppeteer from 'puppeteer';
const browser = await Puppeteer.launch(...);

像这样使用。

async initPuppeteerBrowser() {
    if (
      this.puppeteerBrowser === null ||
      (await this.puppeteerBrowser.pages()).length === 0
    ) {
      this.puppeteerBrowser = await launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] });
    }

    return this.puppeteerBrowser.newPage();
  }

不确定,如果这对您的情况有帮助 - 我有 Typescript,带有 compilerOptions lib: ["es2020"]并且它抛出了这个错误。 将其更改为lib: ["es2017"]为我解决了这个问题。 我什至不确定,为什么它会像这样影响它。 我猜,当您通过import { fn } from "somewhere"导入类似import { fn } from "somewhere"获得一个函数,但该函数以某种方式从类实例导出时 - 它失去了它的绑定this

否则像这样导入

// Works
import Puppeteer, { Browser, PDFOptions } from "puppeteer";
browser = await Puppeteer.launch({});

// Doesn't work
import { launch, Browser, PDFOptions } from "puppeteer";
browser = await launch({});

我的环境

我正在使用 commonjs 模块格式运行我的 Node.js 应用程序。

  • puppeteer@13.5.1
  • typescript@4.5.4
  • node@14.18.3
  • 我的package.json没有适当地指定"module": true
  • 尽管我在 TypeScript 代码中确实使用了 ES 模块语法,但我设置了"module": "commonjs"以转译为 commonjs。

我的tsconfig.json看起来像这样:

{
  "compilerOptions": {
    "target": "ESNext",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "module": "commonjs",
    "moduleResolution": "Node",
    // ... other inconsequential options ...
  },
}

失败的方法

我使用上面的tsconfig.json在官方 TypeScript playground 上进行了测试,以分析每种不同方法的转换结果。

方法一

来源

import { launch } from 'puppeteer';
launch();

Output

const puppeteer_1 = require("puppeteer");
(0, puppeteer_1.launch)();

方法二

来源

import { default as puppeteer } from 'puppeteer';
puppeteer.launch();

Output

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const puppeteer_1 = __importDefault(require("puppeteer"));
puppeteer_1.default.launch();

方法三

来源

import * as puppeteer from 'puppeteer';
puppeteer.launch();

Output

var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const puppeteer = __importStar(require("puppeteer"));
puppeteer.launch();

工作方式

...最后,我尝试了 TypeScript 的特殊import = require()格式。

来源

import puppeteer = require("puppeteer");
puppeteer.launch();

Output

const puppeteer = require("puppeteer");
puppeteer.launch();

所以这看起来与方法 1 最相似。我不太确定方法 1 用它的0参数执行了什么魔术,但也许它正在擦除this上下文或其他东西,这就是导致模块无法找到其launch属性的原因(它可能通过this.launch引用它)? 只是猜测。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM