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

Cannot find all references to shared lib's interfaces in VS Code #3106

Open
andriychuma opened this issue Jun 3, 2020 · 49 comments
Open

Cannot find all references to shared lib's interfaces in VS Code #3106

andriychuma opened this issue Jun 3, 2020 · 49 comments
Assignees
Labels

Comments

@andriychuma
Copy link

andriychuma commented Jun 3, 2020

Current Behavior

VS Code cannot discover references to shared entities that are defined in an nx lib. E.g. in a fresh new angular-nest nx monorepo VS Code cannot find all references to the Message interface defined in api-interfaces.ts. As a consequence, we cannot rename the entity throughout the workspace.

As far as I understood, it happens due to separate Typescript projects we have for apps and libs, and due to the fact, VS Code relies on the Typescript server while identifying references. This issue was described in this Typescript ticket and fixed within this one. It is not reproducible in WebStorm, which perhaps uses another way of reference discovery in a workspace.

That's rather not a bug of nx per se, but the initial configuration bug/improvement.

Expected Behavior

Find all references and Rename features should work in VS Code throughout all the nx monorepo Typescript subprojects.

To have it working, every nx shared lib should have the following Typescript options enabled:
E.g. in libs/api-interfaces/tsconfig.json

{
  ...
  "compilerOptions": {
    ...
    "composite": true,
    "declaration": true
  }
}

More details for the composite option is described here.

Also, we might want to reference lib projects from within application projects. However,
I don't know how beneficial it might be in nx monorepos since it's not required for fixing the current issue.
E.g. in apps/api/tsconfig.json:

{
  ..
  "references": [
      { "path": "../../libs/api-interfaces" }
  ]
}

Steps to Reproduce

  1. Run npx create-nx-workspace@latest test.
  2. Select angular-nest.
  3. Proceed further with any app name and stylesheet format.
  4. Open the workspace with VS Code.
  5. Open api-interfaces.ts (this file should be the first and the only file opened after running VS Code).
  6. Find references to the Message interface via Shift+F12 or Alt+Shift+F12.

Actual result: no reference found.

Environment

  @nrwl/angular : 9.3.0
  @nrwl/cli : 9.3.0
  @nrwl/cypress : 9.3.0
  @nrwl/eslint-plugin-nx : Not Found
  @nrwl/express : Not Found
  @nrwl/jest : 9.3.0
  @nrwl/linter : 9.3.0
  @nrwl/nest : 9.3.0
  @nrwl/next : Not Found
  @nrwl/node : 9.3.0
  @nrwl/react : Not Found
  @nrwl/schematics : Not Found
  @nrwl/tao : 9.3.0
  @nrwl/web : Not Found
  @nrwl/workspace : 9.3.0
  typescript : 3.8.3
@andriychuma andriychuma changed the title Cannot find all references to shared lib's entities in VS Code Cannot find all references to shared lib's interfaces in VS Code Jun 4, 2020
@Disane87
Copy link

