Skip to content

TS importModuleSpecifier could work better for lerna monorepos with libs only #36624

Closed

Description

TS Template added by Matt Bierner (@mjbvz)

TypeScript Version: 3.8.0

Search Terms

  • importModuleSpecifier
  • auto import
  • mono repo / monorepo

Related issue: #36181 (I thought was something related to TS itself, but maybe is not).

Right now, the typescript.preferences.importModuleSpecifier auto option only uses relative paths for files nearer to the actual file than the basePath configuration file. But this isn't the best approach for a monorepo full with libs.

I only want to have aliases on imports from other lib folders, but I want to keep every import within a lib as relative imports. The problem is, VSCode suggestions sometimes adds the alias to imports within files of the same lib. When I build and publish everything as is, the service using that lib will crash because doesn't understand the alias.

Thank you in advance!

Activity

  1. mjbvz commented on Jan 21, 2020

    @mjbvz
    Contributor

    Can you provide a small example project that shows what doesn't work today and explain the expected behavior?

  2. vscodebot commented on Jan 28, 2020

    @vscodebot
  3. lgraziani2712 commented on Jan 28, 2020

    @lgraziani2712
    Author

    Sorry for the delay. Here is the repo: https://github.com/lgraziani2712/vscode-88977

    Here is a comment in the built file: lgraziani2712/vscode-88977@07e82a9#r37005671

  4. removed their assignment
    on Feb 5, 2020
  5. mjbvz commented on Feb 5, 2020

    @mjbvz
    Contributor

    Moving upstream for feedback from TS team

  6. Ore4444 commented on Apr 20, 2020

    @Ore4444

    I'm having the same issue.
    compilerOptions.baseUrl in my project tsconfig is set to root of monorepo modules.
    In every module tsconfig, I have: compilerOptions.outDir = "lib" and compilerOptions.rootDir = "src"
    I don't have a baseUrl in module tsconfigs which is what causes the mismatch of relative imports (i have exactly the same symptoms as #36181).
    If I add compilerOptions.baseUrl = "src" to a module tsconfig, it does solve the issue of doing move refactoring, but for some reason tsc fails with lots of TS2307. Now none of my compilerOptions.paths are resolved for that module.
    The difference between baseUrl and no baseUrl can easily be verified by moving a folder or renaming a file with webstorm.
    Seems like when compilerOptions.baseUrl is set in a composite project, compilerOptions.paths of parent tsconfig stops having a effect.

    I've had this issue since the beginning of my monorepo 1.5 years ago. Finally this issue gave me a direction. I'd love to give more context if that would help.

    More issues I found that might be related: #36235, #35768, #20110

  7. andrewbranch commented on Aug 7, 2020

    @andrewbranch
    Member

    Ore Landau (@Ore4444) what you’re describing sounds like a separate issue than the original post here. Are you able to provide an example repo demonstrating your problem?

    If I add compilerOptions.baseUrl = "src" to a module tsconfig, it does solve the issue of doing move refactoring, but for some reason tsc fails with lots of TS2307. Now none of my compilerOptions.paths are resolved for that module.
    The difference between baseUrl and no baseUrl can easily be verified by moving a folder or renaming a file with webstorm.
    Seems like when compilerOptions.baseUrl is set in a composite project, compilerOptions.paths of parent tsconfig stops having a effect.

    Actually, this sounds like expected behavior. paths are resolved relative to baseUrl, so if you override baseUrl in a child tsconfig, that changes how the parent paths resolve—specifically, in this case, all those paths will fail to resolve.

    Most of what’s described in this issue, including 100% of the problem in Luciano Graziani (@lgraziani2712)’s example repo, is essentially a duplicate of #31869, and would be solved by implementing that proposal. It does leave open the issue of trying to use a common set of paths in a base tsconfig, though, because each composite project will be able to resolve itself with its unrooted paths entry. Example:

    tsconfig.base.json: "paths": { "lib-a": ["packages/lib-a"], "lib-b": ["packages/lib-b"], "lib-c": ... }
    packages/
      app/
        tsconfig.json (extends base, references all libs)
      lib-a/
        tsconfig.json (extends base, references b and c)
      lib-b/
        tsconfig.json (extends base, no references)
      lib-c/
        ...
    

    The intention is probably:

    • the app package can reference any lib by its path mapping - ✔️
    • the lib-a package can reference lib-b and lib-c by their path mappings - ✔️
    • the lib-a package cannot reference itself by the "lib-a" path mapping - ❌

    To accomplish this, even if #31869 is implemented, each project would need its own paths setting to avoid the pitfall of being able to reference itself. I hoped this would be solvable already by letting lib-a/tsconfig.json specify "paths": { "lib-a": [] }, but paths in a child tsconfig completely overwrites paths in an extended config instead of merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions