Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: vitest tsconfig should include all files under src #56

Merged
merged 2 commits into from Feb 16, 2022

Conversation

sodatea
Copy link
Member

@sodatea sodatea commented Feb 15, 2022

Credit to @xiaoxiangmoe

Fixes #55

Fixes the case that a .spec.ts file inside __test__/ imports a
module outside of __test__/ (a cross-(typescript-)project reference).

Note that VSCode language service looks for include patterns in references
top-down, so tsconfig.app.json must come before tsconfig.vitest.json
so that the src/** modules can get the most-accurate type hints.

The previous tsconfig only works for .vue imports in .spec.ts, which
seems to be a Volar bug. We shouldn't rely on that.
This fix is a more accurate configuration.

Vitest TypeScript projects created prior to create-vue 3.1.6 can apply the following patch to the projects:

From a37c33facf0e5db767bee33a71ad9e9fcd3cf373 Mon Sep 17 00:00:00 2001
From: Haoqun Jiang <haoqunjiang@gmail.com>
Date: Tue, 15 Feb 2022 21:50:07 +0800
Subject: [PATCH] fix: vitest tsconfig

---
 package.json         |  2 +-
 tsconfig.app.json    | 12 ++++++++++++
 tsconfig.json        | 14 ++++----------
 tsconfig.vitest.json |  9 +++------
 4 files changed, 20 insertions(+), 17 deletions(-)
 create mode 100644 tsconfig.app.json

diff --git a/package.json b/package.json
index ad9e16d..5138df6 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
     "build": "vue-tsc --noEmit && vite build",
     "preview": "vite preview --port 5050",
     "test:unit": "vitest --environment jsdom",
-    "typecheck": "vue-tsc --noEmit && vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
+    "typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
     "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
   },
   "dependencies": {
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 0000000..cdbea1d
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,12 @@
+{
+  "extends": "@vue/tsconfig/tsconfig.web.json",
+  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+  "exclude": ["src/**/__tests__/*"],
+  "compilerOptions": {
+    "composite": true,
+    "baseUrl": ".",
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  }
+}
diff --git a/tsconfig.json b/tsconfig.json
index 2551bf2..24f21b0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,18 +1,12 @@
 {
-  "extends": "@vue/tsconfig/tsconfig.web.json",
-  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
-  "exclude": ["src/**/__tests__/*"],
-  "compilerOptions": {
-    "baseUrl": ".",
-    "paths": {
-      "@/*": ["./src/*"]
-    }
-  },
-
+  "files": [],
   "references": [
     {
       "path": "./tsconfig.vite-config.json"
     },
+    {
+      "path": "./tsconfig.app.json"
+    },
     {
       "path": "./tsconfig.vitest.json"
     }
diff --git a/tsconfig.vitest.json b/tsconfig.vitest.json
index 5667568..d080d61 100644
--- a/tsconfig.vitest.json
+++ b/tsconfig.vitest.json
@@ -1,12 +1,9 @@
 {
-  "extends": "@vue/tsconfig/tsconfig.node.json",
-  "include": ["src/**/__tests__/*"],
+  "extends": "./tsconfig.app.json",
+  "exclude": [],
   "compilerOptions": {
     "composite": true,
-    "baseUrl": ".",
-    "paths": {
-      "@/*": ["./src/*"]
-    },
+    "lib": [],
     "types": ["node", "jsdom"]
   }
 }
-- 
2.35.1

Fixes vuejs#55

Fixes the case that a `.spec.ts` file inside `__test__/` imports a
module outside of `__test__/` (a cross-(typescript-)project reference).

Note that TypeScript looks for `include` patterns in `references`
top-down, so `tsconfig.app.json` must come before `tsconfig.vitest.json`
so that the `src/**` modules can get the most-accurate type hints.

The previous tsconfig only works for `.vue` imports in `.spec.ts`, which
seems to be a Volar bug. We shouldn't rely on that.
This fix is a more accurate configuration.
@sodatea
Copy link
Member Author

sodatea commented Feb 15, 2022

Cc @cexbrayat I think you might be interested in this fix, too…

@cexbrayat
Copy link
Member

Hmm interesting, that's what we were missing.

One question though: where does ts know that .spec.ts are included now? they are excluded in tsconfig.app.json and never included?

@sodatea
Copy link
Member Author

sodatea commented Feb 15, 2022

One question though: where does ts know that .spec.ts are included now? they are excluded in tsconfig.app.json and never included?

tsconfig.vitest.json now extends from tsconfig.app.json and overwrites exclude to []. So now the project (tsconfig.vitest.json) includes all files under src/**

So now:

  • When type-checking src/utils.ts, VSCode language service will search project reference, and the file is matched by the first tsconfig in the array, tsconfig.app.json, which is the same behavior as previous;
  • When type-checking src/__tests__/utils.spec.ts and it encounters the import for ../utils.ts, TypeScript would also use the ts configuration of utils.spec.ts for the imported module. Now that tsconfig.vitest.json includes all files under src, it no longer complains.

@xiaoxiangmoe
Copy link
Contributor

cypress-ct should also add vitest style tsconfig.app.json and tsconfig.cypress-ct.json.
If we don't add this:

  • file src/App.vue and file src/__tests__/utils.spec.ts will be matched in same tsconfig.
  • src/__tests__/utils.spec.ts have code import { mount } from '@cypress/vue', it will introduce global variables like it, describe and so on.
  • src/App.vue will be able to use global variable it, describe.

So we should split tsconfig to prevent global variables pollution.

@paparent
Copy link

Regarding global variable pollution, I managed to do this in my tsconfig.vitest.json:

{
  "extends": "@vue/tsconfig/tsconfig.node.json",
  "include": ["test-setup.ts", "src/**/__tests__/*"],
  "compilerOptions": {
    "composite": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },
    "types": ["node", "jsdom", "vitest/globals"]
  }
}

having vitest/globals in the types.

I like having different tsconfig files, but it gets confusing!

@sodatea
Copy link
Member Author

sodatea commented Feb 16, 2022

cypress-ct should also add vitest style tsconfig.app.json and tsconfig.cypress-ct.json.

Makes sense. Let me merge this PR and release a patch first. And I'll fix the Cypress-CT issue in another PR. At least it is still working…

@sodatea sodatea merged commit faabf60 into vuejs:main Feb 16, 2022
@sodatea sodatea deleted the fix-vitest-tsconfig branch February 16, 2022 06:34
sodatea added a commit to sodatea/create-vue that referenced this pull request Feb 18, 2022
do-adams added a commit to do-adams/talkee that referenced this pull request Apr 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Projects must list all files or use an 'include' pattern.ts(6307)
4 participants