Table of Contents
- 問題発生
- 結論
- 解説
問題発生
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どこ…?」というエラーの様子。
結論
以下の手順で解決できる。
functions
ディレクトリに.puppeteerrc.cjs
ファイルを作成し、以下のような中身にする。
/**
* @type {import('puppeteer').Configuration}
*/
module.exports = {
cacheDirectory: require("path").join(__dirname, ".cache", "puppeteer"),
}
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"
]
}
],
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にします。