Just stumbled upon this a few minutes ago. :-(

@vsavkin vsavkin added the scope: misc Misc issues label Jul 8, 2020
@vsavkin vsavkin added this to the next milestone Jul 8, 2020
@amayer42
Copy link
Contributor

amayer42 commented Sep 2, 2020

Thanks for posting this @andriychuma. I attempted your suggested workaround and had success with utilizing "Find all references" again. I'm curious though, do the typescript settings need to be made in each lib? I was able to make the change in the root tsconfig and it seems to work.

It seems like this should be fine since all of the individual lib tsconfig files inherit from the root right?

@amayer42
Copy link
Contributor

amayer42 commented Sep 4, 2020

Well, I noticed that changing this value at the root level does fix the "Find all references" issue, but it breaks lots of other things with imports, so it seems that you are correct that it would have to be done in all libs. Suppose I will have to spend a bit more time understanding the fix. Thanks again for posting though.

@vsavkin vsavkin removed this from the next milestone Sep 10, 2020
@Areen3
Copy link

Areen3 commented Sep 23, 2020

Hello,

I have this problem in my application based on monorepo nx

my example looks like this
my-app use -> my-library <- used by my - library-second

first case
close all files in VSC and reopen
and open file main.ts from my-app you see two referencs

  1. from app (1 file)
  2. from my-library (2 files)
  3. refenece from my-library-second don't show

second case
close all files in VSC and reopen
and open file index.ts from from my-library you see only one referencs

  1. from app (1 file) - not show
  2. from my-library (2 files)
  3. refenece from my-library-second don't show

third case
open from my-library-second
shows like firs case

I think the problem is this
VSC / TS does not analyze correctly when opening
organization of the project, whether or not
the method include, files, or refeneces was chosen

example is at:
https://github.com/Areen3/find-references
look at:
microsoft/vscode#80423
#3106

@andriychuma
Copy link
Author

andriychuma commented Oct 3, 2020

Yes @amayer42 , it looks like the composite flag should be introduced for libs only.
Also, after upgrading NX and Angular to 10, the workaround I described in the issue doesn't work. Some changes were introduced to TS configs, so that I needed to extend my fix. Here's what I came up with.

Workaround for NX 10

  1. Add a root level tsconfig.json. This file is the "solution" tsconfig as per the following recommendation. It is not involved in the build process. It looks like tsserver requires a root level tsconfig.json to correctly handle multiple related TS-projects (see the related issue Allow to specify the tsconfig.json filename explicitly  microsoft/vscode#12463).
{
  "extends": "./tsconfig.base.json",
  "files": [],
  "include": [],
  "references": [
    { "path": "./apps/<app1-name>" },
    { "path": "./apps/<app2-name>" },
    { "path": "./libs/<lib1-name>" },
    { "path": "./libs/<lib2-name>" }
  ]
}
  1. Add a root level tsconfig.base-lib.json, which will be the base configuration file for all the monorepo libraries. It will basically make our lib projects composite.
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "composite": true,
    "declaration": true
  }
}
  1. For every monorepo library modify the /libs/<lib-name>/tsconfig.json file. Inherit it from the root tsconfig.base-lib.json and remove files and include entries.

Before

{
  "extends": "../../tsconfig.base.json",
  "files": [],
  "include": [],
  "references": [
    {
      "path": "./tsconfig.lib.json"
    },
    {
      "path": "./tsconfig.spec.json"
    }
  ]
}

After

{
  "extends": "../../tsconfig.base-lib.json",
  "references": [
    {
      "path": "./tsconfig.lib.json"
    },
    {
      "path": "./tsconfig.spec.json"
    }
  ]
}
  1. Restart TS server or VS Code.

From now on, all the monorepo projects are automatically discoverable by TS server and you can find usages/refactor library's interfaces in VS Code.

Works in the following environment

  nx : Not Found
  @nrwl/angular : 10.2.1
  @nrwl/cli : 10.2.1
  @nrwl/cypress : 10.2.1
  @nrwl/eslint-plugin-nx : Not Found
  @nrwl/express : Not Found
  @nrwl/jest : 10.2.1
  @nrwl/linter : 10.2.1
  @nrwl/nest : 10.2.1
  @nrwl/next : Not Found
  @nrwl/node : 10.2.1
  @nrwl/react : Not Found
  @nrwl/schematics : Not Found
  @nrwl/tao : 10.2.1
  @nrwl/web : Not Found
  @nrwl/workspace : 10.2.1
  typescript : 3.9.7

@Areen3
Copy link

Areen3 commented Oct 5, 2020

Thanks @andriychuma

Thank you for your help...
I did as you wrote and it works 👍
however with minor problems
here is link to my example: https://github.com/Areen3/nx-reference

When you turn on references you shoud add to tsconfig.lib.json all files that your library depends on
image
and here is with importing files
image

Maybe you know a better way than to add all the imported files to tsconfig so that renaming works?
The point is that adding all imported libraries to tsconfig.lib.json as well will be a pain.

@andriychuma
Copy link
Author

