crossplane / crossplane/function-sdk-typescript

ts-proto ships 25MB of build-time codegen into every function image; @bufbuild/protobuf is undeclared

オープン
#36 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
TypeScript
スター
3
フォーク
2
平均マージ
9時間 49分
マージ済み PR(30日)
14

説明

### What happened?

Three of the SDK's seven runtime `dependencies` are not imported by the shipped code, and one dependency that *is* imported at runtime is not declared at all. The largest consequence is that `ts-proto` — a build-time `protoc` plugin — drags ~25MB of native binary into every function image built against the SDK.

### Evidence

`ts-proto` is used only as a `protoc` plugin, in `scripts/protoc-gen.sh`:

```
--plugin=./node_modules/.bin/protoc-gen-ts_proto
```

It is imported nowhere in `src/`, and nothing in a fully installed function tree imports it either (grepped every `.js`/`.mjs`/`.cjs`). But it is in `dependencies`, so it ships — and it brings a formatter with it:

```
@crossplane-org/function-sdk-typescript
└─ ts-proto (908K)
└─ ts-poet (216K)
└─ dprint-node (24M) <- native binary, does not compress
```

Mapping each declared runtime dependency to actual imports in `src/`:

| dependency | files importing it | verdict |
|---|---|---|
| `@grpc/grpc-js` | 4 | runtime |
| `pino` | 4 | runtime |
| `ts-deepmerge` | 2 | runtime |
| `kubernetes-models` | 1 | runtime |
| `ts-proto` | 0 | build-time only (protoc plugin) |
| `google-protobuf` | 0 | appears unused |
| `@grpc/proto-loader` | 0 | unused directly; `@grpc/grpc-js` depends on it anyway |
| `@bufbuild/protobuf` | 3 | **runtime, but undeclared** |

### The undeclared dependency

The ts-proto-generated wire code imports `@bufbuild/protobuf`:

```
src/proto/run_function.ts:8: import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
src/proto/google/protobuf/duration.ts:8: import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
src/proto/google/protobuf/struct.ts:8: import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
```

`@bufbuild/protobuf` is not in `package.json`. It resolves today only because `ts-proto` depends on it. **This makes the two changes order-dependent**: moving `ts-proto` to `devDependencies` without first declaring `@bufbuild/protobuf` would remove it from the runtime tree and break every function at import time.

### Proposed change

1. Add `@bufbuild/protobuf` to `dependencies` (currently resolving as 2.11.0). Do this first — on its own it is a correctness fix regardless of the rest.
2. Move `ts-proto` to `devDependencies`.
3. Drop `google-protobuf` and `@types/google-protobuf` if nothing needs them — they look like leftovers from the pre-ts-proto `--ts_out` path still commented out in `scripts/protoc-gen.sh`.
4. Optionally drop `@grpc/proto-loader` from `dependencies`; it is not imported directly and `@grpc/grpc-js` declares it, so this changes nothing on disk.

### Impact

Measured on a real function project (`configuration-aws-network-ts`), installed with `--omit=dev`:

- Removing the `ts-proto` → `ts-poet` → `dprint-node` chain took `node_modules` from **62MB to 37MB**, and the function still started and served requests.
- Dropping `google-protobuf` saves a further ~944K.

`dprint-node` is a native binary, so unlike the `.d.ts` bulk it does not compress away in the packaged layer — it is close to 25MB of image size for every TypeScript function, and it is streamed out of the build container on every build.

`protobufjs` (3.1M) is *not* removable this way; it arrives via `@grpc/proto-loader` ← `@grpc/grpc-js`.

### Caveat

The 62MB → 37MB check verified process startup, a served gRPC listener, and the static import graph. It did not run a full compose request against the stripped tree. Worth confirming before release.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

まず package.json と scripts/protoc-gen.sh を確認し、次に一覧にある src/proto の import と、生成された本番依存関係ツリーを調べます。dev dependencies を省略した状態で runtime の import が解決されること、ビルド時のコード生成が除外されていること、既存の startup checks と完全な compose リクエストが引き続き成功することを確認します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
grpc, node.js, typescript
領域
backend, build-system
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
70/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。