Skip to content

AutoImport for internal package in monorepo stops working if more than a few dependencies are installed #58709

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

Closed
michaelschufi opened this issue May 30, 2024 · 5 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@michaelschufi
Copy link

michaelschufi commented May 30, 2024

🔎 Search Terms

"intellisense not working", "auto import", "autoimport", "internal package", "monorepo internal"

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries "tsconfig.json Behavior" and other mentions of "import" "intellisense" or "module".

Versions checked

❯ every-ts switch main
HEAD is now at 5df3a107c0 Update dependencies (#58639)

❯ every-ts switch 5.5
HEAD is now at b574864abc Update LKG

❯ every-ts switch 5.1
HEAD is now at 6e4aa901f2 Bump version to 5.1.6 and LKG

❯ every-ts switch 4.8
HEAD is now at a614119c19 Bump version to 4.8.4 and LKG

❯ every-ts switch 5.5
HEAD is now at b574864abc Update LKG

❯ every-ts switch 5.3
HEAD is now at 3a36bec244 🤖 Pick PR #56626 (Directly copy only the index signat...) into release-5.3 (#56709)

❯ every-ts switch 5.2
HEAD is now at 9684ba6b0d Cherry-pick fix for cross-file inlay hints (#55476) to release-5.2 and LKG (#55487)

I've used VS Code Insiders so I don't have any excess extensions (just WSL).

Version: 1.90.0-insider (system setup)
Commit: c6e45e96a6b0fe94e0dae5b13ab4167d69ec9788
Date: 2024-05-28T10:48:57.080Z
Electron: 29.4.0
ElectronBuildId: 9593362
Chromium: 122.0.6261.156
Node.js: 20.9.0
V8: 12.2.281.27-electron.0
OS: Windows_NT x64 10.0.19045

⏯ Playground Link

No response

💻 Code

Reproduction Repo

See:
https://github.com/michaelschufi/repro-monorepo-tsserver-import

Internal Package
package.json

{
  "name": "@repo/ui",
  "version": "0.0.0",
  "private": true,
  "main": "./dist/index.js",
  "exports": {
    "./button": "./src/button.tsx",
    "./card": "./src/card.tsx",
    "./code": "./src/code.tsx",
    "./get-foo": "./src/get-foo.ts",
    "./get-foobar": "./src/get-foo-bar.ts"
  },
  "scripts": {
    "lint": "eslint . --max-warnings 0",
    "generate:component": "turbo gen react-component"
  },
  "dependencies": {
    "typescript": "*"
  },
  "devDependencies": {
    "@repo/eslint-config": "workspace:*",
    "@repo/typescript-config": "workspace:*",
    "@turbo/gen": "^1.12.4",
    "@types/node": "^20.11.24",
    "@types/eslint": "^8.56.5",
    "@types/react": "^18.2.61",
    "@types/react-dom": "^18.2.19",
    "eslint": "^8.57.0",
    "react": "^18.2.0",
    "typescript": "^5.3.3"
  }
}

get-foo.ts

export const getFoo = () => "foo"
export const getBar = () => "bar"

pnpx tsc --showConfig

{
    "compilerOptions": {
        "declaration": true,
        "declarationMap": true,
        "esModuleInterop": true,
        "incremental": false,
        "isolatedModules": true,
        "lib": [
            "es2022",
            "dom",
            "dom.iterable"
        ],
        "module": "nodenext",
        "moduleDetection": "force",
        "moduleResolution": "nodenext",
        "noUncheckedIndexedAccess": true,
        "resolveJsonModule": true,
        "skipLibCheck": true,
        "strict": true,
        "target": "es2022",
        "jsx": "react-jsx",
        "outDir": "./dist"
    },
    "files": [
        "./src/button.tsx",
        "./src/card.tsx",
        "./src/code.tsx",
        "./src/get-foo-bar.ts",
        "./src/get-foo.ts"
    ],
    "include": [
        "src",
        "src/get-foo-bar.ts"
    ],
    "exclude": [
        "node_modules",
        "dist"
    ]
}

App using internal package
package.json

{
  "name": "web",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint . --max-warnings 0"
  },
  "dependencies": {
    "@clerk/localizations": "^2.4.3",
    "@clerk/nextjs": "^5.1.2",
    "@tanstack/react-query": "^5.39.0",
    "@trpc/client": "11.0.0-rc.377",
    "@trpc/react-query": "11.0.0-rc.377",
    "@trpc/server": "11.0.0-rc.377",
    "@upstash/redis": "^1.31.3",
    "@repo/ui": "workspace:*",
    "lodash": "^4.17.21",
    "next": "^14.1.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "superjson": "^2.2.1",
    "zod": "^3.23.8"
  },
  "devDependencies": {
    "@next/eslint-plugin-next": "^14.1.1",
    "@repo/eslint-config": "workspace:*",
    "@repo/typescript-config": "workspace:*",
    "@types/eslint": "^8.56.5",
    "@types/lodash": "^4.17.4",
    "@types/node": "^20.11.24",
    "@types/react": "^18.2.61",
    "@types/react-dom": "^18.2.19",
    "eslint": "^8.57.0",
    "typescript": "^5.3.3"
  }
}

page.tsx

const Page = () => {
  // import suggestion for lodash is working
  const bar = sum(1, 2)

  // internal @repo/ui package exports don't work
  const foo = getFoo();
  const bar = getBar();

  return (
    // also not in jsx
    <Card>
      <h1>Hello, world!</h1>
      <p>Welcome to your new app!</p>
    </div>
  );
};

export default Page;

pnpx tsc --showConfig

{
    "compilerOptions": {
        "declaration": true,
        "declarationMap": true,
        "esModuleInterop": true,
        "incremental": false,
        "isolatedModules": true,
        "lib": [
            "es2022",
            "dom",
            "dom.iterable"
        ],
        "module": "esnext",
        "moduleDetection": "force",
        "moduleResolution": "bundler",
        "noUncheckedIndexedAccess": true,
        "resolveJsonModule": true,
        "skipLibCheck": true,
        "strict": true,
        "target": "es2022",
        "plugins": [
            {
                "name": "next"
            }
        ],
        "allowJs": true,
        "jsx": "preserve",
        "noEmit": true
    },
    "files": [
        "./next-env.d.ts",
        "./next.config.js",
        "./app/route.ts",
        "./app/layout.tsx",
        "./app/page.tsx"
    ],
    "include": [
        "next-env.d.ts",
        "next.config.js",
        "**/*.ts",
        "**/*.tsx",
        ".next/types/**/*.ts"
    ],
    "exclude": [
        "node_modules"
    ]
}

🙁 Actual behavior

Import suggestions for an internal package stop working if the number of installed dependencies grows too large. This already happens with as little as ~12 dependencies.

Reproduction

The reprodution repo is basically just Turborepo's basic example with a few dependencies added to showcase the autoimport failing.

pnpm dlx create-turbo@latest

from (Turborepo Getting Started).
It uses the strategy for internal packages outlined here Turborepo Internal Packages - which is already preconfigured in the example.

Initial Steps

  1. Clone the repo from https://github.com/michaelschufi/repro-monorepo-tsserver-import.
  2. Go to the apps/web folder.
  3. Install the dependencies using pnpm pnpm i
  4. Open apps/web/app/page.tsx and try to import-suggest the getFoo function.
  5. Observe it not working.

Observing the strange behavior

  1. Remove a few dependencies (e.g. the first 3, I didn't try removing next, react or react-dom)
  2. Rerun pnpm i to remove them from node_modules.
  3. Restart the TS Server in VS Code.
  4. Observe the import suggestion showing the internal package import.

You can remove any other dependencies (as shown in the video). It doesn't matter which ones. I tried the following

"@clerk/localizations": "^2.4.3", // <-- Group 1
"@clerk/nextjs": "^5.1.2", // <-- Group 1
"@tanstack/react-query": "^5.39.0", // <-- Group 1
"@trpc/client": "11.0.0-rc.377",
"@trpc/react-query": "11.0.0-rc.377",
"@trpc/server": "11.0.0-rc.377", // <-- Group 3, not shown in the video
"@upstash/redis": "^1.31.3", // <-- Group 3, not shown in the video
"@repo/ui": "workspace:*",
"lodash": "^4.17.21",
"next": "^14.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"superjson": "^2.2.1", // <-- Group 2
"zod": "^3.23.8" // <-- Group 2

Removing any ?random? group of packages, makes the import work.

2024-05-30.09-27-16.mp4

Note
The imports start showing up, if at least one file in the project has imported the file already.
E.g. page.tsx imports

import { getFoo } from "@repo/ui/get-foo";

then, all imports from "@repo/ui/get-foo" are available when triggering the suggestion. Even if we are in e.g. layout.tsx.

But the imports from other paths of the internal package e.g. "@repo/ui/get-foobar" are not.

🙂 Expected behavior

I expect the imports to be working regardless of how many dependencies I have installed.

Additional information about the issue

Possibly related issues:

Below are the tsserver logs. Note the following lines in the first one

Info 282  [10:21:34.464] AutoImportProviderProject: attempted to add more than 10 dependencies. Aborting.

https://gist.github.com/michaelschufi/638a0a9bc5bc8568c86b50a8c0c0e723

@RyanCavanaugh
Copy link
Member

Set "Include Package JSON Auto Imports" to "On" instead of "auto"

image

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Jun 6, 2024
@michaelschufi
Copy link
Author

Thank you so much! This seems to fix it 😀
Now, since it's not the default, I have to ask: What are the implications regarding performance if I enable that?

Maybe there could be some kind of whitelist, so we can include the internal packages in the VS Code settings?

@typescript-bot
Copy link
Collaborator

This issue has been marked as "Question" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 10, 2024
@NamGungGeon
Copy link

Set "Include Package JSON Auto Imports" to "On" instead of "auto"

image

You save my life... thanks... 😂

@baptisteArno
Copy link

OMG, that's a game changer!

This issue has been marked as "Question" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

I'd be curious to know that too

@microsoft microsoft locked as resolved and limited conversation to collaborators Sep 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

5 participants