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

importModuleSpecifierPreference: "non-relative" should use self-name package imports #59620

Open
OliverJAsh opened this issue Aug 13, 2024 · 3 comments
Assignees
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@OliverJAsh
Copy link
Contributor

OliverJAsh commented Aug 13, 2024

πŸ”Ž Search Terms

  • relative imports
  • workspaces
  • monorepo
  • subpath export

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about auto imports and subpath exports.

⏯ Playground Link

No response

πŸ’» Code

Full reduced test case: https://github.com/OliverJAsh/typescript-auto-imports-exports

Contents inlined below. TLDR:

  • Two workspaces, packages/a and packages/b.
  • packages/b depends on packages/a.

Root files:

tsconfig.json:

{
  "compilerOptions": {
    "strict": true,
    "noEmit": true,
    "target": "ESNext",
    "module": "Node16",
    "moduleResolution": "Node16"
  }
}

package.json:

{
  "private": true,
  "dependencies": {
    "typescript": "^5.5.4"
  },
  "workspaces": [
    "packages/a",
    "packages/b"
  ],
  "packageManager": "[email protected]"
}

Package a:

packages/a/package.json:

{
  "name": "a",
  "private": true,
  "exports": {
    "./test": "./module.ts"
  }
}

packages/a/module.ts:

export const a = 1;

packages/a/other-module.ts:

// Try to import this
// Auto import uses a relative path here: `./module` ❌
a;

Package b:

packages/b/package.json:

{
  "name": "b",
  "private": true,
  "dependencies": {
    "a": "workspace:^"
  }
}

packages/b/module.ts:

// Try to import this
// Auto import works correctly here: `a/test` βœ…
a;

πŸ™ Actual behavior

  • The auto import suggestion in packages/b/other-module.ts uses the subpath export defined in packages/a/package.json. The suggested import path is a/test. βœ…
  • The auto import suggestion in packages/a/other-module.ts does not use the subpath export defined in packages/a/package.json. Instead it uses a relative import. The suggested import path is ./module.

It seems that TypeScript is not using the subpath export information for self-referencing imports.

πŸ™‚ Expected behavior

In both cases I would expect the subpath export to be used (rather than relative imports), otherwise you can end up with some verbose relative paths in the case of projects with deeply nested folders.

I would expect TypeScript to only use a relative import if a subpath export is not available.

Additional information about the issue

No response

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Aug 13, 2024
@andrewbranch
Copy link
Member

I’ve never seen a project that exclusively uses self-name imports, and this is the first request for it I’ve heard in the years that we’ve supported package.json "exports". I think it’s something we should support, but only under "importModuleSpecifierPreference": "non-relative". Do you have any examples of projects in the wild (other than your own) that never use relative imports (and don’t use tsconfig "paths")?

@OliverJAsh
Copy link
Contributor Author

OliverJAsh commented Aug 13, 2024

Do you have any examples of projects in the wild (other than your own) that never use relative imports (and don’t use tsconfig "paths")?

I'm afraid I don't.

We never had this problem when we used paths previously. This problem only became apparent after we migrated away from paths towards subpath exports (we migrated because it's standard more tools support it).

@OliverJAsh
Copy link
Contributor Author

OliverJAsh commented Aug 13, 2024

exclusively uses self-name imports,

We do use relative imports in some cases where it makes sense. For example, if we have a package containing React components, the public exports would be the components, but each component module may use relative imports for private things e.g. to import a sibling CSS or a co-located helper module.

This is why I suggested the following:

I would expect TypeScript to only use a relative import if a subpath export is not available.

@andrewbranch andrewbranch added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature and removed Needs Investigation This issue needs a team member to investigate its status. labels Aug 13, 2024
@andrewbranch andrewbranch changed the title Auto import suggestions should prefer subpath export over relative imports importModuleSpecifierPreference: "non-relative" should use self-name package imports Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants