[英]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
。"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();
const puppeteer_1 = require("puppeteer");
(0, puppeteer_1.launch)();
import { default as puppeteer } from 'puppeteer';
puppeteer.launch();
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();
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();
const puppeteer = require("puppeteer");
puppeteer.launch();
所以这看起来与方法 1 最相似。我不太确定方法 1 用它的0
参数执行了什么魔术,但也许它正在擦除this
上下文或其他东西,这就是导致模块无法找到其launch
属性的原因(它可能通过this.launch
引用它)? 只是猜测。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.