@Areen3 , I see you made your apps composite by extending /apps/<app-name>/tsconfig.json from /tsconfig.base.lib.json. Actually, you might want to use /tsconfig.base.lib.json as a base config for your libs only /libs/*. For /apps/* use the regular one /tsconfig.base.json.

Areen3 pushed a commit to Areen3/nx-reference that referenced this issue Oct 7, 2020
@Areen3
Copy link

Areen3 commented Oct 7, 2020

Thanks
You have right, I corrected it

Do You complete the include area in your applications (in tsconfig)?

I found out about completing references in tsconfig.json
it helps only VSC to avoid underlining aliases
however, if we want to build app, missing include section causes compilation errors because not all files are in project directory

According to me, it is quite onerous, I have about 30 libraries (at the moment) and I will have about 100
so listing them all in the include part will be a pain
Please write down how you deal with the rename option - use include to rename or do something else???

I have a second question, I noticed that monorepo NX imports do not always fit well (by VSCode)
my settings.json:
"typescript.preferences.importModuleSpecifier": "non-relative",

I tried the original importer with VSCode, AutoImport, TypeScriptImport
with different configurations
and in 20% of cases, the imports do not use aliases and look like this:
image

I was looking on the internet, the problem is arising
but I failed to find a sufficient solution
do you have a suggestion, it would be very useful

thank you very much

@johannesschobel
Copy link
Contributor

Dear @andriychuma ,

I just stumbled upon the exact same issue, however, in another context: I noticed, that my VSCode was not able to "update imports after renaming" anymore, and i was buffled by this fact.

  • I tried another (brand new) dummy workspace with the nest preset and still got the same issue. When moving a file, the imports were not updated. 🔴
  • I then created an empty workspace and just created 2 files where one was imported in the other and renamed / moved it. worked properly. 🟢
  • Then i added one @nrwl/workspace:lib to this empty workspace and it stopped working. 🔴
  • Naturally, the issue must be with the library or the generated workspace file. When i removed the library (but let the workspace file untouched), it worked again. 🟢

Then this got me hooked and i was thinking this must be some joke 🤔

I then inspected the tsconfig files from the generated library and found, that the main one (tsconfig.json) has this empty files and includes arrays, which are then "overwritten" by the tsconfig.lib.json and tsconfig.spec.json files respectively.

When i removed those empty arrays, i got errors, that the other 2 files must have the composite: true flag, otherwise it wont work.

Adding the latter solved the issue for me - and i can refactor again 😆

Dear @vsavkin , @FrozenPandaz , may someone look into this issue? i can confirm the issue described by @andriychuma as i ran into this issue myself today. It costed me about 5 hours, until i found the solution!

All the best

@johannesschobel
Copy link
Contributor

Dear @andriychuma ,

thank you for your proposed solution in comment ( #3106 (comment) ), however, this does not work for me (see issue with updating file imports).

Do you have, by chance, the same issue? Does your solution work for the latest NX?

All the best

@drewwiens
Copy link

drewwiens commented Feb 3, 2021

Since the workarounds in this thread do seem to work, but don't compile, at least in Nx 11.0, I made a CLI tool to quickly apply and un-apply them to a workspace: https://www.npmjs.com/package/farp

@quolpr
Copy link

quolpr commented Feb 15, 2021

I don't recommend that solution to anyone, it is pretty radical, but what I made(tested only on react repos). I deleted all tsconfig*.json files from all dirs and made just one tsconfig.json in root dir:

{
  "compileOnSave": false,
  "files": [
    "./node_modules/@nrwl/react/typings/cssmodule.d.ts",
    "./node_modules/@nrwl/react/typings/image.d.ts"
  ],
  "include": [
    "**/*.js",
    "**/*.jsx",
    "**/*.ts",
    "**/*.tsx"
  ],
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "rootDir": ".",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es2015",
    "module": "esnext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "<your-lib>": ["libs/<your-lib>/src/index.ts"]
    },
    "incremental": true,
    "jsx": "react",
    "allowJs": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  },
  "exclude": [
    "node_modules",
    "tmp", 
    "**/*.spec.ts", 
    "**/*.spec.tsx", 
    "**/*.stories.tsx", 
    "dist",
    "apps/<your-app>-e2e", 
    "apps/<your-other-app>-e2e", 
  ]
}

