vite项目中配置alias别名

25 阅读3分钟

vite项目中配置alias别名

方式一:CommonJS 传统方式 (__dirname)

  • 依赖 Node.js 内置的全局变量 __dirname,它指向当前执行脚本所在的目录。
  • 主要用于 CommonJS 模块规范(使用 require)。
  • 绝大多数老项目和 Webpack 配置都采用这种方式。对于习惯 Node.js 开发的人来说非常直观。

缺点:

ESM* 兼容性*:在纯 ES Modules ("type": "module") 环境下,**__dirname** 是未定义的。如果你在现代 Vite 项目(默认 ESM)中直接这样写,可能会报错。

import { resolve } from 'path'/** 路径查找 */
const pathResolve = (dir) => {
  return resolve(__dirname, '.', dir)
}
​
const alias =  {
  '@': pathResolve('src'),
}

因为 Vite 默认运行在 ESM 模式下,强行使用 __dirname 会导致 ReferenceError: __dirname is not defined

在 Vite 项目中,如果你非要用 __dirname,你需要在代码顶部手动定义它

// 不推荐的折中方案
import { dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));

方式二:现代 ESM 方式 (import.meta.url)

  • 目前 Vite 官方文档推荐的做法,也是适配未来趋势的写法。
  • 利用 import.meta.url 获取当前模块的绝对 URL(类似 file:///...),然后通过 URL 构造函数和 fileURLToPath 将其转换为系统路径。
  • ES Modules (* ESM***)** 环境,是现代前端构建工具(如 Vite)的首选。
  • 完全符合现代 JavaScript 模块标准。
  • package.json 设置了 "type": "module" 的项目中运行顺畅。
  • Vite 配置文件默认就是 ESM,这种写法不需要任何 Polyfill。

最终在 defineConfig中配置生效

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'import { fileURLToPath, URL } from 'node:url'
const alias =  {
  '@': fileURLToPath(new URL('./src', import.meta.url))
}
​
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias,
  },
})

路径提示或者ts类型提示

为了获取路径提示或者ts类型提示,需要在 jsconfig.json 或者 tsconfig.json 中配置

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

Node.js 的 Subpath Imports 特性

还有一种别名是配置在 package.json 中的。Node.js 的 Subpath Imports 特性。从 Node.js 12.19.0+ 和 14.6.0+ 开始,官方引入了一种原生支持路径别名的方式,直接在 package.json 中通过 imports 字段配置。

  • 原生限制imports 字段的键必须以 **#** 开头,这是为了确保它们与普通的 npm 包(如 @vue/runtime-core)区分开来。
  • Vite 的 alias 可以使用任何字符(如 @),没有任何硬性限制。
  • Subpath Imports:这是 Node.js 官方规范。如果你在运行一些不需要构建步骤的 Node 脚本(比如单元测试、SSR 服务端渲染),Node.js 能直接识别 #/*,不需要额外的编译转换。
  • Alias:完全依赖于构建工具(Vite/Webpack)。如果直接用 node 运行包含 @/ 的代码,会直接报错。
  • 私有化imports 字段不仅可以定义别名,还可以用来做“条件导出”。它可以根据当前环境(如 nodebrowser)指向不同的文件。
  • 不可见性:如果你的项目是一个 npm 包,imports 定义的别名对包的外部使用者是不可见的,这起到了一定的封装作用
// package.json
{
  "name": "my-vue-app",
  "type": "module",
  "imports": {
    "#*": "./src/*"
  }
}
// tsconfig.app.json
{
  "compilerOptions": {
    // 1. 必须配置 baseUrl,它是解析非绝对路径的基础目录
    "baseUrl": ".", 
    // !!! typescript 7 +, 计划移除“baseUrl”,所以不需要配置此项,
    // 在不配置 baseUrl 的情况下, paths 中的路径需要使用相对路径
    
    "paths": {
      // 2. 映射关系必须与 package.json 保持一致
      "#/*": ["src/*"] 
    },
    
    // 3. 在现代 Vite 项目中,通常还需要确保 moduleResolution 足够新
    "moduleResolution": "bundler", // 或者 "node"
    
    "allowJs": true
  },
  "include": ["src/**/*"],
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}