Nuxt.jsからPuppeteerが実行できない TypeError: Cannot read property 'on' of undefined

Nuxt.jsからPuppeteerが実行できない TypeError: Cannot read property 'on' of undefined:


現象

単体のCLIから起動すると成功するコードを、NuxtのserverMiddlewareとしてリクエスト経由で起動するとpage.gotoが動かない。


実行環境

  • Windows7
  • Node.js 11.0.0 (に上げたが変わらず)
  • Puppeteer 1.9.0 (および@nextも同様)
  • Nuxt.js 2.2.0


エラー出力

TypeError: Cannot read property 'on' of undefined 
    at Function.addEventListener (~\node_modules\puppeteer\lib\helper.js:165:13) 
    at new NavigatorWatcher (~\node_modules\puppeteer\lib\FrameManager.js:1146:14) 
    at FrameManager.navigateFrame (~\node_modules\puppeteer\lib\FrameManager.js:75:21) 
    at Frame.goto (~\node_modules\puppeteer\lib\FrameManager.js:404:37) 
    at Frame.<anonymous> (~\node_modules\puppeteer\lib\helper.js:145:23) 
    at Page.goto (~\node_modules\puppeteer\lib\Page.js:579:49) 
    at Page.<anonymous> (~\node_modules\puppeteer\lib\helper.js:145:23) 
(中略: 呼び出し元スクリプト) 
    at process.internalTickCallback (internal/process/next_tick.js:77:7) 


エラー箇所の原因

puppeteer\lib\Connection.js



/** 
   * @param {!CDPSession} session 
   * @return {!Connection} 
   */ 
  static fromSession(session) { 
    let connection = session._connection; 
    // TODO(lushnikov): move to flatten protocol to avoid this. 
    while (connection instanceof CDPSession) 
      connection = connection._connection; 
    return connection; 
  } 
このループ文が、Nuxt経由の場合は、connectionがConnectionのインスタンスにも関わらず条件がtrueとなり掘り続けて、undefinedまで潜って終わるため。

console.logで見るとConnectionなのにinstanceof CDPSessionが通る理由はprototypeに明るくないのでよくわからない…

コードの意味を汲み取れないが、潜り続ける問題を場当たり的に回避したコードを書くと、Nuxt経由でもうまく動いた。

/** 
   * @param {!CDPSession} session 
   * @return {!Connection} 
   */ 
  static fromSession(session) { 
    let connection = session._connection; 
    // TODO(lushnikov): move to flatten protocol to avoid this. 
    while (connection instanceof CDPSession) { 
      if (connection._connection) { 
        connection = connection._connection; 
      } else { 
        break; 
      } 
    } 
    return connection; 
  } 
これで少なくとも返される値はundefinedではなくなる。


でもこれじゃnode_modulesのコードをいじるのでデプロイできないんですよね。


コード例

api.js(NuxtでserverMiddlewareとして動かすスクリプト)
module.exports = async (req, res, next) => { 
   const puppeteer = require('puppeteer') 
   const browser = await puppeteer.launch({ headless: true, }) 
   const page = await browser.newPage() 
   await page.goto('https://www.google.com/') 
} 
nuxt.config.js
const serveStatic = require('serve-static') 
 
module.exports = { 
    serverMiddleware: [{ 
        path: '/api', handler: '~/api.js' 
    },] 
} 
nuxt で http://localhost:3000 に立てhttp://localhost:3000/apiにアクセスすると、api.jsが実行される。


調査

エラー的に似てそうなのはこれなのだが関係ないと考えている。

ただ、Nuxtが裏でどう取りまとめているのかを理解していないのでなにか無理解が原因の可能性もあるのではと思っている。

zero configurationで動くのは本当にすごい1がエラーが出たときにこまることを痛感。


どうする?

expressとpuppeteerの連携はいくつか見かけたので、Nuxtからexpressに乗り換えるかserverMiddlewareをexpressにしてそこからpuppeteer起動でなんとかならないかと考えている。

しかしすごく遠回りなのでモチベーションがまったく出ない。



  1. serverMiddlewareを使わなければnuxt.config.jsも不要 


コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)