Skip to content

Moving a folder that's imported using a path alias does not update the import paths. #59603

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
Bunkerbewohner opened this issue Aug 12, 2024 Β· 11 comments Β· Fixed by #59625
Closed

Moving a folder that's imported using a path alias does not update the import paths. #59603

Bunkerbewohner opened this issue Aug 12, 2024 Β· 11 comments Β· Fixed by #59625
Assignees
Labels
Fixed A PR has been merged for this issue

Comments

@Bunkerbewohner
Copy link

Bunkerbewohner commented Aug 12, 2024 β€’

πŸ”Ž Search Terms

"vscode path alias import"

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried.

⏯ Playground Link

No response

πŸ’» Code

Given some TS project where a folder is mapped using path aliases, e.g. mapping "@app" to the root folder.

import { foo } from '@app/bar/folder/module'

Move the folder folder to a different parent, e.g. baz, using VSCode.

πŸ™ Actual behavior

The imports referencing the moved files are not updated when the VScode setting typescript.tsserver.experimental.useVsCodeWatcher is enabled.
When disabling the setting, the behavior is as expected (see below).

πŸ™‚ Expected behavior

The import referencing the module should be updated automatically to

import { foo } from '@app/baz/folder/module'

Additional information about the issue

See https://github.com/Bunkerbewohner/vscode-path-alias-problem for a reproduction repo.

@dkamins
Copy link

dkamins commented Aug 12, 2024

@Bunkerbewohner Thanks for posting this. Very clear. The problem is affecting a lot of people.

Another user posted a similar repro repo here (which includes both aliased and relative imports for side-by-side comparison):
https://github.com/ran-collective/update-import-bug

I traced this VS Code regression with @aliased (path-mapped) imports no longer updating on file moves to be likely related to an experimental feature that began rolling out gradually in early/mid 2024. There is a short-term workaround, but we definitely need to get to the root of it. I wrote a longer post about details here:

The TypeScript team engaged and suggested we post new issues, so here we are!

@RyanCavanaugh
Copy link
Member

Here's what I did, since the repro steps given don't align with the folder names in the repo:

  • Ensure that useVsCodeWatcher is on
  • Create components/target
  • Drag the whatever folder into target
  • Click "Yes" when asked if I wanted to update imports
  • The import did get updated
2024-08-12.13-03-02.mp4

Can you post a video along with the TS Server log operating on the provided repo?

@RyanCavanaugh RyanCavanaugh added the Needs More Info The issue still hasn't been fully clarified label Aug 12, 2024
@RyanCavanaugh
Copy link
Member

In #59119 it was pointed out that this was likely fixed by #59418. Have you tried using the latest TS build? It's very easy to set up with this extension

@Bunkerbewohner
Copy link
Author

Bunkerbewohner commented Aug 12, 2024 β€’

Thanks a lot for looking into this!

Here is a video using the latest TS build with the extension you suggested, where it didn't work.
https://github.com/user-attachments/assets/8ae647c3-9c94-41d8-8e00-e83876a651fc

However, I then tried to reproduce it a second time (reset the repo, restarting VScode).
Suddenly it worked the first time I moved the folder, but not when I moved the folder back.
See this video:

tsnext.works.then.not.mp4

So there seems to be some randomness, or at least some stateful condition involved.

P.S. forgot to show it, but that's with the experimental VScode watcher enabled. When it's disabled, it always seems to work.

