【Firebase Cloud Functions + Puppeteer】Puppeteerのv19が動かない問題の対処法 (備忘録)

2023/03/14 00:19公開
2023/06/29 17:28最終更新
Table of Contents
  1. 問題発生
  2. 結論
  3. 解説

問題発生

OGPのサムネイル生成用に、Puppeteerを使ったCloud Functionsの関数をデプロイしようとした。

開発環境(エミュレーター)では正常に動作するのに、なぜかデプロイするとError: could not handle the requestと表示されて動作しなくなる。ログを確認すると、以下のようなエラーが出ていた。

Error: Could not find Chromium (rev. 1095492). This can occur if either
 1. you did not perform an installation before running the script (e.g. `npm install`) or
 2. your cache path is incorrectly configured (which is: /www-data-home/.cache/puppeteer).
For (2), check out our guide on configuring puppeteer at https://pptr.dev/guides/configuration.

どうやら「Chromiumどこ…?」というエラーの様子。

結論

以下の手順で解決できる。

  1. functionsディレクトリに.puppeteerrc.cjsファイルを作成し、以下のような中身にする。
/**
 * @type {import('puppeteer').Configuration}
 */
module.exports = {
  cacheDirectory: require("path").join(__dirname, ".cache", "puppeteer"),
}
  1. firebase.jsonに以下を追記する。(※JSONではコメントの記述はできないため、//以下は削除してください)
"functions": [
  {
    "source": "functions",
    "codebase": "frontend",
    "ignore": [
      "node_modules",
      ".git",
      "firebase-debug.log",
      "firebase-debug.*.log",
      ".cache"  // <= 追記
    ],
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ]
  }
],
  1. package.jsonを以下のように変更する。(※JSONではコメントの記述はできないため、//以下は削除してください)
"scripts": {
  "lint": "eslint --ext .js,.ts .",
  ...
  "postinstall": "node node_modules/puppeteer/install.js" // <= 追記
},
...
"engines": {
  "node": "16"  // <= 16にする。詳細は下記。
}

解説

調べてみると、Puppeteerのv19で以下のような破壊的変更があった模様。

use ~/.cache/puppeteer for browser downloads

(https://github.com/puppeteer/puppeteer/releases/tag/v19.0.0)

ホームディレクトリはCloud Functionsのデプロイの対象にならないため、実際に実行される環境でChromiumが存在せず、エラーとなっているようです。

そのため、Puppeteerのインストール先をプロジェクト内に変更してやります。これが1.です。

この状態でnode_modulesを削除してnpm installし直すと、設定したパスに開発端末のOSに合ったChromiumがインストールされます。ここでfirebase deployしようとすると、「パッケージが大きすぎるためデプロイできません」のようなエラーが発生します。これは巨大なChromium本体がデプロイの対象となっているためで、これはデプロイ不要なので除外してやる必要があります。これが2.です。

あとは、Cloud Functionsではなぜかnpm install時にChromiumが自動的にインストールされないので、postinstallでインストールスクリプトを実行してやります。(3.)

また、Nodeの最新バージョンは18ですが、2023/03/14現在、Node 18用のイメージにPuppeteerの実行に必要なライブラリが含まれていないため、16にします。