crossplane / crossplane/function-sdk-typescript

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

Abierto
#36 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
3
Forks
2
Merge medio
9 h 49 min
PR fusionados (30 d)
14

Descripción

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

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Línea de trabajo

Empieza por package.json y scripts/protoc-gen.sh; después inspecciona los imports de src/proto indicados y el árbol de dependencias de producción generado. Verifica que los imports de runtime se resuelvan omitiendo las dependencias de desarrollo, que la generación de código en tiempo de compilación quede excluida y que las comprobaciones de inicio existentes, así como una solicitud completa de compose, sigan ejecutándose correctamente.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
grpc, node.js, typescript
Área
backend, build-system
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Activo
Claridad
Bastante claro
Aptitud para principiantes
70/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.