FirebaseCloudFunctionsで使用する言語をJavascriptからTypeScriptに乗り換えたい
TypeScriptを使ってみたらいい感じだったので既存のjsプロジェクトも乗り換えたい
公式にちゃんとあった
とりあえずTypeScriptの作業で参考にしたの貼ってく
TypeScriptに乗り換えるからには型の恩恵を受けたいので導入
と思ったけど最新のAppStoreのAPI仕様に対応しているtype定義のライブラリはまだ無いみたい?
これも同じようなライブラリだけど、 こんなissueがnull許容型?というか「型は指定するけどnullも入るかもよ」っていうのは記述の仕方がいくつかあるのかな。
C#だったらそもそも参照型は
string someField = null;
っていうのが成立するけど、TypeScriptでやりたかったら
変数宣言だと
let someField:string|null = null;
で、typeの宣言だと
type someType = {
someField?:string,
someField2:string|null
}
みたいな記述がいけるけど、どれが普通なんだろ
JSON.parseがオブジェクトをanyで返してくれるのはいいんだけど、型のキャストを必須にするメソッドはないだろうか
ライブラリで型定義してるファイルは大体~~.d.tsっていうファイルなんだけど、これはそういうルールなんだろうか
- 型定義ファイル有り
TypeScriptで書かれたパッケージ
JavaScriptで書かれたパッケージだが.d.tsファイルを同梱している- 型定義ファイル有りだが別途インストールが必要
JavaScriptで書かれたパッケージだが、 DefinitelyTypedに登録されている- 型定義ファイル無し
JavaScriptで書かれたパッケージで型定義ファイルが存在しない
理解した
TypeScriptはJavaScriptにコンパイルされるときに型情報は無くなってしまいます。そのままJavaScriptパッケージを利用すると型定義の恩恵を得ることができません。しかし型定義ファイルを同梱することにより補完やコードチェックとして利用することができます。
javascriptでCloudFunctionsを書いてたときに補完が聞いてたのはFirebase側が.d.tsファイルを用意してくれてたからか
よりも の方が最新の定義に近いのでこっちを使う
CloudFunctionsの環境変数について、1年前は
firebase functions:config
を使用するよう書いてあったけど、最新のドキュメントだと変わってるみたい。(configも一応今も使える)
functionsフォルダに.envファイルを追加してその中に記述すればOK
dotenvというパッケージを使用するのでその導入だけしておく
npm install dotenv --save
envファイルの中身
HOGE=hogeValue
アクセス方法
require('dotenv').config() //ファイル冒頭とかでやっておく
console(process.env.HOGE);
普通の環境変数だったら.envファイルでいいけど、secretとかpasswordは隠したい。
Secret Manager では、6 個のアクティブなシークレット バージョンを無料で使用できます。つまり、1 つの Firebase プロジェクトで 1 か月あたり 6 個のシークレットを無料で使用できます。
7個以上使うと課金対象になっちゃうらしい
firebase functions:secrets:set SECRET_NAME
で設定できるはずだけど、エラー出た。
Error: functions:secrets:set is not a Firebase command
バージョンが古いとか?
ファイルベースの構成には、次のバージョン以上の Firebase CLI と Cloud Functions for Firebase が必要です。
firebase-functions v3.18.0
firebase-tools v 10.2.0
バージョンの確認する
% firebase --version
9.10.0
やっぱ古い。どうやってアップデートするの
nodebrew使って管理してたので↓
Firebaseをアップデートしたのでsecretを設定しようとしたらエラー
Error: HTTP Error: 403, Secret Manager API has not been used in project *******
before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/secretmanager.googleapis.com/overview?project=******* then retry.
If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
firebase functions:secrets:set SECRET_NAME
も無事動いた。↑のコマンドを打つと値の入力を促す表示が出てくる。
値を確認したいときは
firebase functions:secrets:access SECRET_NAME
全く意識してなかったが、どうやらJavaScriptにはモジュールシステムとして、CommonJSとESMというものがあるらしい。
ふわっとした理解だけど、JavaScriptは自由な言語なのでなんでもできるが故にライブラリ(もといパッケージ?機能群)同士を活用するためにはライブラリ間の共通の最低限のルールを決めておく必要がある。それがモジュールシステム。みたいな
それでFirebaseCloudFunctionではデフォルトでCommonJSが使用されているが、依存するライブラリによってはESMに移行しないとTypeScriptからJavaScriptへのトランスパイルに失敗するらしい。
自分のプロジェクトTでFirebaseCloudFunction(TypeScript)を使用したときは、依存するライブラリの数がそんなに多くなかったのと、どれもCommonJSで正常に動くライブラリだったので気にせず実装できていた。
ただ、別のプロジェクトRでは、slackのライブラリおうとしたタイミングで
node_modules/@slack/socket-mode/dist/SocketModeClient.d.ts:2:8 - error TS1259: Module '"functions/node_modules/@types/ws/index"' can only be default-imported using the 'esModuleInterop' flag
2 import WebSocket from 'ws';
~~~~~~~~~
node_modules/@types/ws/index.d.ts:353:1
353 export = WebSocket;
~~~~~~~~~~~~~~~~~~~
This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.
Found 1 error in node_modules/@slack/socket-mode/dist/SocketModeClient.d.ts:2
というエラーが出た。
これはslackライブラリがesModuleで動く想定なのにCommonJSから呼び出そうとしててデフォルトインポート(import WebSocket from 'ws';の部分)に失敗してる的な。
それを解決するにはcompilerOptionで"esModuleInterop": true を追記してあげればいいんだけど、
なんか他のエラー出たので寝るところですおやすみなさい