⛈️

Viteでgrpc-webを使うのはおすすめできない

2024/03/29に公開

結論

公式 (https://github.com/grpc/grpc-web) は使えるがおすすめしない。

(※ 間違いや提案などあればコメント下さい。)

公式の問題点

grpc-web not working in a Vite+Typescript app #1242 などで議論になっていた通りViteとgrpc-webの相性が悪いと言われていたが、原因は公式のgrpc-webがCommon JSかClosureのみしか生成できないことにある。

Viteは原則ESMしか理解しないのでそのままimportすることができない。

回避策

Viteは世の中に多数存在するCJS製ライブラリが依存関係に含まれているケースに対応するために、デフォルトでnode_modules/ 内などのCJSをESMに変換してくれる機能を持っている(依存関係の事前バンドル を参照)。

そのため、grpc-webにより生成されたCJSのコードをパッケージ化してしまえばよい。

サンプル実装

別の問題点

上記の回避策でViteとの相性が悪い問題は解消するが、ESMを生成できない以外にもgrpc-webがモダン化に追いつけていない別の問題がある。

Viteでgrpc-webを利用したアプリケーションをビルドすると分かるが、生成されたコードが依存する google-protobuf というランタイムライブラリにeval が含まれていることについてWarningが出る。

node_modules/google-protobuf/google-protobuf.js (48:475) Use of eval in "node_modules/google-protobuf/google-protobuf.js" is strongly discouraged as it poses security risks and may cause issues with minification.

このeval は、google-protobuf がclosureコンパイラによって作られており、その際にコンパイラが依存するclosure-library によって出力されるのだが、Closure Library is in Maintenance Mode #1214 にもある通りclosure-library はモダンなJSの出力に対応できていない・今後もできないと予想されることから今はメンテナンスモードとなっており、2024年8月1日を持って開発終了する事が決まっている。

google-protobufclosure-library に依存せずにモダンなJSとして更新される、もしくはgrpc-webの生成コードが依存するランタイムライブラリがgoogle-protobuf から新しいものに置き換えられるなどしない限り、このeval の問題は今後改善される見込みがないことになる。

あくまでWarningなので気にしないという手も無くはないが、少なくともプロダクションで利用する場合は、例え公式であっても上記のeval の問題を含め今後古くなって顕在化する問題点等が改善される見込みの極めて低いパッケージには出来れば依存したくない。

ちなみに、先述のclosure-library が開発終了する発表をしたissue では、下記の通りprotobufjsts-proto などをgoog.proto の代替として提案している。

For protocol buffers (goog.proto, goog.proto2), consider protobufjs or ts-proto.

代替

公式に頼れない時点でデファクトスタンダードは無いように思うので要件や好みに合わせて選択することになるが、個人的にはconnect-webが使いやすく信頼できるように思う。

protobuf-ts も悪く無い。

上記2つは少なくとも公式と同じWarningは出ないことを確認している[1]のと、ESMとして使えるのでパッケージ化などの回りくどいワークアラウンドを必要としないので少なくとも公式よりは良いと思う。

脚注
  1. connect-web, protobuf-ts各ブランチで確認 ↩︎

GitHubで編集を提案

Discussion