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

Auto imports from referenced project not working until already imported once in project #39778

Open
EKashpersky opened this issue Jul 17, 2020 · 28 comments
Labels
Cursed? It's likely this is extremely difficult to fix without making something else much, much worse Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Milestone

Comments

@EKashpersky
Copy link

EKashpersky commented Jul 17, 2020

TS Template added by @mjbvz

TypeScript Version: 4.0.0-dev.20200727

Search Terms

  • angular
  • project references
  • auto imports

  • VSCode Version: 1.47.2
  • OS Version: Mac OS Catalina 10.15.5

Steps to Reproduce:

I have an Angular project, and just 1 of the files don't have a proper suggestion support in it.
Same happens when I create a file via plus sign from the side bar.
VSCode doesn't suggest "obvious(necessary)" things, quite the contrary happens:
it suggests everything else what's available, but not what I need and not what really exists in the project.

Also, when I try to import environment object with 'src/environments/environment',
it doesn't seem to know about src folder(project_name/src).
Although it already works this way for all the other files in the project.

Cache cleaning && insiders build didn't help out, no errors in debug console and I couldn't find any useful tsserver logs.
Although I can send if necessary.
Having 3.9.7 TS

Does this issue occur when all extensions are disabled?: Yes

@EKashpersky
Copy link
Author

For me it's not a problem even for a session with screen sharing, if anything

@mjbvz
Copy link
Contributor

mjbvz commented Jul 20, 2020

Can you share the project that causes this?

@EKashpersky
Copy link
Author

Yup!
Working on it

@EKashpersky
Copy link
Author

@mjbvz here you go

https://github.com/EKashpersky/mentare-102740-0
https://github.com/EKashpersky/mentare-102740-1

Each project has // environment line their src/app/app.component.ts, and when I uncomment the line and do command + space to have suggestions list pop up, for 102740-0 I get nothing or allowedNodeEnvironmentFlags function from 'process' package, if npm -i has been ran.

Works fine for 102740-1.

@mjbvz mjbvz transferred this issue from microsoft/vscode Jul 27, 2020
@mjbvz
Copy link
Contributor

mjbvz commented Jul 27, 2020

Looks like src/environments/environment.ts and app.component.ts are part of separate tsconfig projects, although both of these project are both referenced by tsconfig.json.

Moving upstream to get the TypeScript team's feedback on this behavior

@mjbvz mjbvz removed their assignment Jul 27, 2020
@mjbvz mjbvz changed the title Corrupted autocomplete Auto imports not working with project references Jul 27, 2020
@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jul 29, 2020
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.1.0 milestone Jul 29, 2020
@cevek
Copy link

cevek commented Sep 18, 2020

Confirm this issue. My composite projects referenced to each other don't auto import names from other connected projects

@zerkalica
Copy link

zerkalica commented Sep 18, 2020

Confirm. Autocomplete not working via references in tsconfig.json

demo: https://github.com/zerkalica/ts-references-autoimport-bug/tree/autoimport-no-ref

Currently autocomplete works only with includes (cpu eating on big projects) and via "types" in package.json.

Autocomplete doesn't works with direct imports (without types in package.json)

@webberwang
Copy link

Project reference imports like using @ namespace only works when there is already an import using that path. Otherwise it defaults to relative paths. Very annoying to have to manually type it out initially everytime

@theomessin
Copy link

Any update on this? How can Microsoft's IDE (written in TypeScript!) not properly support Microsoft's TypeScript 🤯

@divillysausages
Copy link

This might seem like a stupid suggestion, and it's probably super complex behind the scenes, but if it works by using the types property of package.json as @zerkalica mentioned, what's preventing TypeScript from treating project references as if they were normal npm install --save dependencies when it comes to resolving types/classes?

@andrewbranch
Copy link
Member

TypeScript doesn’t resolve types from “normal” node_modules dependencies without the types or exports package.json fields or an index.d.ts at the root. The issue is that linked project references aren’t treated specially at all for auto-imports. The request is to do something extra, more than we would do for “normal” dependencies.