And then inside of each lib/app new tsconfig.app.json/tsconfig.lib.json file:

{
  "extends": "../../tsconfig.json"
}

As a benefit, it also solves #3664 (you can make a type check command that will check types of all your source code. It is good for CI at least) with just one command:

tsc -p ./tsconfig.json --noEmit

@quolpr
Copy link

quolpr commented Feb 15, 2021

NOTE: this is a solution only for NX 11, and as I suppose you may lose upgradeability to the future NX versions

@tomtaz
Copy link

tomtaz commented Feb 24, 2021

Hello there,

Here is my fix that addresses everything and breaks nothing that I'm aware of. Ping me otherwise.
I would be interested to know about the performance impact on build time for large repos with many apps/libs.

In tsconfig.base.json, add this:

{
  "includes": ["**/*.ts"]
}

Replace the tsconfig.json of every library by:

{
  "extends": "../../tsconfig.base.json"
}

@johannesschobel
Copy link
Contributor

Dear @tomtaz ,

i think, a better solution is as follows:

  1. leave your tsconfig.base.json as is
  2. in every app / lib folder look for the tsconfig.json file and adapt as follows:
{
  "extends": "../../tsconfig.base.json",
+  // "files": [],
+  "include": ["**/*.ts"],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.spec.json"
    }
  ]
}

i.e., comment out the files array and add **/*.ts to the include.
This will have the same effect, but follows the nrwl approach more accurately, i guess.

@tomtaz
Copy link

tomtaz commented Feb 27, 2021

Hi @johannesschobel ,

I tried what you proposed, it does not solve every issue I have.

  • X Find all references does not work
  • X Import suggestions does not work
  • V Auto update import of moved files works

@johannesschobel
Copy link
Contributor

Maybe @vsavkin or @FrozenPandaz can join and provide feedback and maybe a hotfix for nrwl/nx. This issue may be a serious problem in the long run. You can also take a look at microsoft/vscode#4508 where i reported similar problems / issues with additional information

@github-actions
Copy link

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
If we missed this issue please reply to keep it active.
Thanks for being a part of the Nx community! 🙏

@github-actions github-actions bot added the stale label Mar 29, 2021
@drewwiens
Copy link

If we missed this issue please reply to keep it active.

Bump

@github-actions github-actions bot removed the stale label Mar 29, 2021
@javieroc
Copy link

I was following the tutorial from nx docs and vscode not recognize @myorg/data shared lib, someone had this issue?

Thanks!

@alvaromartmart
Copy link

This is still an issue 😕 and it really breaks the DX while refactoring code (i.e. I cannot just simply rename properties/methods etc. that might be shared used outside a lib, I have to rely on search & replace to be sure)

@github-actions github-actions bot removed the stale label Mar 18, 2022
@itspers
Copy link

itspers commented Jun 4, 2022

All this modern web-development is pretty sad. On real world project with dozen apps and 50 shared libs VScode is basically acts as text editor, spending seconds each time to understand where to go with ctrl+click, and its not only TS/JS, its same for Angular - also spinning CPU each time you hover something or ctrl+click...

@vsavkin just uses IDEA, jetbrains IDEs have no such problems, but they dont have proper NX extension - existing 3rd party one breaks after each update, nowdays for example custom generators not working...

There was hope that this exponential grow of VSCode will make it as powerfull as IDEA in few years, but majory of users using it to write Hello-world apps with React and filming Youtube videos - there is just no demand to fix this.

I think best option is to switch to become some Unity or Android developer to fix this problem 😁

@normtronics
Copy link

@FrozenPandaz Any updates on this?

@itPiligrim
Copy link

Up ↑

1 similar comment
@ljacho
Copy link

ljacho commented Oct 24, 2022

Up ↑

@evelant
Copy link

evelant commented Nov 23, 2022

@andriychuma is this still an issue? I just stumbled upon this issue and it's making me question whether I should continue to work on integrating nx into my existing repo. If it's going to break TS dev experience (which is already poor without nx) then I'll have to rethink things.

@johannesschobel
Copy link
Contributor

which is already poor without nx

Seriously? The TS Dev Experience is one of the smoothest in my opinion..

@andriychuma
Copy link
Author

andriychuma commented Nov 28, 2022

@evelant, the issue is not fixed yet, but I don't think it should be a pitfall on your Nx monorepo journey. Even being fixed, it's quite likely you wouldn't avoid additional manual adjustments. A multi-project TypeScript repository with project interdependencies should have a properly configured dependency tree for IntelliSense/TSServer to work properly in VS Code. When you add a new app or lib into your monorepo, Nx CLI doesn't know its future relationships with other apps, that's where manual intervention might be needed.

I took the latest Nx v15.2.1 and tried to identify the config adjustments needed for IntelliSense to work fine. There might be some edge cases that I didn't test, but the following tweaks fix the issue.

I created a fresh new monorepo and added three projects:

  • client, an Angular application
  • server, a NestJs application
  • shared, a library for sharing stuff between client and server

Here's the initial structure of tsconfigs:

├── apps
│   ├── client
│   │   ├── tsconfig.app.json
│   │   ├── tsconfig.editor.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.spec.json
│   ├── server
│   │   ├── tsconfig.app.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.spec.json
├── libs
│   ├── shared
│   │   ├── tsconfig.json
│   │   ├── tsconfig.lib.json
│   │   ├── tsconfig.spec.json
├── tsconfig.base.json

Then I tweaked them a little bit and added a solution-like tsconfig in the root folder:

├── apps
│   ├── client
│   │   ├── tsconfig.app.json
              "compilerOptions": {
                "composite": false, // added
                "declaration": false // added
              },
│   │   ├── tsconfig.editor.json
│   │   ├── tsconfig.json
              "include": ["**/*.ts"], // modified
              // "references": [...], // removed whole section
              "compilerOptions": {
                "composite": true, // added
                "declaration": true // added
              },
