当前位置: 首页 > article >正文

【99.9%解决】vue3+vite+typescript+vscode使用@alias路径别名配置不正确导致红色波浪线的解决办法

相信很多人设置了别名“@”后在编辑器内产生了大量的红色波浪线,警告无法读取相关模块。网上针对这个问题都没有好好分析原因,并且提供真正理解之下的解决方案。我在历经各种失败后,总结出这篇文章,希望对大家有所帮助。
当然我因为是匆忙上手vue项目,没有系统去学习nodejsvite等,所以很可能这个问题产生的根本原因只是你我都没仔细看说明书~~~

各种出错情况

在这里罗列一下我曾出现的问题,大家如果有别的现象,但后来通过本文所提方法解决了,请写在留言里,我会补充进来。

  • vscode编辑器中出现大量红色波浪线警告,这就是路径没配置好的最明显证据;
  • 使用typescript就出错,使用javascript就正常,把<script lang="ts"></script>中的lang="ts"删除后正常;
  • .vue组件页面中用import引入时不出现警告,但在独立的.js.ts文件中引用文件时出现波浪警告;
  • npm run dev时出现错误提示;
  • 编辑器有大量红色警告,但执行npm run dev命令正常启动服务;
  • 无论开发状态下有没有出现红色警告,但执行命令npm run devvite build正常,执行npm run build时却失败,出现类似提示Cannot find module '@/test/types' or its corresponding type declarations (我就一直卡在这里);
  • 编译时提示模块找不到,出现类似src/index.ts:4:31 - error TS7016: Could not find a declaration file for module '@/components/system/Register.vue'. 'E:/Projects/test/src/components/system/Register.vue' implicitly has an 'any' type.的提示

在这里插入图片描述

vite和typescript调用分析

Vite 配置中设置路径别名时,.vue 文件和 .ts 文件的处理方式有所不同。

  • .vue 文件中的路径解析会被 Vite 的插件自动处理。
    比如 .vue非typerscript代码中找不到 @ 别名,很可能是因为vite.config.ts 文件中没有正确配置路径别名。
  • .ts 文件的别名解析可能依赖于 tsconfig.json 的配置。
    比如 .ts 文件中找不到 @ 别名,很可能是因为tsconfig.json 文件中没有正确配置路径别名。

如果这两个没有配置正确,那自然就会出现之前提及的各种错误。
比如单独的ts或ts代码片段里出现错误,那就说明vite配置好了,但typescript没有配置好。

解决方案

不要跳,一步步看,看懂了以后遇到任何类似问题都能解决了。

- 主要配置

这是网上出现的最主要方案,但很可能配完以后还是失败。

  1. 确认 Vite 配置中的路径别名生效:
    vite.config.ts 中,确保别名配置正确,主要写法如下:
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': '/src'
    }
  }
});
  1. tsconfig.json 中设置路径别名:
    确保在 tsconfig.json 文件中加入类似下面的配置,以便 TypeScript 在编译时能正确解析 @,主要写法如下:
// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

如果配置完成后还是失败,但情况与之前不同了,那么恭喜你,我们将进入下个必要手段:

  1. 开发时虽然路径有波浪线警告,但执行npm run dev命令正常,前端可运行【说明vite.config.ts配置正确】;
  2. 运行vite build正常【说明vite.config.ts配置正确】;
  3. 运行npm run build失败【说明tsconfig.json配置错误】。

- 次要及必要配置(往往是这一步导致的错)

你再仔细看看你的ts.config.json真是写得一摸一样么?反正我不是。。。

用vite首次创建项目时,tsconfig.json往往内容是这样的:

// tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}

你改完以后的代码往往是这样的:

// tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
    	"@/*": ["src/*"],
    }
  }
}

问题就出在这里了。

typescript在解析时,他根据配置引入了 ./tsconfig.app.json 这个配置文件,而这个配置文件可能是这样的;

// tsconfig.app.json
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "Bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "preserve",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

