knip icon indicating copy to clipboard operation
knip copied to clipboard

πŸ› Knip module resolution doesn't take account of TypeScript `rootDirs` from referenced project

Open pawelblaszczyk5 opened this issue 1 year ago β€’ 3 comments

Prerequisites

Reproduction url

https://github.com/pawelblaszczyk5/knip-root-dirs-repro

Reproduction access

  • [X] I've made sure the reproduction is publicly accessible

Description of the issue

Hello πŸ‘‹

In one of my monorepos, where I use Knip I'm migrating from Remix to React Router. They're using rootDirs from TypeScript for some funky typesafety codegen stuff. I'm also using project references to split up settings for e.g. tests and app code. While importing from this "magically" mapped stuff I'm getting "unresolved imports" errors.

In my reproduction you can see these behaviours:

  1. Running pnpm knip fails with unresolved imports error
  2. Running pnpm knip --tsConfig tsconfig.source.json on the other hand works so Knip can correctly resolve rootDirs
  3. Uncommenting rootDirs in main tsconfig.json also works, so same as 2.

It seems like Knip isn't correctly using stuff from projects that are referenced from root tsconfig.json. I'm not sure but maybe related to these two: https://github.com/webpro-nl/knip/issues/780 https://github.com/webpro-nl/knip/issues/779

pawelblaszczyk5 avatar Dec 08 '24 21:12 pawelblaszczyk5

Thanks PaweΕ‚, useful to have that repro.

Looks related to the issues you mention indeed.

Hopefully easy to resolve in Knip, but need to dig some deeper. For starters, Knip uses the same config loader as tsc itself. Having references.path point to another TS config file does not result in configs getting merged or something. E.g. tsc --build or bundler takes care of that, and Knip will need to do something similar. Just not sure yet if and how to merge those TS configs.

webpro avatar Dec 09 '24 09:12 webpro

That's interesting, in theory just tsc won't even resolve anything in this file because it's not included in the root tsconfig.json. As you mentioned - you have to use tsc --build to run typechecking for all the referenced projects.

Also afaik, it's not really "merging" it's just using completely different config based on which one of the references includes a given file. That should maybe be a little bit easier, because you don't need any merging logic? I'm not knowledgable with Knip internals enough πŸ˜„ Also curious how LSP does it ootb without any additional changes

pawelblaszczyk5 avatar Dec 09 '24 13:12 pawelblaszczyk5

It's different config but a "Go To Definition" still resolves it properly, so I was also thinking of looking into LSP stuff.

Fwiw, it's quite literally sending compilerOptions from ts.parseJsonConfigFileContent to ts.resolveModuleName.

webpro avatar Dec 09 '24 13:12 webpro

Knip has migrated from enhanced-resolve to oxc-resolver. This resolver sits in front of the TS internal module resolver. There seems to be no mention of rootDirs in docs nor the repo at all, so I don't have high hopes, but wanted to mention it anyways.

webpro avatar May 15 '25 11:05 webpro

Knip has migrated from enhanced-resolve to oxc-resolver. This resolver sits in front of the TS internal module resolver. There seems to be no mention of rootDirs in docs nor the repo at all, so I don't have high hopes, but wanted to mention it anyways.

I’ll check later today and update the reproduction in case it’s still applicable πŸ˜ƒ Thanks for the update

pawelblaszczyk5 avatar May 15 '25 11:05 pawelblaszczyk5

Unfortunately it's still the same - bumped version of Knip in the reproduction

pawelblaszczyk5 avatar May 15 '25 20:05 pawelblaszczyk5

I'll take a look at rootDirs https://github.com/oxc-project/oxc-resolver/issues/521.

Boshen avatar May 16 '25 04:05 Boshen

I'm not sure whether it's strictly related to rootDirs solely - if I setup rootDirs without project references it works. Take a look at behaviour 2. or 3. in the issue πŸ˜ƒ

pawelblaszczyk5 avatar May 16 '25 07:05 pawelblaszczyk5