You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+TypeScript+ESLint导入组件缺失声明文件问题求助

Vue3 + TypeScript 项目导入嵌套目录组件的类型声明报错

我用Vue3和TypeScript搭建了新项目,并且接入了ESLint。当我导入@/components/UI/LoadingPage.vue组件时,编辑器弹出错误:
Vue: Could not find a declaration file for module @/components/UI/LoadingPage.vue

组件本身可以正常渲染,但编辑器把路径解析成了src/components/UI/LoadingPage.vue.js;奇怪的是在router.ts里导入这个组件完全没问题,而且把组件移到components根目录后,报错就消失了。

以下是我的项目配置文件:

eslintrc.cjs

root: true,
env: {
    node: true,
},
extends: [
    "plugin:vue/vue3-strongly-recommended",
    "plugin:import/recommended",
    "plugin:import/typescript",
],
settings: {
    "import/resolver": {
        typescript: {}
    },
},
parserOptions: {
    "ecmaVersion": "latest",
    "sourceType": "module",
    "parser": "@typescript-eslint/parser",
},
rules: {
    "vue/html-self-closing": ["error", {
        "html": {
            "void": "never",
            "normal": "always",
            "component": "always"
        },
        "svg": "always",
        "math": "always"
    }],
    "indent": [
        "error",
        "tab"
    ],
    "vue/html-indent": [
        "error",
        "tab",
        {
            attribute: 1,
            baseIndent: 1,
            closeBracket: 0,
            alignAttributesVertically: true,
            ignores: []
        }
    ],
    'no-tabs': 0,
    'vue/max-attributes-per-line': ['error', {
        'singleline': {
            'max': 3
        },
        'multiline': {
            'max': 1
        }
    }],
    'import/no-extraneous-dependencies': ['error', {'includeInternal': true, 'includeTypes': true}],
    'vue/order-in-components': ['error', {
        order: [
            'el',
            'name',
            'key',
            'parent',
            'functional',
            ['delimiters', 'comments'],
            ['components', 'directives', 'filters'],
            'extends',
            'mixins',
            ['provide', 'inject'],
            'ROUTER_GUARDS',
            'layout',
            'middleware',
            'validate',
            'scrollToTop',
            'transition',
            'loading',
            'inheritAttrs',
            'model',
            ['props', 'propsData'],
            'emits',
            'setup',
            'asyncData',
            'data',
            'fetch',
            'head',
            'computed',
            'watch',
            'watchQuery',
            'LIFECYCLE_HOOKS',
            'methods',
            ['template', 'render'],
            'renderError'
        ]
    }],
    "vue/no-irregular-whitespace": ["error", {
        "skipStrings": true,
        "skipComments": false,
        "skipRegExps": false,
        "skipTemplates": false,
        "skipHTMLAttributeValues": false,
        "skipHTMLTextContents": false
    }],
    "vue/component-definition-name-casing": ["error", "PascalCase"],
    "vue/match-component-file-name": ["error", {
        "extensions": ["vue"],
        "shouldMatchCase": false
    }],
    "vue/no-dupe-keys": ["error", {
        "groups": []
    }],
    "vue/component-name-in-template-casing": ["error", "kebab-case", {
        "registeredComponentsOnly": true,
    }],
    'comma-dangle': ['error', {
        arrays: 'never',
        objects: 'never',
        imports: 'never',
        exports: 'never',
        functions: 'never'
    }],
    'linebreak-style': ["error", "unix"],
    'no-console': 'error',
    'no-debugger': 'error',
    'arrow-parens': ['error', 'as-needed'],
    'no-plusplus': 'off',
    'constructor-super': 'off',
    "no-mixed-operators": [
        "error",
        {
            "groups": [
                ["+", "-", "*", "/", "%", "**"],
                ["&", "|", "^", "~", "<<", ">>", ">>>"],
                ["==", "!=", "===", "!==", ">", ">=", "<", "<="],
                ["&&", "||"],
                ["in", "instanceof"]
            ],
            "allowSamePrecedence": true
        }
    ],
    'import/extensions': 'off',
    'import/prefer-default-export': 'off',
    'no-unused-expressions': 'error',
    'no-param-reassign': 'off',
    'prefer-destructuring': ["error", {
        "array": true,
        "object": true
    }, {
        "enforceForRenamedProperties": false
    }
    ],
    'no-bitwise': ['error', {allow: ['~']}],
    'no-unused-vars': ['error', {argsIgnorePattern: '^_'}],
    'max-len': ['error', {code: 140}],
    'object-curly-newline': ['error', {
        ObjectExpression: {multiline: true, consistent: true},
        ObjectPattern: {multiline: true, consistent: true}
    }],
    'lines-between-class-members': ['error', 'always', {exceptAfterSingleLine: true}]
}

vite.config.ts

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { fileURLToPath, URL } from 'url';

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

tsconfig.json

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

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,

    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

内容的提问来源于stack exchange,提问作者Maks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:14:56