Google Cloud FunctionsとTypeScriptを使ってとあるSlackボットを作っていたら、正しく依存関係を指定しているはずなのに「File ./dist/index.js that is expected to define function doesn't exist」というエラーが出てうまくデプロイできず、結構ハマったので原因と解決策を。
(あたりまえですが./dist/index.js
のところは個人が設定しているエントリポイントによってかわります)
先に結論。
ここに書いてあることがすべて
構成
├── .gitignore
├── README.md
├── dist
│ └── index.ts
├── package-lock.json
├── package.json
├── src
│ └── index.ts
└── tsconfig.json
src配下にTypeScriptのファイルが配置されていて、それをコンパイルするとdist配下にJSが吐かれるというよくあるかんじの構成です。
package.jsonのmain
にはdist/index.js
が指定されています。
また、.gitignoreにはdistが指定されています。これもTypeScriptのプロジェクトではよくあることかなと思います。
デプロイしようとした
完成したのでデプロイしようとして以下のようなコマンドを実行しました。
tscでコンパイルを行い、2行目のgcloudを使ってCloud Functionsへデプロイを実行しました。
$ npx tsc
$ gcloud functions deploy hoge --runtime nodejs8 --trigger-http --project hoge-proj
すると、「File ./dist/index.js that is expected to define function doesn't exist」というエラーが発生しました。
間違いなくdistの下にindex.jsファイルはあるのにおかしいと思い、いろいろ調べたり悩んだ結果たどり着いたのが上記に貼ったStackOverflowでした。
原因
gcloud functions deploy
を実行すると.gcloudignore
というファイルが自動的に作成されます。
こんなファイルです
# This file specifies files that are *not* uploaded to Google Cloud Platform
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
# $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore
node_modules
# !include:.gitignore
.gitやnode_modulesなど、Cloud Functions側にあげる必要のないファイルを.gitignoreと同じような形式で書いておくことで、無視してくれるようになります。
今回原因となったのは一番最後の行、#!include:.gitignore
これです。
これは.gitignoreの内容を取り込んでくれるものになります(多分)。今回私は.gitignoreにdistを指定していたため、gcloud function deployを実行しても肝心のdist以下がアップロードされずにエラーが出た、というのが原因でした。
解決策
最後の行に!dist
と書き足すとよいです。これだけでdist以下を読んでくれるようになります。ついでにsrcはあげなくていいのでsrc
と書き足しておくといいかもしれません。
まとめ
普通にJS書いてた時はうまくいってたので、油断してたらこんな罠が…と言う感じでした。
FirebaseのFunctionsはfirebase-toolsで初期化するときにTypeScriptを使う選択をすると、自動的にこの辺のファイルとかのテンプレを吐き出してくれるので、困ったことなかったのですが、今回使ったのはGCPの方のFunctionsだったのでハマってしまいました。
調べ方がわるかったのか、なかなか上記StackOverFlowにも辿りつかず、結構苦労しました。
この記事が誰かの役に立つといいなあ。
おわり。