Also just for posterity: the concrete repro steps are mentioned in the README of the repo (https://github.com/Bunkerbewohner/vscode-path-alias-problem?tab=readme-ov-file#bug-moving-a-folder-thats-imported-from-using-path-aliased-should-update-imports).

@dkamins
Copy link

dkamins commented Aug 12, 2024

P.S. forgot to show it, but that's with the experimental VScode watcher enabled. When it's disabled, it always seems to work.

Reminder to anybody else contributing to this thread: Please make sure to check and note your typescript.tsserver.experimental.useVsCodeWatcher setting in conjunction with any reports. It's typically ON by default, and turning it off often make the problem go away. So it's super-important to document the state of your setting, and ideally test with it both checked and unchecked, and report the difference!

@dkamins
Copy link

dkamins commented Aug 12, 2024

Here is a video using the latest TS build with the extension you suggested, where it didn't work.

Quick note on something illustrated in this video that might be helpful in troubleshooting: when the import updating doesn't work, it doesn't even try. I.e. the "Update imports for ...?" popup (seen at 0:15) that appears after the "Are you sure you want to move...?" popup just never even pops up (would have been at 0:25).

@dkamins
Copy link

dkamins commented Aug 13, 2024

I've been testing this today and have some useful info to report. I believe I've gotten to the root of the unpredictability and apparent randomness.

Environment

  • VS Code 1.92.1 (and Cursor fork of VS Code 1.91.1, same).
  • Mac OS 14.4.1.
  • typescript.tsserver.experimental.useVsCodeWatcher is ENABLED (the default). When disabled, everything works consistently. So the info below is about VS Code with that setting ENABLED.
  • Using the repo at the top of the page (and some variations to it).

Experiment 1 (Simple)

  • Open the repo at the top of the page.
  • Open 'index.ts' file and watch it.
  • Move 'alert.ts' from 'components/whatever/alert.ts' to 'functions/alert.ts'
  • Notice the prompt to update imports, and imports in index.ts update properly (@app/functions/alert).
  • Move 'alert.ts' back to its original location or anywhere else.
  • You are no longer even prompted to update imports, leaving index.ts in erroneous state.
  • Try moving the file anywhere. It won't work offer to update imports any more.
  • Restart TS Server.
  • Imports still are not offered to be updated on move until you close the project and re-open it again.

Learned: There is state that is cleared by closing/opening project, allowing a single update imports to work. Restarting TS Server does not affect this.

Question: To what extent does file location affect the state, and is moving it back to its original location relevant?

Experiment 2 (Multiple Locations)

  • Consider a project with 3 folders in a "lib" directory: "a", "b", and "c". There is a library file in "a" that is imported (via path alias) in an "index" file higher up.
  • Quit and open up VS Code fresh. Open the project fresh.
  • The first time you move the lib file (from within "a" to "b"), you are prompted to update imports, and it works (updates imports in the "index" file).
  • If you try to move the same file again (from "b" to "c"), it will not detect it, and not offer to update imports.
  • Your index import statements remain stuck on "b" with a red underline on the import and error eg "Cannot find module '@app/components/b/alert' or its corresponding type declarations.ts(2307)".
  • Even if you move the file back to the 2nd location ("b", matching the import), and even if you close and reopen the index file with the errors, the red underline remains.
  • If you "Restart TS Server", it realizes the file is in place and removes the red underline.
  • You can still no longer move the file and have imports updated.
  • Close VS Code window (don't have to quit) and re-open the project.
  • Everything works again (once).

Learned: The state seems to be associated with how many times the file is moved and not the location. I.e. moving it back to its original location is no different than moving it elsewhere. The first move works, and subsequent ones don't.

Question: Is the file itself relevant to the state, or is this a global state?

Experiment 3 (Multiple Files)

  • Now start with two lib files instead of just one (both imported separately by the index file using path aliases).
  • Do all the steps from the previous experiments to move the file a few times and notice its imports only updated once and no longer.
  • Now try to move the second file.
  • The imports are updated! But just once. Further attempts at moving are the same as before and don't offer to update imports any more.

Learned: The state appears to be associated with each file that is moved, only allowing the imports to be updated for the file the first time it is moved. But even in "broken" state, other files can still be moved (once).

Takeaways

So these experiments (hopefully easily reproducible) show a few things:

  1. There is state affecting this, and closing and re-opening the project/window seems to clear it, allowing it to work once per file.
  2. Restarting TS Server doesn't seem to resolve the bad state. Must close/reopen project window.
  3. The state seems to be specific to each file, as in each file can be moved once and trigger imports updating.
  4. We now have some easily reproducible steps that bypass the randomness and apparent non-determinism we've been seeing.

@sheetalkamat
Copy link
Member

@Bunkerbewohner pls test with tonight’s nightly that would have fix #59625 to see if things resolved for you . If not give pls provide clear repro steps along with video and tsserver log .

Thanks

@Bunkerbewohner
Copy link
Author

Bunkerbewohner commented Aug 15, 2024 β€’

Thanks for your observations, @dkamins! That would be in line with the issue that @sheetalkamat linked, and it could essentially be a caching issue.

@sheetalkamat I think you actually might have fixed it! I tested again today with ms-vscode.vscode-typescript-next-5.6.20240814 and I can no longer reproduce the issue with that version! πŸ₯³ I hope others can corroborate. Either way, thank you very much for looking into it! πŸ™

tsnext20240814.mp4

@Bunkerbewohner
Copy link
Author

Bunkerbewohner commented Aug 15, 2024 β€’

I tested again in our actual app, not in my reproduction repo, and there even disabling the experimental typescript.tsserver.experimental.useVsCodeWatcher option does not fix the issue. However, with ms-vscode.vscode-typescript-next-5.6.20240814 it works there, as well! Confirmed by my colleagues.

Our app uses an older TypeScript 5.3.3.

@sheetalkamat sheetalkamat linked a pull request Aug 15, 2024 that will close this issue
@sheetalkamat
Copy link
Member

I am going to close this issue as fixed. If anyone has other repros, please file a new issue with clear repro steps, tsserver log and video as these things are tricky to track down without proper information.

@sheetalkamat sheetalkamat self-assigned this Aug 15, 2024
@sheetalkamat sheetalkamat added the Fixed A PR has been merged for this issue label Aug 15, 2024
@microsoft microsoft locked as resolved and limited conversation to collaborators Aug 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants