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字段不仅可以定义别名,还可以用来做“条件导出”。它可以根据当前环境(如node或browser)指向不同的文件。 - 不可见性:如果你的项目是一个 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"]
}