くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

pnpm workspaceでCloud Functions for Firebaseを扱う

pnpm workspaceでのモノレポ化を進めているけど、
Cloud Functions for Firebaseがうまくデプロイできなかったので、
いろいろ調べてみたときの備忘録(*´ω`*)

package.json"workspace:^"があるとダメっぽい。

ディレクトリ構成

ディレクトリ構成はこんな感じ。
functionsからcommon-tsを参照している形。

packages/
  common-ts/
  functions/
    lib/
      index.js
    src/
      index.ts
    package.json
    tsconfig.json
package.json
pnpm-workspace.yaml

発生したエラー

firebase deployを実行してみるとこんな感じのエラーが。。

$ firebase deploy --only functions
Build failed: npm ERR! code EUNSUPPORTEDPROTOCOL
npm ERR! Unsupported URL Type "workspace:": workspace:^

npm ERR! A complete log of this run can be found in: /www-data-home/.npm/_logs/2023-12-16T04_48_38_227Z-debug-0.log; Error ID: b0ba1f57
Build failed: npm ERR! code EUNSUPPORTEDPROTOCOL
npm ERR! Unsupported URL Type "workspace:": workspace:^

functions/package.jsonのこの部分がいけないらしい。。

{
  "devDependencies": {
    "@myapp/commons-ts": "workspace:^",
  }
}

やったこと

firebaseに関係ないところでビルドし、
functions/lib/package.jsonを配置することで対応した。

firebase.jsonの変更

predeployをせず、直接packages/functions/libを見るように変更

  {
    "functions": {
-     "source": "packages/functions",
-     "predeploy": "npm --prefix \"$RESOURCE_DIR\" run build"
+     "source": "packages/functions/lib"
    },
  }

functions/package.jsonの変更

ビルドしたあとに、"workspace:"の行を除いたpackage.json
lib/配下に配置するように変更。

package.jsonの場所が変わるので、mainのパスも変更する。

  {
    "scripts": {
-     "build": "rm -rf lib && tsc --project tsconfig.build.json"
+     "build": "rm -rf lib && tsc --project tsconfig.build.json && pnpm gen:json",
+     "gen:json": "cat package.json | sed '/workspace:/d' > lib/package.json"
    },
-   "main": "lib/index.js",
+   "main": "index.js",
    "devDependencies": {
      "@myapp/commons-ts": "workspace:^",
    }
  }

jsonをパースして最小限のjsonを吐き出すのがスマートだけど、
sedだけでも十分なので簡易的で低コストな対応にした。

ビルド&デプロイ

あとは、ビルドしてからデプロイすればOK

$ pnpm build -F functions
$ firebase deploy --only functions

firebase.jsonから、predeployを除いたので、
firebase deployだけではビルドされないので注意。


以上!!これで、モノレポ化が進む。。(*´ω`*)

参考にしたサイトさま