背景 #
protoc を使った複雑なスクリプトを引き継いだので、 Buf に移行したいよねという気持ちから調べてみた結果をまとめる。
前提 #
簡略化したプロジェクト構成はこちら。実際のコードではパッケージ名とディレクトリ構造が一致しておらずリンターにも指摘されているのですが、ここではその点は省略します。
/
├─ buf.yaml
├─ buf.gen.yaml
├─ buf.lock
├─ proto/
│ ├─ v1/
│ │ ├─ analytics/
│ │ │ ├─ analytics.proto
│ │ │ └─ analyticsHealth.proto // ../healthcheck.proto に依存
│ │ ├─ api/
│ │ │ └─ api.proto
│ │ └─ healthcheck.proto
│ └─ v2/
│ └─ api/
│ ├─ api.v2.proto
│ └─ other.proto // google/protobuf/timestamp に依存
└─ gen/ // 将来はここに生成させたいみたこと #
Buf には build と generate の両方の設定ファイルに入力ファイルの指定がある #
そもそも buf.gen.yaml の方の inputs は任意だった。これは paths や exclude_paths などを使って module の中を更に絞り込みたい時に使うべきと理解。
複数の module を指定したときは生成結果はマージされる #
buf.yaml
modules:
- path: proto/v1
- path: proto/v2buf.gen.yaml
plugins:
- local: ./node_modules/ts-proto/protoc-gen-ts_proto
out: gen/ts_proto
strategy: allこういう時。 proto/v1 proto/v2 がそれぞれカレントディレクトリとして処理されるので、生成されるファイルは api/api.ts api/api.v2.ts のように、どちらも api/ 配下になる。
最終的にマージされるので、結果は以下になる。重複しているファイルは上書きになる。上書きが発生した時は警告が出た。
gen
└── ts_proto
├── analytics
│ ├── analytics.ts
│ └── analyticsHealth.ts
├── api
│ ├── api.ts
│ ├── api.v2.ts
│ └── other.ts
├── google
│ ├── api
│ │ ├── annotations.ts
│ │ └── http.ts
│ └── protobuf
│ ├── descriptor.ts
│ └── timestamp.ts
└── healthcheck.ts特定のファイルのみ generate するときは buf.gen.yaml の inputs.paths を使う #
例として v1 だけ生成するとします。module のルートを変更するので import のパスは適切に変更してください。
buf.yaml
modules:
- path: protobuf.gen.yaml
inputs:
- directory: .
paths:
- proto/v1結果
gen
└── ts_proto
├── google
│ ├── api
│ │ ├── annotations.ts
│ │ └── http.ts
│ └── protobuf
│ └── descriptor.ts
└── v1
├── analytics
│ ├── analytics.ts
│ └── analyticsHealth.ts
├── api
│ └── api.ts
└── healthcheck.tsprotoc-gen-ts には grpc-js が必要で、 ts-proto には不要 #
オプションなしの素の状態で生成した場合はそうなった。NestJS に組み込む場合は protoc-gen-ts で出る雛形(UnimplementedXXXXService)は使わないので、どちらでもいい。
protoc は -XXX_out を基準にコード生成が実行されるので、protoc では1回の実行であっても Buf に移行すると plugins を複数書く場合がある #
- つまり複数の -XXX_out を書くことで 1 回の protoc で複数のプラグインを実行可能
- –plugin を指定しても、対応する -XXX_out が存在しないとそのプラグインは実行されない(-XXX_opt も同様で、無駄な指定になる)
- 無駄な指定めっちゃあって 😡
js は protoc にビルトインされているので、–plugin を指定せずともコード生成可能 #
書いている通り。
最後に #
更新するかも。
最終更新日: 2026-01-13