π Knip module resolution doesn't take account of TypeScript `rootDirs` from referenced project
Prerequisites
- [X] I'm using the latest version
- [X] I've read the relevant documentation
- [X] I've searched for existing issues
- [X] I've checked the list of known issues
- [X] I've read the issue reproduction guide
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:
- Running
pnpm knipfails withunresolved importserror - Running
pnpm knip --tsConfig tsconfig.source.jsonon the other hand works so Knip can correctly resolverootDirs - Uncommenting
rootDirsin maintsconfig.jsonalso 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
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.
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
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.
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.
Knip has migrated from
enhanced-resolveto oxc-resolver. This resolver sits in front of the TS internal module resolver. There seems to be no mention ofrootDirsin 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
Unfortunately it's still the same - bumped version of Knip in the reproduction
I'll take a look at rootDirs https://github.com/oxc-project/oxc-resolver/issues/521.
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 π