microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.73k stars 12.45k forks source link

Update import does not work with typescript alias import #51763

Closed ran-collective closed 2 months ago

ran-collective commented 1 year ago

Type: Bug

How to configure VSCode to work with alias import in typescript, specifically for auto-update import path on file/folder move or rename?

I've created a repo to reproduce the issue: https://github.com/ran-collective/update-import-bug

moving the folder api/src/modules/inetgarionA to api/src/modules/integrations/inetgarionA will not work

moving the folder api/src/modules/inetgarionB to api/src/modules/integrations/inetgarionB will work, and you can see the import changed in api/src/v1/controller.ts

the import from integrationA file is path alias, and the import from integrationB is a relative import.

VS Code version: Code 1.73.1 (6261075646f055b99068d3688932416f2346dd3b, 2022-11-09T03:54:53.913Z) OS version: Linux x64 5.14.0-1054-oem snap Modes: Sandboxed: No

System Info |Item|Value| |---|---| |CPUs|11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz (8 x 1800)| |GPU Status|2d_canvas: disabled_software
canvas_oop_rasterization: disabled_off
direct_rendering_display_compositor: disabled_off_ok
gpu_compositing: disabled_software
multiple_raster_threads: disabled_off
opengl: disabled_off
rasterization: disabled_software
raw_draw: disabled_off_ok
skia_renderer: enabled_on
video_decode: disabled_software
video_encode: disabled_software
vulkan: disabled_off
webgl: disabled_off
webgl2: disabled_off
webgpu: disabled_off| |Load (avg)|2, 2, 2| |Memory (System)|31.10GB (19.87GB free)| |Process Argv|--no-sandbox --force-user-env --unity-launch --crash-reporter-id edbfcff7-5171-4183-8a78-d5c45fe7cfbf| |Screen Reader|no| |VM|0%| |DESKTOP_SESSION|ubuntu| |XDG_CURRENT_DESKTOP|Unity| |XDG_SESSION_DESKTOP|ubuntu| |XDG_SESSION_TYPE|x11|
Extensions (33) Extension|Author (truncated)|Version ---|---|--- atlascode|atl|2.10.12 htmltagwrap|bra|0.0.7 path-intellisense|chr|2.8.1 vscode-eslint|dba|2.2.6 githistory|don|0.6.19 es7-react-js-snippets|dsz|4.4.3 vscode-babel-coloring|dza|0.0.4 gitlens|eam|13.0.4 EditorConfig|Edi|0.16.4 vscode-npm-script|eg2|0.3.29 prettier-vscode|esb|9.9.0 flow-for-vscode|flo|2.2.0 copilot|Git|1.59.7338 cypress-fixture-intellisense|Jos|1.2.0 vscode-colorize|kam|0.11.1 inline-parameters|lia|0.2.1 vscode-language-babel|mgm|0.0.36 line-linker|Mic|1.6.0 dotenv|mik|1.0.1 vscode-docker|ms-|1.22.2 isort|ms-|2022.8.0 python|ms-|2022.18.2 vscode-pylance|ms-|2022.11.30 remote-containers|ms-|0.262.3 vscode-react-native|msj|1.10.0 vscode-jest|Ort|4.6.0 vscode-thunder-client|ran|1.20.1 vscode-yaml|red|1.10.1 code-spell-checker|str|2.11.0 code-spell-checker-hebrew|str|1.0.0 pdf|tom|1.2.0 highlight-matching-tag|vin|0.10.1 vscode-icons|vsc|12.0.1
A/B Experiments ``` vsliv368:30146709 vsreu685:30147344 python383:30185418 vspor879:30202332 vspor708:30202333 vspor363:30204092 vstes627:30244334 vslsvsres303:30308271 pythonvspyl392:30443607 vserr242:30382549 pythontb:30283811 vsjup518:30340749 pythonptprofiler:30281270 vshan820:30294714 vstes263cf:30335440 vscorecescf:30445987 pythondataviewer:30285071 vscod805cf:30301675 binariesv615:30325510 bridge0708:30335490 bridge0723:30353136 cmake_vspar411:30581797 vsaa593cf:30376535 pythonvs932:30410667 cppdebug:30492333 vscaat:30438848 vsclangdf:30486550 c4g48928:30535728 dsvsc012cf:30540253 azure-dev_surveyone:30548225 pyindex848:30577860 nodejswelcome1cf:30587006 fc301958:30595537 282f8724:30602487 gswce1:30612156 3d0df643:30613357 dbltrim-noruby:30604474 f6dab269:30613381 ```
RyanCavanaugh commented 1 year ago

