Search code examples
typescriptintellij-ideawebstormmonorepovitest

IntelliJ IDEA - how to resolve the right global TypeScript types in NPM monorepo?


I have a NPM workspaces package that is using Vitest and my tsconfig.vitest.json looks like this:

{
  "$schema": "https://json.schemastore.org/tsconfig.json",
  "extends": "./tsconfig.app.json",
  "include": ["vite.config.ts", "vitest.config.mts", "tests/**/*.ts", "tests/**/*.js"],
  "exclude": [],
  "compilerOptions": {
    "composite": true,
    "outDir": "../../dist/out-tsc",
    "lib": [],
    "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"]
  }
}

In that package I have no Cypress or Jest installed, but I have Cypress in a neighbour package and Jest is one of the global peer dependencies. I don't want to manually import { vi, expect, test, describe } from 'vitest' - this is what "types": ["vitest/globals"] is for. But why does IntelliJ not resolve the right types, especially since only Vitest is installed locally, what can I do about it?

enter image description here

I am using typescript >= 5.0, so IntelliJ uses Vue Language Server (Volar) for compilation, but I think this only relevant for .vue files, not .spec.ts ?


Solution

  • Finally got it working. What helped for me was to make sure that the right framework is installed only in the right workspace. Then IntelliJ can automatically run whatever is available/installed.

    I had to use a hack to exclude Cypress and Jest (which are peer deps of various packages) to be installed at monorepo root. I have created a folder stub/cypress under root with the files package.json

    {
      "name": "cypress",
      "version": "0.0.0"
    }
    

    and index.d.ts

    export {};
    

    and added to my root' package.json dependencies

    "cypress": "file:stub/cypress",
    

    What this does is forcing a specific version of cypress (0.0.0) to be installed at root node_modules which does not meet the requirements of the workspace packages and which does not provide any actual interfaces to pollute the namespaces (hence the empty export). So my e2e package installed cypress locally after this.


    As for Jest, I removed the packages which had the peer deps, but I guess the same hack would also work there.

    Before using the hack, I have also tried to set

    "workspaces": { "nohoist": [ "cypress" ] }
    

    in my root package.json, but that did not work. If anyone knows why, please leave a comment.