crossplane / crossplane/function-sdk-typescript

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

Aperta
#36 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
TypeScript
Stelle
3
Fork
2
Merge medio
9h 49m
PR unite (30g)
14

Descrizione

### 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.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Direzione di ricerca

Start with package.json and scripts/protoc-gen.sh, then inspect the listed src/proto imports and the generated production dependency tree. Verify that runtime imports resolve with dev dependencies omitted, that build-time codegen is excluded, and that the existing startup checks plus a full compose request still succeed.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
grpc, node.js, typescript
Ambito
backend, build-system
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Attiva
Chiarezza
Abbastanza chiara
Idoneità per principianti
70/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.