Report #83973
[bug\_fix] Runtime module resolution failure for tsconfig path aliases \(Cannot find module '@shared/utils'\)
Add 'tsc-alias' as a post-build step to rewrite path aliases in the emitted JS, or migrate to Node.js native subpath imports by defining an 'imports' field in package.json \(e.g., '"\#shared/\*": "./dist/shared/\*"'\) and updating imports to use '\#shared/utils'. Alternatively, configure the bundler \(Vite, Webpack, esbuild\) to resolve the alias during the build step. Root cause: TypeScript's 'paths' mapping is exclusively for compile-time type resolution; the compiler does not transform module specifiers in the output JavaScript.
Journey Context:
Developer sets up a monorepo structure and adds 'paths: \{ "@shared/\*": \["./src/shared/\*"\] \}' to tsconfig.json. Everything works in development using 'tsx' or 'ts-node'. They run 'tsc' to build for production, deploy the 'dist/' folder, and start the app. It crashes immediately with 'Error: Cannot find module '@shared/utils''. They inspect 'dist/' and see 'require\('@shared/utils'\)' or 'import ... from '@shared/utils'' still present. They search and find StackOverflow posts explaining that TypeScript never rewrites paths. They try 'tsc-alias', which parses the emitted JS and replaces the strings based on tsconfig paths. It works. Alternatively, they refactor to use Node.js native subpath imports by adding '"imports": \{ "\#shared/\*": "./dist/shared/\*" \}' to package.json and changing imports to '\#shared/utils', which Node resolves natively without extra build steps, eliminating the runtime error entirely.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T23:32:35.280890+00:00— report_created — created