│   │   ├── tsconfig.spec.json
│   ├── server
│   │   ├── tsconfig.app.json
              "compilerOptions": {
                "composite": false, // added
                "declaration": false // added
              },
│   │   ├── tsconfig.json
              "include": ["**/*.ts"], // modified
              // "references": [...], // removed whole section
              "compilerOptions": {
                "composite": true, // added
                "declaration": true // added
              },
│   │   ├── tsconfig.spec.json
├── libs
│   ├── shared
│   │   ├── tsconfig.json
              "include": ["**/*.ts"], // modified
              // "references": [...], // removed whole section
              "compilerOptions": {
                "composite": true, // added
                "declaration": true // added
              },
│   │   ├── tsconfig.lib.json
│   │   ├── tsconfig.spec.json
├── tsconfig.base.json
├── tsconfig.json (added the solution tsconfig file)
      {
        "references": [
          {
            "path": "apps/client/tsconfig.json"
          },
          {
            "path": "apps/server/tsconfig.json"
          }
        ]
      }

Now if you export an interface from the shared lib and use it in client and server, it will be properly discoverable by IntelliSense from any place.

@evelant
Copy link

evelant commented Nov 28, 2022

@andriychuma Thanks for the details! I actually ended up using https://github.com/google/wireit with pnpm workspaces and that provides me with everything I need for now. I don't think I really need the extra capabilities of nx at the moment. Wireit does a fantastic job of running my build tasks in parallel with caching and has very simple configuration.

FWIW I ended up needing a similar tsconfig setup, nx or not. I think that's just how ts generally ends up needing to be configured to work in a monorepo layout.

@kbihler
Copy link

kbihler commented Dec 9, 2022