@bradedelman
Copy link

any update here? my team would really like this issue fixed.

@andrewbranch
Copy link
Member

The update was that it’s pretty hard to fix and almost nobody was interested enough to try my experimental branch for the 3 weeks that it was open. As far as I know the only issue here is that project references for Project B aren’t automatically made available for auto-import in Project A before there is an existing import that brings types from B into A. This is actually how all node_modules auto imports worked for many years before there was sufficient demand for us to write a (pretty complicated) feature to proactively pull in any package.json dependencies. Today, that feature also works for project references that are linked through node_modules in a workspaces-style monorepo, as long as the packages declare their dependencies on each other in their respective package.json files. So the feature I attempted at #47690 really only covers a narrow set of circumstances, and it turned out to totally ruin existing auto-imports caching infrastructure, so the current status is it’s definitely not worthwhile. I suspect many of the upvotes on this issue actually come from people who are experiencing some other bug or misconfiguration, not people whose issue would be solved by #47690. If you’d like to put together a small repro of your issue, I can take a look and see what the actual problem is.

@andrewbranch andrewbranch removed this from the TypeScript 4.8.0 milestone Oct 21, 2022
@andrewbranch andrewbranch removed their assignment Oct 21, 2022
@andrewbranch andrewbranch changed the title Auto imports not working with project references Auto imports from referenced project not working until already imported once in project Oct 21, 2022
@andrewbranch andrewbranch added Suggestion An idea for TypeScript Cursed? It's likely this is extremely difficult to fix without making something else much, much worse and removed Needs Investigation This issue needs a team member to investigate its status. Fix Available A PR has been opened for this issue Rescheduled This issue was previously scheduled to an earlier milestone labels Oct 21, 2022
@RyanCavanaugh RyanCavanaugh added the Experience Enhancement Noncontroversial enhancements label Oct 21, 2022
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Oct 21, 2022
@adamsmasher
Copy link

adamsmasher commented Oct 21, 2022

@andrewbranch

Sure, here's a repo that has the issue.

This is based on a simplification of our own yarn monorepo. We've got a common project that contains stuff that's shared between frontend and backend (the backend project is omitted), and a web project that references it via a @common alias. Each project has its own tsconfig.json. I believe this is pretty similar to the example repo posted above. To see the problem, hop into web/src/Helper.ts and try to use a "Quick Fix" to import square from the common repo.

This example repo doesn't include any of this extra stuff because it suffices to show the issue, but for context, in our real repo web is a CRA-based Webpack app. We run it via yarn tsc --build --watch & react-app-rewired start (we run tsc separate because CRA's setup doesn't understand building projects). We want to import the compiled code in common/dist via an alias (e.g. import { square } from '@common/MyModule').

Our biggest issue is the one mentioned in the comment above - VSCode auto-import suggests relative paths to the original .ts file no matter what. There's a few issues here:

  • it leads CRA to barf because of the attempt to import a file outside of the project (this works fine with aliases, with some monkey-grease)
  • we want to be importing the compiled .js file, not the original .ts file
  • Depending on VSCode settings, it won't even import the correct file.

What I mean by that last point is, if I try it with the "Import Module Specifier" preference set to "shortest", it works (although with a relative path, which is still undesirable):

Screen Shot 2022-10-21 at 2 50 32 PM

But if I set "Import Module Specifier" to "non-relative", it curiously gives me:

Screen Shot 2022-10-21 at 2 48 45 PM

Which is simply broken - an immediate compilation error.

It's totally possible - and would be great if! - this is just a configuration issue on our part and there's a different/better way to do it.

Thanks for your help!

@andrewbranch
Copy link
Member

Opened a new issue because that does sound different. Will take a look next week; thanks for the detailed info!

@kbrilla
Copy link

kbrilla commented Apr 10, 2023

