Uh oh!
There was an error while loading. Please reload this page.
Proposal: importModuleSpecifierPreference: project-relative - #40637
Conversation
TypeScript Bot (typescript-bot)
commented
Sep 18, 2020
Thanks for the PR! It looks like you've changed the TSServer protocol in some way. Please ensure that any changes here don't break consumers of the current TSServer API. For some extra review, we'll ping Sheetal Nandi (@sheetalkamat), Andrew Casey (@amcasey), Matt Bierner (@mjbvz), Mine Starks (@minestarks) for you. Feel free to loop in other consumers/maintainers if necessary |
AlCalzone
commented
Sep 23, 2020
Andrew Branch (@andrewbranch) should the improved behavior for same-package-imports already be present in 4.1-beta or is this PR required? |
Andrew Branch (andrewbranch)
commented
Sep 23, 2020
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| */ | ||
| readonly includeAutomaticOptionalChainCompletions?: boolean; | ||
| readonly importModuleSpecifierPreference?: "auto" | "relative" | "non-relative"; | ||
| readonly importModuleSpecifierPreference?: "shortest" | "external-non-relative" | "relative" | "non-relative"; |
There was a problem hiding this comment.
Kind of nervous that auto is going away; can you explain?
There was a problem hiding this comment.
I’ve renamed auto to shortest to be more descriptive. Previously, auto was an acceptable name because it would pick between the other options (relative and non-relative) based on some heuristic (number of path separators). Now, there are two options that pick between relative and non-relative based on some heuristic. auto becomes a bad name because it no longer encompasses all of the other options, it’s no more or less automatic than the new mode, and its name conveys nothing about the heuristic it uses. Values of "auto" will still map to "shortest", by merit of it being the default.
Ryan Cavanaugh (RyanCavanaugh)
commented
Sep 29, 2020
Let's bikeshed this name somewhere |
Andrew Branch (andrewbranch)
commented
Oct 19, 2020
Renamed to “project-relative.” How do we feel about this going into 4.1? |
Andrew Branch (andrewbranch)
commented
Oct 27, 2020
Since this hasn’t gotten much attention and we’re now quite close to the RC, I think I’d prefer to wait for 4.2 for this. To get user feedback on it, I might see if there’s any interest in running a VS Code Insiders experiment setting |
AlCalzone
commented
Oct 27, 2020
How can one participate in that experiment? |
Andrew Branch (andrewbranch)
commented
Oct 27, 2020
TypeScript Bot (@typescript-bot) pack this You can try it out now by installing the tarball that TypeScript Bot (@typescript-bot) will post shortly, and adding to {
"typescript.tsserver.importModuleSpecifierPreference": "project-relative"
}After this is properly merged, I’ll add a corresponding option to VS Code’s preferences UI. |
Heya Andrew Branch (@andrewbranch), I've started to run the tarball bundle task on this PR at 2b875bb. You can monitor the build here. |
Hey Andrew Branch (@andrewbranch), I've packed this into an installable tgz. You can install it for testing by referencing it in your and then running There is also a playground for this build. |
Andrew Branch (@andrewbranch) Do I need to configure project references, If you want to try:
|
Andrew Branch (andrewbranch)
commented
Oct 27, 2020
Oops, apparently the TypeScript language support extension in VS Code filters out values it doesn’t recognize. I guess I’ll have to make an update there first. |
AlCalzone
commented
Nov 9, 2020
Andrew Branch (@andrewbranch) please let me know when there's something I can test. Not sure how long the process to update the extension takes. |
Andrew Branch (andrewbranch)
commented
Nov 17, 2020
AlCalzone you can use the TypeScript nightly and VS Code Insiders now: |
AlCalzone
commented
Nov 17, 2020
Andrew Branch (@andrewbranch) I must be missing a puzzle piece... |
Andrew Branch (andrewbranch)
commented
Nov 17, 2020
Ah, it’s because you have this package symlinked through node_modules... and node_modules dependencies get priority. I didn’t notice that before. I’ll have a separate fix up for that. |
Andrew Branch (andrewbranch)
commented
Nov 18, 2020
Wait, this is only allowed to happen because |
See also this discussion:
That would be great news, I've always thought TypeScript needs |
Andrew Branch (@andrewbranch) FYI I just tried to migrate the project to So I guess if you don't want to support |
Andrew Branch (andrewbranch)
commented
Nov 18, 2020
Huh, I guess I haven’t been using |
Leslie Leigh (李的序) (shrinktofit)
commented
Dec 4, 2020
Andrew Branch (@andrewbranch) How can I prevent import specifier suggestion from suggesting non-entry modules in other "packages(folder)" in same repo? I hope the specifier suggestion only suggest exports of |
Andrew Branch (andrewbranch)
commented
Dec 4, 2020
Exports available from the package index have the highest priority, but you can’t prevent exports in other files from showing up. |






Fixes#36624
People often want to use
pathsaliases to refer to “external” code (cross-project/package/some other conceptual boundary), but use relative paths elsewhere. Auto-imports cannot help you do this today.The problem is that the conceptual boundaries within which people want to use relative imports and across which they want to use
pathsaliases can’t always be inferred. Suppose I have a monorepo structure with a base tsconfig definingpathslikeBecause we are familiar with common monorepo patterns, it’s clear that the package boundaries are the direct subdirectories of
packages. So within./packages/fooI’d use relative imports to import anything in that package, and"bar"to import./packages/bar.However, it’s also common for webpack-bundled apps to have a convenience alias for the project root:
This is structurally identical, but serves a different purpose—I needn’t treat
./src/utilsand./src/routesas separate, siloed directory trees.My original hope was to be able to split module specifier suggestion behavior based on how
pathsis defined, but I think that is too hand-wavy. Instead, this PR introduces two more conservative heuristics:For everything else, use a relative path.
This should cover basically all monorepo / project references configurations. I can imagine scenarios where I want to conceptually silo directories within a single project where these heuristics wouldn’t help you, but I haven’t heard user feedback from anyone with a setup like that.
I am proposing renaming
importModuleSpecifierPreference: 'auto'to'shortest'to be more descriptive, leaving it as the default (which means that clients sending'auto'will continue to work), and giving this new setting a brief but descriptive name. Right now it’s'external-non-relative', which is terrible.