发现没,这里也有一个compilerOptions项,现在你有那种茅塞顿开的感觉了么?
反正当我看到这个的时候恍然大悟了,原来是tm被覆盖了啊!

路径别名配置的生效文件: 由于 tsconfig.json 文件引用了 tsconfig.app.json 和 tsconfig.node.json,要确保这两个文件中没有覆盖 baseUrl 和 paths 配置。一般来说,主要的路径别名配置应位于 tsconfig.app.json 文件中,以便应用编译时可以正确使用别名。

事情到这里都应该知道怎么处理了吧?其实有很多种方式,这里列二种区别明显的:

方法一:覆盖

我让你覆盖,我让你覆盖。
你是不是要覆盖,行,我让你也有,你爱覆盖谁覆盖谁!

// tsconfig.json 原内容不变
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  // 写不写都可以
  /*"compilerOptions": {
    "baseUrl": ".",
    "paths": {
    	"@/*": ["src/*"],
    }
  }*/
}

// tsconfig.app.json
{
  "compilerOptions": {
   // 原配置
    "noUncheckedSideEffectImports": true,
    ... 

	// 不管tsconfig.json写不写,我都给他写一下
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

方法二:继承

references配置的模块就是子模块,那我让子模块继承extends父模块的衣钵不就行了?

// tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  // 新增配置
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
    	"@/*": ["src/*"],
    }
  }
}

// tsconfig.app.json
{
  // 加一句:继承,从你爸爸这里继承配置,看谁覆盖谁
  "extends": "./tsconfig.json",
  // 原生配置
  "compilerOptions": {
    "noUncheckedSideEffectImports": true,
    ...
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

通过继承,可以在 tsconfig.json 中定义一些通用的配置项,然后在 tsconfig.app.json 中只定义特定的或覆盖的配置项。这样可以减少重复配置,提高维护性。
了解了继承的概念后,以后你可以根据项目需要写不同的配置,然后把他们按需引进来就行了~~
哇哦,有用却用不上的概念又多了一点点。

其它情况

上面的操作基本上能解决99%的问题,现在我再提几个可能存在的情况。

- 安装依赖

在vue里使用typescript,请看一下node_modules/里是不是已经安装了vuevue-tsc,这个问题一般是不存在的,除非你中途从js转到了ts。。。

npm install vue vue-tsc --save-dev

- path在vite.config.ts的应用

有些人喜欢使用 path 模块的 resolve 方法,将 __dirnamesrc 组合成一个绝对路径,更保险一点。

  • 跨平台兼容性:path 模块确保路径在不同操作系统上都能正确解析,避免了路径分隔符不一致的问题。
  • 动态路径生成:path.resolve 可以根据当前文件的位置动态生成路径,适用于项目结构复杂或路径需要动态变化的场景。
  • 可读性和维护性:使用 path 模块的代码更具可读性和维护性,尤其是在大型项目中,路径管理变得更加清晰。
  1. 先安装path模块
cnpm i path
  1. vite.config.ts里设置
...
import path from 'path'

export default defineConfig({
 ...
 resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
    ...
 }
 ...
})
  1. 示例
// 1. path
const path = require('path');

const srcPath = path.resolve(__dirname, 'src');
console.log(srcPath); // 输出: C:\Users\user\project\src

//2. 原始
const srcPath = '/src';
console.log(srcPath); // 输出: /src
  • __dirname 是当前文件 config.js 所在的目录路径,即 C:\Users\user\project。
  • path.resolve(__dirname, ‘src’) 会将 C:\Users\user\project 和 src 组合成一个绝对路径 C:\Users\user\project\src。
    这个路径是正确的,无论你在哪个操作系统上运行,都会生成正确的路径。

- 版本不同、模块冲突、完整安装等问题

这个情况就很复杂了,每个人当前系统都有差异,不太好分析。

比如你在vite.config.ts中配置如下:

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    },
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
  },
  // 编译时的配置
  build: {
    outDir: 'dist',
    assetsDir: 'static',
    rollupOptions: {
      input: 'src/main.ts',
    },
  },
  // 配置生产环境的目录,注意process必须配置了 npm i @types/node
  base: process.env.NODE_ENV === 'production' ? '/abc/' : '/',
})