There is a possible gotcha hidden in your project tsconfig.json file that has not been mentioned here. If you have set baseUrl then VS code cannot find your module in libs (typescript error). This results in the problem described.

"compilerOptions": {
    "baseUrl": ".",
}

Remove it and it works again. If you do your internal imports without path navigation

import { thing } from 'components/thing';

then you will need to add it back in

import { thing } from '../components/thing'; 

Hope that helps someone!

@div-cowboy
Copy link

div-cowboy commented Jan 10, 2023

Ran into this problem, and figured out my issue. Context: I'm re-platforming an old Next build to a new Next environment using Typescript and NX, but I have some libraries from the old build with components in regular js/jsx. The solve was updating allowJs to be true, and updating includes to: ["**/*.js"] in my library's ts.config

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "allowJs": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": false
  },
  "files": [],
  "includes": ["**/*.js"],
  "references": [
    {
      "path": "./tsconfig.lib.json"
    },
    {
      "path": "./tsconfig.spec.json"
    }
  ],
  "extends": "../../../../tsconfig.base.json"
}

@github-actions
Copy link

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
If we missed this issue please reply to keep it active.
Thanks for being a part of the Nx community! 🙏

@github-actions github-actions bot added the stale label Jul 10, 2023
@BurningEnlightenment
Copy link

AFAICT this still hasn't been fixed.

@github-actions github-actions bot removed the stale label Jul 11, 2023
@EthanML
Copy link
Contributor

EthanML commented Jul 19, 2023

This still seems like a very pressing issue - if it's not something that can/will be "fixed" by Nx itself, is it possible that a recommended approach to TS config could be published in the docs somewhere so that Nx users making use of VS Code (presumably most of them?) aren't losing core basic Typescript functionality like Rename?

How are the Nx team working around this in their projects?

@jaysoo
Copy link
Member

jaysoo commented Oct 30, 2023

AN issue is opened here, and we're getting help from the vscode folks on it. microsoft/TypeScript#56268

@tsopeh
Copy link

tsopeh commented Dec 4, 2023

The microsoft/TypeScript#56268 issue got closed ("Working as Intended"). We need some official Nx docs/resource we can follow in order to solve this problem

@alfaproject
Copy link
Contributor

Has anyone tried the solution suggested here? https://jakeginnivan.medium.com/using-typescript-project-references-in-nx-b3462b2fe6d4

@zilia-gmethot
Copy link

This is still a major issue for me. It is impossible to find consumers of let's say a function that is part of a shared Nx library by using the Find all references feature of the TypeScript langage server used by VS code, which is by far the most used IDE in web development. Want to rename a symbol? Now all code that depends on it is broken because it wasn't updated. And having to search by string matching is really inefficient and prone to error.

Has anyone found a solution yet?

@AaronConlon
Copy link

The microsoft/TypeScript#56268 issue got closed ("Working as Intended"). We need some official Nx docs/resource we can follow in order to solve this problem

2024-04-15 SOS

@FrozenPandaz FrozenPandaz assigned JamesHenry and unassigned jaysoo May 14, 2024
@david-gettins
Copy link

I have a similar issue from test files in an nx/next project. The non-spec files can find the lib at it's tsconfig path but not spec files...

@david-gettins
Copy link

david-gettins commented Jul 20, 2024

The issue in my case was that the nx/next generated app set up it's tsconfigs like so:

-> tsconfig.json
-> tsconfig.spec.json

As soon as I changed it to match other nx generated projects I start to get lib paths being found in spec files i.e.

-> tsconfig.app.json
-> tsconfig.json
-> tsconfig.spec.json

Not 100% sure, but it seems to be related to fact the app tsconfig (was tsconfig.json, now tsconfig.app.json) has includes and excludes defined. What is now my project's tsconfig.json has no include and exclude defined, but now has references.

@Akuket
Copy link

Akuket commented Sep 24, 2024

Hello,

Any news on this topic ?

@rbmdotdev
Copy link

Also a problem for us, lots of import error noise and getting worse, seems silly that after 4 years there is not any nx documentation around this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests