Repository navigation
Use files from tsconfig references with --use-tsconfig-files - #2126
Conversation
β¦ebpro-nl#2116) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
webpro
left a comment
There was a problem hiding this comment.
Thanks for picking this up! Following references in --use-tsconfig-files mode is the right direction, and leaving the default mode alone makes sense given ambient-declaration-files.test.ts. Requesting changes to the reference walk: it should stay within the project, and loadTSConfig can do it by recursing into itself (see inline comment).
| } | ||
| }; | ||
|
|
||
| const expandReferencedFileNames = ( |
There was a problem hiding this comment.
In project-reference setups a package's tsconfig usually references its dependencies, e.g. "references": [{ "path": "../lib" }]. tsc -b builds ../lib as a separate project, and its source files are not part of the referencing program. Following those references turns another package's files into project files of this workspace:
- Issues in an
ignoreWorkspacesworkspace get reported. Repro:packages/app/tsconfig.jsonwith"include": ["src"], "references": [{ "path": "../ign" }], no root tsconfig, and{ "ignoreWorkspaces": ["packages/ign"] }. On main onlyappandlibissues are reported; with this PR the unused exports inpackages/ignshow up too. - Each workspace globs the transitive closure of its references. In a synthetic chain of 100 packages where each references the previous one,
--use-tsconfig-filesgoes from 0.5s to 1.7s with identical output.
References that point up or sideways are dependencies. The ones at or below the referencing tsconfig's directory (./tsconfig.app.json, ./tsconfig.node.json, ./tsconfig.lib.json) are part of the project. With that rule, loadTSConfig can recurse into the references itself, which also removes the duplicated include/exclude/files/outDir handling:
export const loadTSConfig = async (
tsConfigFilePath: string,
isUseTscFiles = false,
visited = new Set([tsConfigFilePath])
): Promise<TSConfigInfo> => { const fileNames = expandFileNames(dir, compilerOptions, include, exclude, files);
if (isUseTscFiles && config.references) {
for (const ref of config.references) {
const refPath = resolveReference(ref.path, dir);
if (!refPath?.startsWith(`${dir}/`) || visited.has(refPath)) continue;
visited.add(refPath);
for (const filePath of (await loadTSConfig(refPath, true, visited)).fileNames) fileNames.push(filePath);
}
}A fixture like the repro above would make a good regression test.
There was a problem hiding this comment.
Thanks, done in bc2615c: loadTSConfig recurses into references at or below its own directory, and expandReferencedFileNames is gone. Your repro is the new tsc-files-mode-references-workspaces fixture (app references ../ign, which is in ignoreWorkspaces): it fails on the previous commit with the ign export reported, and passes now. tsc-files-mode-references still passes.
References that point up or sideways are dependencies built as separate projects, so their files must not become project files of the workspace. loadTSConfig now recurses into the references at or below its directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
webpro
left a comment
There was a problem hiding this comment.
Thanks for the quick update, looks good!
commit: |
|
π This pull request is included in v6.41.0. See Release 6.41.0 for release notes. Using Knip in a commercial project? Please consider becoming a sponsor. |
Closes #2116.
With a solution-style
tsconfig.json("files": []plusreferences, ascreate-vitegenerates),--use-tsconfig-filesfound no project files and Knip reported nothing. The editor extension, MCP server and language server hit the same case, since they enable the flag when there is no Knip config.With
--use-tsconfig-files,loadTSConfignow also loads the tsconfigs referenced at or below its own directory (./tsconfig.app.json,./tsconfig.node.json) and adds their files. References that point up or sideways (../lib) are dependencies built as separate projects and are not followed. The default mode is unchanged: there the referenced.d.tsfiles would become entries, whichambient-declaration-files.test.tsrules out.Tests:
tsc-files-mode-referencesis thetsc-files-modefixture in solution style and expects the same results (the first test fails on main).tsc-files-mode-references-workspaceschecks that a reference to another workspace (here inignoreWorkspaces) does not add its files. The repro from the issue now reportsorphan, same as with a single tsconfig.