How to configure module resolution aliases in Vite

Module aliasing in Vite requires precise alignment between TypeScript path mappings and Rollup’s native resolution engine. Unlike legacy bundlers that rewrite paths at build time, Vite resolves aliases during the dev server’s native ESM transformation phase. Understanding the underlying JavaScript Build Pipeline & Module Resolution Fundamentals is critical for avoiding resolution deadlocks in modern monorepo architectures.

Alias Resolution Failure & Debugging Workflow

Error Signature: Vite dev server returns HTTP 404 on aliased imports (e.g., import { config } from '@core/config') or throws ERR_MODULE_NOT_FOUND during vite build pre-bundling.

Root Cause: Mismatch between tsconfig.json compilerOptions.paths and Vite’s resolve.alias configuration, compounded by Vite’s dependency pre-bundling caching aliased paths as absolute URLs instead of relative specifiers. This breaks the native ESM loader’s resolution algorithm.

Exact Config & CLI Fix: Implement synchronous alias resolution in vite.config.ts using path.resolve() with import.meta.url. Clear stale caches via CLI: npx vite --force. Ensure resolve.alias uses an array of { find: RegExp | string, replacement: string } objects.

// vite.config.ts
import { defineConfig } from 'vite';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

export default defineConfig({
  resolve: {
  alias: [
  { find: /^@app\/(.*)/, replacement: path.resolve(__dirname, 'src/$1') },
  { find: '@core', replacement: path.resolve(__dirname, 'src/core') }
  ]
  }
});

Verification Metric: Zero 404s in Chrome DevTools Network tab during HMR; vite build completes with ✓ built in <X>ms; rollup-plugin-visualizer confirms aliased modules are correctly deduplicated and tree-shaken without chunk bloat.

Debugging Workflow: When debugging resolution failures, trace the module graph using vite --debug. The resolution chain must align with Understanding ES Modules vs CommonJS in Bundlers to prevent dual-package hazards during alias expansion.

Monorepo Workspace Alias Conflicts & Cache Invalidation

Error Signature: Stale alias resolution after workspace dependency updates, resulting in SyntaxError: Unexpected token or incorrect chunk hashing in production builds.

Root Cause: Vite’s node_modules/.vite cache retains pre-bundled module metadata. Workspace symlink changes or package.json exports field updates bypass the default cache invalidation heuristic, causing the resolver to serve outdated ESM stubs.

Exact Config & CLI Fix: Force cache regeneration via npx vite --force or programmatically set optimizeDeps.force: true in config. Add resolve.dedupe: ['@workspace/shared'] to enforce single-instance resolution across workspace boundaries. Configure optimizeDeps.include to explicitly pre-bundle aliased workspace packages.

// vite.config.ts (workspace patch)
export default defineConfig({
  resolve: {
  alias: [ /* existing aliases */ ],
  dedupe: ['@workspace/shared']
  },
  optimizeDeps: {
  force: true,
  include: ['@workspace/shared', '@workspace/ui']
  }
});

Fallback Logic: If workspace symlinks persistently break resolution or trigger circular dependency warnings, bypass pre-bundling for internal packages by adding them to optimizeDeps.exclude. This forces Vite to resolve them directly from source during dev, eliminating stale cache collisions while preserving HMR speed.

Verification Metric: Cache directory node_modules/.vite/deps regeneration timestamp matches build start; vite build --debug logs show resolved alias mapping correctly to workspace dist/ outputs; production bundle size decreases by >15% due to eliminated duplicate chunks.

Production Verification & Performance Metrics

Validation Phase: Execute npx vite build --mode production with build.sourcemap: 'hidden' and build.minify: 'esbuild'. Run npx vite preview and audit the network waterfall for sequential alias resolution delays.

# Build with hidden sourcemaps and esbuild minification
npx vite build --mode production

# Audit runtime performance
npx vite preview --port 4173

Verification Metric: Initial chunk load time < 200ms on simulated 3G; vite-bundle-analyzer reports 0 duplicate alias imports; HMR latency remains < 50ms after alias-triggered file changes.

Final Validation: Cross-reference build artifacts with runtime performance. Ensuring alias resolution does not introduce synchronous blocking or duplicate module instantiation is critical for maintaining optimal bundle architectures. Validate chunk splitting boundaries using build.rollupOptions.output.manualChunks to guarantee aliased modules land in predictable, cacheable assets.