← Debugging Guides

阅读中文版本

Vue/Vite: @ alias fails to resolve

Fix Vite and Vue "Failed to resolve import" for the @ alias by configuring resolve.alias and matching tsconfig paths.

beginnerdebuggingvitevuebuild

Symptoms

  • Failed to resolve import "@/components/Foo.vue"
  • Imports with @ work in the editor but fail at build time
  • The alias resolves in dev but not in the production build

Possible causes

  • resolve.alias is not configured in vite.config
  • tsconfig paths are set but Vite does not read them
  • The alias is configured but points at the wrong directory
  • A plugin or framework reset the resolve configuration

Diagnosis steps

Check vite.config for a resolve.alias entry

Interpretation

Vite does not know @ by default; without an explicit alias it treats @ as a package name.

Verify the alias target resolves to the src directory

Interpretation

A wrong base path produces "failed to resolve" even though the alias exists.

Confirm tsconfig paths match the alias

Interpretation

Mismatched paths make the editor and the bundler disagree, so one passes while the other fails.

Root cause

Bundlers resolve module specifiers literally unless an alias is declared. The @ prefix is a convention, not a built-in, so Vite fails to resolve it without resolve.alias. Editors often read tsconfig paths separately, which is why the import can appear valid in the IDE while the build rejects it.

Fix

Add resolve.alias in vite.config mapping @ to the src path using fileURLToPath or path.resolve, and mirror the same mapping in tsconfig paths so the editor agrees. Also configure the test runner and any type-check step to use the alias, since each tool resolves independently.

Verify the fix

Run the dev server and a production build; both resolve @ imports without error, and the editor no longer shows unresolved-import warnings.

Symptoms

The build fails with Failed to resolve import "@/components/Foo.vue". The same import may look fine in the editor, so the two tools disagree.

Diagnosis

Inspect the Vite config and tsconfig:

// vite.config.js — check for resolve.alias
import { fileURLToPath, URL } from 'node:url';

export default defineConfig({
  resolve: {
    alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) },
  },
});

If there is no alias, Vite treats @ as a package scope.

Fix

Configure the alias and mirror it for the editor:

// tsconfig.json
{ "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["src/*"] } } }

Verification

Run vite dev and vite build; both resolve @/... imports with no error, and the editor no longer underlines them, confirming every tool uses the same mapping.

Additional Notes

Editors and bundlers resolve module specifiers independently, so an alias that satisfies one does not automatically satisfy the other, which is why a path can look valid in the ide yet fail the build. Declaring the alias in the bundler and mirroring it in the type checker keeps both views consistent, and a wrong target directory produces the same unresolved message as a missing alias. Because wrappers such as framework plugins can reset the resolve configuration, reviewing the effective settings rather than assuming defaults is the reliable way to confirm where resolution broke.