fix(webapp): make prop-types a production dependency - #4492
Conversation
The server bundle imports prop-types directly, so it has to be present in a production install. It was declared only as a devDependency, so `pnpm install --prod` leaves it out and the built server fails to boot with ERR_MODULE_NOT_FOUND on startup. Nothing in the webapp's own code imports it. It arrives through recharts, whose react-smooth dependency declares propTypes on its components. That used to be invisible here: while recharts was resolved at runtime, the import was satisfied inside recharts' own dependency tree. #4486 added recharts to `ssr.noExternal` to fix a hydration mismatch, which inlines react-smooth into the server bundle and moves its prop-types import into the webapp's own resolution scope, where the package was not available in production. Verified by pruning the workspace the way docker/Dockerfile does and running `pnpm install --prod` against it: importing prop-types from the webapp fails with ERR_MODULE_NOT_FOUND before this change and resolves after. It is the only devDependency-only bare import in the server bundle, out of 169 specifiers.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
📜 Recent review details⏰ Context from checks skipped due to timeout. (33)
🧰 Additional context used📓 Path-based instructions (2)**/package.json📄 CodeRabbit inference engine (AGENTS.md)
Files:
apps/webapp/**/package.json📄 CodeRabbit inference engine (apps/webapp/CLAUDE.md)
Files:
🧠 Learnings (1)📚 Learning: 2026-04-27T16:46:03.861ZApplied to files:
🔇 Additional comments (1)
WalkthroughThe webapp package now declares 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
The webapp's server bundle imports
prop-typesdirectly, but the package was declared only as adevDependency. A production install therefore leaves it out and the built server fails to boot:Moving it to
dependenciesis 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 toPropTypes, anywhere underapps/webapp/app. It arrives throughrecharts, whosereact-smoothdependency still declarespropTypeson its components.That was invisible until recently. While
rechartswas resolved at runtime, itsprop-typesimport was satisfied insiderecharts' own dependency tree, which is production all the way down. #4486 addedrechartsandvictory-vendortossr.noExternalto fix a hydration mismatch on every server-rendered chart; that inlinesreact-smoothinto the server bundle, which moves itsprop-typesimport 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/Dockerfilebuilds the runtime dependencies withpnpm install --prodagainst aturbo prune --scope=webapp --dockeroutput, so I reproduced exactly that: pruned the workspace, installed with--prod, and importedprop-typesfromapps/webapp.mainas it stands (devDependency only)FAILS: ERR_MODULE_NOT_FOUNDprop-types resolves OKIt resolves both as a CommonJS
requireand as an ESMimport, 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-typesis 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-typesis inert in production (its entry point swaps infactoryWithThrowingShims), 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-typestossr.noExternalso 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.