Cannot find module 'xxx' or its corresponding type declarations

3,225 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

背景

根据 Vite 的介绍,利用@vitejs/create-app搭建项目,选择vue-ts模板

得package.json:

{
  "dependencies": {
    "vue": "^3.2.16"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^1.9.3",
    "typescript": "^4.4.3",
    "vite": "^2.6.4",
    "vue-tsc": "^0.3.0"
  }
}

vite.config.ts:

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

export default defineConfig({
  plugins: [vue()]
})

resolve配置

为了方便后续文件的引用,故配置别名alias、导入时省略的扩展名列表extensions

针对后者,Vite:resolve.extensions 介绍如下:

  • 类型:  string[]
  • 默认:  ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'] 导入时想要省略的扩展名列表。注意, 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会干扰 IDE 和类型支持。

其默认值满足需求,可跳过配置

安装 @types/node,添加alias配置

// ……
import { resolve } from 'path';
export default defineConfig({
  // ……
  resolve: {
    alias: {
      '@': resolve('src')
    },
  },
})

tsconfig

若根据上述配置,在.vue文件引入ts文件

<script lang="ts">
import { defineComponent, computed, onMounted } from "vue";
import { XXX } from "@/XXX/XXX";
export default defineComponent({})
</script>

报错:

Cannot find module 'xxx' or its corresponding type declarations. Vetur(2307)

即找不到模块“xxx”或其相应的类型声明

Q & A

vite.config.ts已配置alias无误,看看tsconfig.json的配置:

{
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

如果一个目录下存在一个tsconfig.json文件,那么它意味着这个目录是TypeScript项目的根目录。 tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。

可见,模板默认的tsconfig.json 关于ts路径别名的配置

查找资料,关于 TypeScript-模块解析文档:路径映射 的说明

设置baseUrl来告诉编译器到哪里去查找模块

TypeScript编译器通过使用tsconfig.json文件里的"paths"来支持这样的声明映射

所以,compilerOptions添加配置如下:

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

请注意"paths"是相对于"baseUrl"进行解析。 如果 "baseUrl"被设置成了除"."外的其它值,比如tsconfig.json所在的目录,那么映射必须要做相应的改变。

baseUrl若为"baseUrl": "src"

对应path修改为

"paths": {
   "@/*": ["./*"]
}

问题解决了

Last but not least

如有不妥,请多指教呀~