Search code examples
typescriptvue.jsvite

How to get Vite, TS, and Vue to properly work in vs-code


I have spent a few days trying to figure out this problem and have read every source I can find.

I am currently working on a Vue-3 project that uses typescript. VSCode is giving me the error "Cannot find module '' or its corresponding type declarations.ts(2307)" However, my code compiles just fine (as in I am able to do development). VSCode gives me this error for any source I import using an alias. I am using the following packages:

Vue: ^3.2.47
"@rushstack/eslint-patch": "^1.3.3",
    "@types/cypress": "^1.1.3",
    "@types/jsdom": "^21.1.1",
    "@types/node": "^20.5.1",
    "@vitejs/plugin-vue": "^4.3.1",
    "@vue/eslint-config-prettier": "^8.0.0",
    "@vue/eslint-config-typescript": "^11.0.3",
    "@vue/test-utils": "^2.4.1",
    "@vue/tsconfig": "^0.4.0",
    "autoprefixer": "^10.4.15",
    "cypress": "^12.17.4",
    "eslint": "^8.47.0",
    "eslint-plugin-cypress": "^2.14.0",
    "eslint-plugin-vue": "^9.17.0",
    "jsdom": "^22.1.0",
    "npm-run-all": "^4.1.5",
    "postcss": "^8.4.28",
    "prettier": "^3.0.2",
    "start-server-and-test": "^2.0.0",
    "tailwindcss": "^3.3.3",
    "typescript": "^5.1.6",
    "vite": "^4.4.9",
    "vitest": "^0.34.2",
    "vue-tsc": "^1.8.8"

My tsconfig.json:

    {
  "files": [],
  "include": ["./src/**/*", "./ts-types/**/*", "./src/**/*.vue"],
  "exclude": ["node_modules", "dist", "build", "coverage", "tests", "test", "cypress"],
  "references": [
    {
      "path": "./tsconfig.node.json"
    },
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.vitest.json"
    }
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@assets/*": ["src/assets/*"],
      "@stores/*": ["src/stores/*"],
      "@shared/*": ["src/components/shared/*"],
      "@customTypes/*": ["/ts-types/types/*"],
      "@interfaces/*": ["/ts-types/interfaces/*"],
      "@customEnums/*": ["/ts-types/customEnums/*"]
    },
    "alwaysStrict": true,
    "verbatimModuleSyntax": false,
    "types": ["vite/client"]
  },
  "forceConsistentCasingInFileNames": true
}

tsconfig.app.json:

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
  "exclude": ["src/**/__tests__/*"],
  "compilerOptions": {
    "composite": true
  }
}

tsconfig.node.json:

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": [
    "vite.config.*",
    "vitest.config.*",
    "cypress.config.*",
    "playwright.config.*",
    "ts-types/**/*",
    "src/**/*",
    "src/**/*.vue"
  ],
  "compilerOptions": {
    "composite": true,
    "types": ["node"]
  }
}

tsconfig.vitest.json:

{
  "extends": "./tsconfig.app.json",
  "exclude": [],
  "include": ["./src/**/*", "./ts-types/**/*", "./src/**/*.vue"],
  "compilerOptions": {
    "composite": true,
    "lib": [],
    "types": ["node", "jsdom"],
    "baseUrl": "./",
    "paths": {
      "@/*": ["./src/*"],
      "@assets/*": ["./src/assets/*"],
      "@stores/*": ["./src/stores/*"],
      "@shared/*": ["./src/components/shared/*"],
      "@customTypes/*": ["./ts-types/types/*"],
      "@interfaces/*": ["./ts-types/interfaces/*"],
      "@customEnums/*": ["./ts-types/customEnums/*"]
    }
  }
}

vite.config.ts:

import { fileURLToPath, URL } from 'node:url'

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

const version = '0.0.0'

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '')

  return {
    plugins: [vue()],
    build: {
      rollupOptions: {
        output: {
          entryFileNames: `[name].${version}.js`,
          chunkFileNames: `[name].${version}.js`,
          assetFileNames: `[name].${version}.[ext]`
        }
      }
    },
    resolve: {
      alias: [
        { find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) },
        {
          find: '@assets',
          replacement: fileURLToPath(new URL('./src/assets', import.meta.url))
        },
        {
          find: '@stores',
          replacement: fileURLToPath(new URL('./src/stores', import.meta.url))
        },
        {
          find: '@shared',
          replacement: fileURLToPath(new URL('./src/components/shared', import.meta.url))
        },
        {
          find: '@customTypes',
          replacement: fileURLToPath(new URL(`./ts-types/types`, import.meta.url))
        },
        {
          find: '@interfaces',
          replacement: fileURLToPath(new URL(`./ts-types/interfaces`, import.meta.url))
        },
        {
          find: '@customEnums',
          replacement: fileURLToPath(new URL(`./ts-types/customEnums`, import.meta.url))
        }
      ]
    }
  }
})

vitest.config.ts:

import { fileURLToPath } from 'node:url';
import { mergeConfig } from 'vite';
import { configDefaults, defineConfig } from 'vitest/config';
import viteConfig from './vite.config';

export default mergeConfig(
  viteConfig as any,
  defineConfig({
    test: {
      environment: 'jsdom',
      exclude: [...configDefaults.exclude, 'e2e/*'],
      root: fileURLToPath(new URL('./', import.meta.url))
    }
  })
);

My volar select typescript version is set to "use workspace version: 5.1.6" . I have disabled "TypeScript and JavaScript Language Features" for the workspace.

I have tried adding a shim to my src folder and a shim and it gets rid of the error "cannot find module . . ." for *.vue files but if I use this method for interfaces or types that are aliased, then it will cause other errors. Thus, the shim suggestion will not solve my issue.

Does anyone have any suggestions on how to get TS to work properly? When I run "vue-tsc --noEmit -p tsconfig.vitest.json --composite false" it says I have 1000 errors in my project. However, almost all of them have to deal with importing files. Thus, the configuration of TS has basically made TS counterproductive and cumbersome. Any assistance would be greatly appreciated.


Solution

  • in your tsconfig.json try to replace your include with this one here:

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