Module resolution determines how TypeScript translates import paths to actual files. Algorithms: Node (legacy CJS), NodeNext/Node16 (ESM + CJS for Node.js), Bundler (modern bundlers, no extension requirement). Package.json exports field defines the public API of a package, allowing conditional exports (esm/cjs/types). Path aliases (@/components → src/components) require both tsconfig paths and bundler config. Understanding resolution prevents "cannot find module" errors.
Package exports field for dual CJS/ESM packages.
"Node" resolution misses modern package.json exports. "Bundler" correctly resolves conditional exports and allows extension-less imports that your bundler handles. Use "NodeNext" for Node.js native ESM.
tsconfig paths only affect TypeScript type resolution — not runtime. If you add "@/*" to tsconfig paths without adding the corresponding alias in vite.config.ts, builds succeed but runtime fails.
Without an exports field, tree-shaking and subpath imports are impossible. All modern packages should define exports with "types", "import", and "require" conditions for TypeScript + dual CJS/ESM support.
Sign in to share your feedback and join the discussion.