Please provide a simplified repro if you're reporting a bug. Thanks!

ran-collective commented 1 year ago

Please provide a simplified repro if you're reporting a bug. Thanks!

Hey, here is a link to a repo containing the simplest way to reproduce. https://github.com/ran-collective/update-import-bug

in the original post I've described how to reproduce

Thank you.

hems commented 8 months ago

This still happens to me, did you find any solutions to this? @RyanCavanaugh / @ran-collective ?

ran-collective commented 8 months ago

@hems it still happens sometimes, but less... no idea how or why

hems commented 8 months ago

@hems it still happens sometimes, but less... no idea how or why

yeah very awkward i have the same feeling that sometimes it stops working then i close and open and it comes back again :(

mk-kialo commented 7 months ago

Got the same issue in our project with VScode users. We have an alias defined like this:

// foo/tsconfig.json
"paths": {
            "@foo/*": ["./*"]
        }

My VScode version:

Version: 1.86.2 (Universal)
Commit: 903b1e9d8990623e3d7da1df3d33db3e42d80eda
Date: 2024-02-13T19:42:13.651Z
Electron: 27.2.3
ElectronBuildId: 26908389
Chromium: 118.0.5993.159
Node.js: 18.17.1
V8: 11.8.172.18-electron.0
OS: Darwin arm64 23.2.0

Using the "JavaScript and TypeScript" extension v5.5.20240303.

simplenotezy commented 3 months ago

I can confirm we have the same issue. We're using a default Next.js starter project configured with alias imports (configurable when creating a new Next.js project), and when renaming files, it does not update the aliased imports.

alexberezin commented 2 months ago

The issue still exists

simplenotezy commented 2 months ago

Related issue, I believe: https://github.com/microsoft/TypeScript/issues/59119

RyanCavanaugh commented 2 months ago

Update Imports is only supported for relative paths. Path-mapping paths are not supported.

dkamins commented 2 months ago

(2024-08) Analysis of VS Code regression: updating @aliased imports paths on file moves

(First, apologies for the length. I tried to make this as clear and organized as possible, but there's a lot to touch on.)

Context / Background

This detailed analysis is in regards to VS Code's ability to automatically update TypeScript path aliased (path-mapped) imports when users rename or move files or directories. This ability to refactor and reorganize so easily has been a key feature of VS Code that drew many developers to it and became a key aspect of their daily development workflow.

However recently (mid 2024), automatic import updates started breaking in mysterious and confusing ways.

The top post in this issue #51763 contains distilled repro steps and repo to download. This issue is from 2022, and perhaps it started as a result of something else, but it's 100% relevant today.

The TypeScript and VS Code community faces an issue more complicated than it might seem -- less technical in nature than about product management and communication/coordination. After much confusion and frustration, I decided to dig in deep and figure out what's going on. I hope this analysis helps shed some light.

What are path aliases and import updates? (Skip if you know)

A path alias import looks like this:

Here we might have @foo mapped to src/components/foo in tsconfig, which would look like this:.

A file src/components/foo/lib/bar.ts contains export class Bar. If we move (in VS Code) bar.ts to a subdirectory such as src/components/foo/lib/extra-level/bar.ts, the lovely VS Code will offer to "Update Imports", and if you say "Yes", then all references in the project will be updated to:

This feature is provided automatically by VS Code via the typescript.updateImportsOnFileMove.enabled setting, which defaults to prompting the user. This has worked brilliantly, including with path-mapped imports / aliases for quite some time.

Root Cause

The core issue lies in the integration of a new experimental VS Code setting that has led to import updates failing. See first this snippet from VS Code 1.89 release notes (April 2024):

A new experimental setting typescript.tsserver.experimental.useVsCodeWatcher controls if the TS extension is using VS Code's core file watching support for file watching needs. TS makes extensive use of file watching, usually with their own node.js based implementation. By using VS Code's file watcher, watching should be more efficient, more reliable, and consume less resources. We plan to gradually enable this feature for users in May and monitor for regressions.

This sounds fantastic! In its current state though (August 2024, many versions including 1.91.1 which I am using now) there is a significant problem which causes a major regression in functionality for VS Code that disrupts a feature crucial to many developers:

Why is this complicated?

This situation is complicated for several reasons:

First, the "gradual rollout" from VS Code of this setting is making the behavior and reproduction inconsistent across devices, versions, and users. Many reports in both microsoft/TypeScript as well as microsoft/vscode are getting ignored, closed, misunderstood, or marked as dupes.

Second, @RyanCavanaugh (Development lead for the TypeScript team at Microsoft) closed this issue as Not a Defect yesterday (2024-08-09) here in "Update import does not work with typescript alias import #51763" with comment:

Update Imports is only supported for relative paths. Path-mapping paths are not supported.

If the VS Code experimental setting is moving from TypeScript to VS Code versions, then I don't totally follow what Ryan is referring to here since the old way (TypeScript presumably) DID support tracking and updating path alias imports perfectly, and it's the new way (VS Code as I understand it) that doesn't, but maybe he was referring to the new VS Code way (?), or maybe he's talking about something unrelated to VS Code entirely, or maybe the people who wrote the release notes and settings text got it backwards... Not sure. Regardless, that comment and closing with "Not a Defect" is a clear statement, especially when other issues are redirecting to this one.

I want to take a brief moment to express my appreciation of all the contributions and work from both VS Code and TypeScript teams (Ryan included) and clarify that nothing in here is aimed at anybody or intended as criticism. I'm quoting and referencing relevant things because they're relevant. On that note, here are some more relevant issues:

Recent Related Issues

Some recent related microsoft/TypeScript issues for reference:

Some recent possibly related microsoft/vscode issues for reference:

Next Steps

In the interim, this workaround (originally identified by bastiankistner) is legitimate: Disable "TypeScript › Tsserver › Experimental: Use Vs Code Watcher" (typescript.tsserver.experimental.useVsCodeWatcher), and import paths will update properly again.

The VS Code team will likely now pursue one of these paths:

  1. Figure out how to identify and fix this significant regression so a key feature developers depend on is restored (and we get the new more efficient code watching they are working on).
  2. Scrap plans to transition to the new way of doing it (miss out on alleged performance gain, but at least everything keeps working).
  3. Declare that VS Code will no longer support this feature.
  4. Ignore it.

Options 3 and 4 would be quite unfortunate and likely lead to massive user exodus, as competing IDEs (including VS Code itself up until recently) support this natural feature. My initial reading of Ryan's comment was that it was either dancing around option 3, or more likely nobody had taken the time to clarify what we're even talking about here in the first place, and he has 10,000 other issues and bug reports on his plate -- which is partly why I took the time to write this up. I can confidently say the majority of users are hoping for option 1, with option 2 a very close second.

It took a while to bundle up all this information. I hope this helps clarify everything for anybody wondering why their imports aren't updating any more as well as for some of the people involved in these product decisions.

To the community: please provide your feedback! Do you depend on this feature? When did you notice it breaking? How has your daily development workflow been impacted? Did the workaround work for you?

RyanCavanaugh commented 2 months ago

👀 We can certainly look at this again

RyanCavanaugh commented 2 months ago

@dkamins thanks for the analysis!

What we've found is that different file layouts, different OSes, different user settings, different order of operations, etc, can all have an impact on which events ultimately trigger import updates. There's a lot of interplay between VSC and TS in this process so it's easy for a set of steps that works for one developer to be done slightly differently by another developer and encounter different behavior.

Can you please post a separate issue with a succinct and reproducible repro (plus what steps you did) so that we can ensure we're looking at the right problem and get it fixed? If this worked in prior versions, we'd also like to know which version that was. Thanks!

Bunkerbewohner commented 2 months ago

Thank you so much for this write up @dkamins! I really appreciate it. I'm not even a VSCode user myself, and yet this problem has single-handedly blocked my company from improving our code base with alias imports, because there are many VScode users for whom imports are just broken when using them. So a code editor that isn't even used by everyone in our company suddenly dictates what TypeScript feature we can or cannot use, even though other editors we use support this just fine. It has been quite frustrating.

Because our code is a monorepo with deep hierarchies, path aliases have many advantages that we cannot profit from right now. I will definitely share the workaround with my coworkers and hopefully this way can unblock the transition. For the sake of our VScode users I hope this issue will be fixed.

RyanCavanaugh commented 2 months ago

@Bunkerbewohner same question for you - please log a separate issue that demonstrates the problem you're encountering. It may or may not have the same root cause as what other people are encountering, and a separate repro we can manually validate a fix against ensures that your specific configuration will get fixed. Thanks!

Bunkerbewohner commented 2 months ago

Alright! I logged a separate issue https://github.com/microsoft/TypeScript/issues/59603 and linked a small reproducible repository (https://github.com/Bunkerbewohner/vscode-path-alias-problem). Thank you!

dkamins commented 2 months ago

Can you please post a separate issue with a succinct and reproducible repro (plus what steps you did) so that we can ensure we're looking at the right problem and get it fixed? If this worked in prior versions, we'd also like to know which version that was. Thanks!

@RyanCavanaugh Thank you for re-opening and looking into this. ❤️

I'm happy to continue to help here and can make a new issue but want to make sure I'm not just adding more noise, as there are already:

As far as where to post a new issue, part of the challenge here is knowing who is even responsible for this complex cross-product issue. My current understanding is that this problem most recently arose due to VS Code transitioning (beginning in ~April 2024 with 1.89's new typescript.tsserver.experimental.useVsCodeWatcher, but gradually and unpredictably) FROM "[TypeScript's own] file watching ... with their own node.js based implementation" (where the import updating worked with path aliases) TO "VS Code's core file watching support" (where import updating no longer works with path aliases), and disabling that "experimental" feature restores proper functionality. But this is partly confounded by your (Ryan's) statement (presumably as TypeScript lead, but possibly speaking for VS Code?) that "path-mapping paths are not supported", when based on the info we have, the TS version is the one where they were supported (and hints at this being more of a Product Management / Engineering / User alignment issue than a technical one).

Since the distinction between TypeScript and VS Code teams may be a bit unclear to outsiders, would you please share whether a new issue for this should be better created in microsoft/TypeScript or microsoft/vscode? Should the new issue focus on "regression caused by experimental VS Code feature" vs. the problem itself and mentioning that as more of a footnote? Any other specific terms or phrases to use to ensure clarity and minimize extraneous discussion there, or anything else you can share about that transition of file watching approaches that VS Code is undergoing?

Thank you!

RyanCavanaugh commented 2 months ago

Just to be clear, the useVsCodeWatcher setting is new as of this year, so can't really be implicated as the root-cause in a 2-year old bug. Or is something else happening here that makes this issue the right venue to talk about that flag?

It's really a lack of clear repro steps that is preventing progress here. Once we have clear repro steps in front of us, we can easily route the problem (and root cause it) appropriately. Whether this is ultimately a VS Code or TypeScript problem is not really something I want you to have to concern yourself with - it's our job to get it figured out, once we have clear repro steps.

dkamins commented 2 months ago

Yes, totally agree. There is surely a real root beneath the "root" I identified. Whatever old bug this might have been was recently resurfaced because of that new useVsCodeWatcher flag though, and not wanting to make more dupe issues and seeing some recent attention here, this seemed like a reasonable place to advance the discussion. There might even be some relevant commit history around when this was originally reported and possibly fixed incidentally.

Now that we have the newly created issue though, I added some clear repro steps and experiments and takeaways over there:

Hope it helps get to the bottom of it!

lirbank commented 2 months ago

I have found two ways to make the aliased updates work:

  1. Add "baseUrl": "." to the compiler options in tsconfig.json (Next.js does not have it by default), or
  2. Set "typescript.tsserver.experimental.useVsCodeWatcher": false

But either one is enough, you don't need both.

UPDATE: No 1 above only works occasionally, no 2 seems to work a lot better.

RyanCavanaugh commented 2 months ago

This is elsewhere confirmed as fixed on the newest build.

We've had multiple fixes going in over the last couple weeks/days. If you're still seeing this on the latest nightly build of both VS Code and TypeScript, please log a new issue with clear repro steps (e.g. a cloneable repo), tsserver log and video.