此刻
如果你没有安装path,那path.resolve(__dirname, 'src')path就无法识别
如果你没有安装@types/node,那base: process.env.NODE_ENV === 'production' ? '/abc/' : '/',process就无法识别

只能先安装了

npm i path
npm i @types/node

其它情况你只能根据错误提示来安装了,如果实在不行我建议就删了重新部署一个干净的,再把项目代码放进去就行了。

- 书写错误

昨天为了写这篇文章,为了测试,在我现有代码上做了很多次改动,结果整个系统崩掉了,所以诸位兄弟姐妹一定要仔细看代码啊。

我的错误也是挺特殊的,正好与本文契合:

我的vite.config.ts写成这样了,@多了一个斜杠/

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vite.dev/config/
export default defineConfig({
  ...
  resolve: {
    alias: {
      '@/': path.resolve(__dirname, 'src')
    }
  },
  ...
})

然后死活整不出了。。。
这个问题解决也简单:

// 1. 方案一,删掉斜杠
...
export default defineConfig({
  ...
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  ...
})

// 2. 方案二,为了斜杠而斜杠
...
export default defineConfig({
  ...
  resolve: {
    alias: {
      '@/': `${path.resolve(__dirname, 'src')}/`
    }
  },
  ...
})

// 3. 方案三,之前已经写过了,这里重申一下:注意斜杠是在前面的
...
export default defineConfig({
  ...
  resolve: {
    alias: {
      '@': '/src'
    }
  },
  ...
})

通过这里的知识点,其实你已经可以写很多自己的别名了,比如你常用目录是在a/b/c,那就搞个别名叫abc呗~~

- vue声明

vscode开发typescript在引用vue时会提示找不到模块,错误提示大概如下:

`src/index.ts:4:31 - error TS7016: Could not find a declaration file for module '@/components/system/Register.vue'. 'E:/Projects/test/src/components/system/Register.vue' implicitly has an 'any' type.`

这时需要在环境配置中加入声明,一般用方法一就够了。

// src/vite-env.d.ts
/// <reference types="vite/client" />

// 定义 .vue 文件的模块声明,使 TypeScript 能够正确识别和处理 Vue 组件
// 1. 方法1:更适合项目中有复杂的组件配置需求,或者需要更精确的类型检查
declare module "*.vue" { 
    import { ComponentOptions } from 'vue'
    const componentOptions: ComponentOptions
    export default componentOptions
}


// 2. 方法2
declare module "*.vue" {
    import Vue from 'vue';
    export default Vue;  
}

// 注意,当自定义目录下有一些常规内容读不了,试试把这个目录也加进去,如下
// 定义路径别名的类型声明
declare module '@/xxxx/*' {
    import type { ComponentOptions } from 'vue'
    const componentOptions: ComponentOptions
    export default componentOptions
}

- 清空缓存重启服务

有时 TypeScript 缓存可能会导致配置更改没有生效。尝试清理缓存(删除 node_modulesdist_vite 等文件夹),然后重新构建。

cnpm install 

也可以重启vite服务

vite --force 

也可以重启vscode

- 文件后缀或目录完整度

这条不是本文的主题,本文主题是@别名,但会有同学因为这个问题导致出错,所以这里提一下。

还记得原生代码中有这句么?

// tsconfig.app.json
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]

目的很明确了,include 就相当于一个白名单,名单里有的文件类型才编译,那为什么有些人必须要写了这句才能解决@的问题呢?
不是tsconfig.app.json里配置了include么?

我猜,我猜啊,他们这一类在tsconfig.json的配置中没有里这个references

  // tsconfig.json
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],

因为他们的tsconfig.json里既没有include,又没有references引入tsconfig.app.json,所以出错了。

好了,现在知道为什么要加了不?参考下方代码。