Any news on this? Monorepos with @nrwl/nx are nightmare to use without suggestions.

@RyanCavanaugh
Copy link
Member

Nothing has changed since the last update

@theKashey
Copy link

I found autoimports working quite reliably if top level tsconfig includes all files. It will be unused by any particular file or project having own local configuration, but magically enables autocomplete.

Also almost the opposite advice - do not reference workspace packages from a top-level config. Even for small projects it might take too much time to start language server, so you'll be left with no support as-you-type.

@MathieuUrstein
Copy link

@theKashey what do you mean by root level tsconfig including all files?
I have created a repro repo and if add "include": ["**/*"] to the root tsconfig I still don't get any autocomplete until first imported

@theKashey
Copy link

So that the trick you should have your tsconfig-base as your tsconfig and put references aside (tsconfig.references.json) using them only inside particular packages.
image

I am not sure references are expected to work this way, but it works.

@aminpaks
Copy link
Contributor

aminpaks commented Sep 9, 2023

The only way I got this working is to include the referenced projects' source code in include of the project using the references. Not sure if this is how it's intended to work 🤷

@aminpaks
Copy link
Contributor

aminpaks commented Sep 20, 2023

Just realized if we include the referenced projects in include it will break the incremental builds! This is really frustrating.
Do you know any workarounds for this @andrewbranch?

Here is a sample to reproduce the issue.

@aminpaks
Copy link
Contributor

aminpaks commented Sep 20, 2023

For those who want to fix the auto import in composite projects, I have a partial solution for you. I think as this already works out of the box with the current implementation, the TypeScript team might be able to actually leverage this, and fix the issue internally so we don't have to configure all the referenced projects to built files to make types available only for auto-import.

Here is how it all works, you will have to add the built version of the referenced projects where the declaration files are generated in the compilerOptions.typeRoots, this is on top of node_modules/types, and remember adding node_modules/types is important or it will break the global types in your project.

A minimal base configs (that will be extended by the composite projects) look like this:

{
    "extends": "@tsconfig/strictest/tsconfig.json",
    "compilerOptions": {
        // required configs
        "baseUrl": ".",
        "rootDir": ".",
        "outDir": "./built/local",

        "composite": true,
        "declaration": true,
        "declarationMap": true,
        "sourceMap": true,

       // configure these based on your needs
        "module": "esnext",
        "target": "es2016",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "jsx": "react-jsx",
        "checkJs": false
    }
}

And a project that has references can include the built of shared in the typeRoots like this:

{
    "extends": "../../tsconfig-base",
    "compilerOptions": {
        "typeRoots": [
            "../../node_modules/@types",
            "../../built/local/app/shared",
        ],
    },
    "include": [
        "**/*",
        "**/*.json",
    ],
    "references": [
        {"path": "../shared"},
    ],
}

And the shared project configs that was referenced above:

{
    "files": [],
    "include": [],
    "references": [
        {"path": "./main"},
        {"path": "./shared"},
    ],
}

And then you'll have to build the whole project for the declarations to be available for auto-import to work by running tsc -b app --watch.

This works only partially, and for some reasons the root exported declarations are not available in the auto import. In our example loadConfigs1 is not available which is in the root index.ts but loadConfigs2 is available in the auto-import list.

This should allow the incremental build, and the auto imports in vscode to work properly.

@dajinchu
Copy link

dajinchu commented Dec 4, 2024

FYI I got auto importing in a monorepo working by:

  1. setting up my workspace using dependencies instead of project references (I am using Yarn PnP but I don't think it matters)
  2. adding an exports field to the shared module. In my case, exporting everything with a glob, which works as of 5.2.2 Offer auto-imports from wildcard exports with AutoImportProvider #54831
  3. setting VScode setting typescript.preferences.includePackageJsonAutoImports to on. Looking into if I can avoid this or enforce using a typescript plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Cursed? It's likely this is extremely difficult to fix without making something else much, much worse Experience Enhancement Noncontroversial enhancements Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.