fix(webapp): make prop-types a production dependency (#4492)

## Summary

The webapp's server bundle imports `prop-types` directly, but the
package was declared only as a `devDependency`. A production install
therefore leaves it out and the built server fails to boot:

```
Failed to start server: Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'prop-types'
  imported from /triggerdotdev/apps/webapp/build/server/assets/server-build-*.js
```

Moving it to `dependencies` is the whole change.

## Why the bundle imports it

Nothing in the webapp's own code uses `prop-types` — there is no
reference to it, or to `PropTypes`, anywhere under `apps/webapp/app`. It
arrives through `recharts`, whose `react-smooth` dependency still
declares `propTypes` on its components.

That was invisible until recently. While `recharts` was resolved at
runtime, its `prop-types` import was satisfied inside `recharts`' own
dependency tree, which is production all the way down. #4486 added
`recharts` and `victory-vendor` to `ssr.noExternal` to fix a hydration
mismatch on every server-rendered chart; that inlines `react-smooth`
into the server bundle, which moves its `prop-types` import into the
webapp's own resolution scope — where the package was not available in
production.

So the bundling change was correct about *which* d3-shape build both
sides resolve, and wrong about what the production runtime would be able
to find.

## Verification

`docker/Dockerfile` builds the runtime dependencies with `pnpm install
--prod` against a `turbo prune --scope=webapp --docker` output, so I
reproduced exactly that: pruned the workspace, installed with `--prod`,
and imported `prop-types` from `apps/webapp`.

| | result |
| -- | -- |
| `main` as it stands (devDependency only) | `FAILS:
ERR_MODULE_NOT_FOUND` |
| with this change | `prop-types resolves OK` |

It resolves both as a CommonJS `require` and as an ESM `import`, which
is the form the bundle uses.

I also checked this is not one symptom of a wider problem: of the 169
bare specifier roots the server bundle imports, `prop-types` is the
**only** one that is a devDependency and not a production dependency.
The rest are node builtins or production dependencies.

The hydration fix from #4486 is unaffected — the rebuilt bundle still
carries the rounding d3-path build.

## Notes

`prop-types` is inert in production (its entry point swaps in
`factoryWithThrowingShims`), so this adds a 124 KB package that does no
work at runtime. It has to be resolvable regardless, because the import
is real.

An alternative would be adding `prop-types` to `ssr.noExternal` so it is
inlined and needs no runtime resolution. That keeps the dependency list
honest about the fact that the webapp itself does not use it, at the
cost of bundling a CommonJS package into the ESM server output. This
route is the smaller, better-understood change.

Worth following up separately: a check that every bare import in the
server bundle resolves from a production install would have caught this
before it landed. Local development installs every devDependency, so the
gap is invisible when the built server is run from a working tree.
This commit is contained in:
Eric Allam
2026-08-03 17:09:03 +01:00
committed by GitHub
parent 3fba04573d
commit 57254b57fb
2 changed files with 4 additions and 4 deletions
+1 -1
View File
@@ -179,6 +179,7 @@
"prism-react-renderer": "^2.3.1",
"prismjs": "^1.30.0",
"prom-client": "^15.1.0",
"prop-types": "^15.8.1",
"qrcode.react": "^4.2.0",
"random-words": "^2.0.0",
"react": "^18.2.0",
@@ -260,7 +261,6 @@
"npm-run-all": "^4.1.5",
"postcss-import": "^16.0.1",
"postcss-loader": "^8.1.1",
"prop-types": "^15.8.1",
"rimraf": "^6.0.1",
"style-loader": "^3.3.4",
"supertest": "^7.0.0",
+3 -3
View File
@@ -668,6 +668,9 @@ importers:
prom-client:
specifier: ^15.1.0
version: 15.1.0
prop-types:
specifier: ^15.8.1
version: 15.8.1
qrcode.react:
specifier: ^4.2.0
version: 4.2.0(react@18.3.1)
@@ -906,9 +909,6 @@ importers:
postcss-loader:
specifier: ^8.1.1
version: 8.1.1(postcss@8.5.15)(typescript@6.0.3)(webpack@5.102.1(@swc/core@1.3.26)(esbuild@0.15.18))
prop-types:
specifier: ^15.8.1
version: 15.8.1
rimraf:
specifier: ^6.0.1
version: 6.0.1