"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]

我目前强迫症,喜欢把 src/**/*.d.ts 给加进去

- baseUrl基目录

compilerOptions中一般要把baseUrl加进去,"baseUrl": "." 的意思就是将项目的基目录为当前目录。

如果你的文件在D:/project/test/tsconfig.ts,那么.就意味着D:/project/test/是基目录,一切从此出发。

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

你可以注意一下这个位置有没有配置错误。

- 小经验

编译的时候两个命令都用一下最好

vite build
npm run build

这两者产生的错误警告有所不同,编译有时候npm没通过,vite却通过了。

总结

- 文字

  1. 因为是 vitetypescript两条线走路,所以有两处需要配置。
  2. 不管你怎么改,万变不离其宗:主旨就是让typescript调用的时候能看到你的完整路径!
  3. 完整路径由 根目录+目录名+文件名+文件后缀 组成,从这几点上去考虑,相信很快就能找到你自己代码的病症,开出准确的方子来解决。

- 代码

这里贴一下较为完整又精简够用的配置代码

// 1. vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vite.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    },
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
  },
  // 编译时的配置
  build: {
    outDir: 'dist',
    assetsDir: 'static',
    rollupOptions: {
      input: 'src/main.ts',
    },
  },
  // 配置生产环境的目录,注意process必须配置了 npm i @types/node
  base: process.env.NODE_ENV === 'production' ? '/abc/' : '/',
})

// 2.tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
    	"@/*": ["src/*"]
    }
  }
}

// 3. tsconfig.app.json
{
  "extends": "./tsconfig.json", // 继承自tsconfig.json

  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "Bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "preserve",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

如果对你有帮助,一键三连!
如果对你有帮助,一键三连!
如果对你有帮助,一键三连!

参考:
vue3+vite+typescript+setup组合式代码风格的模式开发的项目所需的一些必备内容,该安装安装,该创建创建
vue3+vite+ts 配置别名@报错找不到模块
【typescript - tsc 编译后路径问题/路径别名问题】
【解决90%】vue3+vite3+ts使用@alias路径别名爆红解决办法
Vue3解决“找不到模块“@/components/xxx.vue”或其相应的类型声明”


http://www.kler.cn/a/374329.html

相关文章:

  • MySQL数据库——常见的几种锁分类
  • 【操作系统】课程 3进程同步与通信 同步测练 章节测验
  • python报错ModuleNotFoundError: No module named ‘visdom‘
  • 五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测
  • 【信息系统项目管理师】高分论文:论信息系统项目的资源管理(移动警务通系统)
  • 学习笔记(C#基础书籍)-- C#高级应用
  • ssm026校园美食交流系统+vue(论文+源码)_kaic
  • 第三百零六节 Log4j教程 - Log4j日志级别
  • kubevirt cloud-init配置
  • 【解决方案】用git reset --hard重置了提交但是发现reset了一些本不该reset的内容,是不是寄了?
  • Android 圆形进度条CircleProgressView 基础版
  • Linux 程序地址空间
  • python读取视频并转换成gif图片
  • Python爬虫之urllib库详解
  • 【论文阅读笔记】VLP: A Survey on Vision-language Pre-training
  • 基于AI深度学习的中医针灸实训室腹针穴位智能辅助定位系统开发
  • mac-ubuntu虚拟机(扩容-共享-vmtools)
  • Oracle视频基础1.3.3练习
  • sql题库中常见问答
  • 【青牛科技】GC4921替代BD6921/罗姆在水泵、筋膜枪、吸尘器和电动工具中的应用
  • Django中分组查询(annotate 和 aggregate 使用)
  • 从0开始搭建一个生产级SpringBoot2.0.X项目(六)RestTemplate调用第三方接口
  • fastGPT添加知识库文本索引模型m3e一直处于索引中怎么解决
  • 练习LabVIEW第二十八题
  • SSM复习——M(MyBatis)二
  • VR动捕数据手套如何配合头显装置进行机器臂遥操作?