Check package reachability before using exports in declarations - #64599
Mateusz Burzyński (Andarist) wants to merge 1 commit into
Conversation
|
This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise. |
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
Review effort: Lite
Findings: 1
Open (2)
What changed in this PR
Fixes a TypeScript module specifier generation bug where package exports could return a bare specifier before validating that the importing file can actually reach the corresponding node_modules folder.
Changes:
- Reorders reachability validation to occur before consulting
package.jsonexportswhen computing node module specifiers. - Adds a compiler test case covering unreachable-package scenarios involving
exports(root, subpath, and pattern exports). - Adds baselines for both
module=preserveandmodule=nodenextfor the new test.
| File | Description |
|---|---|
| tsc/internal/modulespecifiers/specifiers.go | Moves node_modules reachability check earlier to prevent exports from bypassing validation. |
| tsc/testdata/tests/cases/compiler/declarationEmitUnreachablePackageExports.ts | New repro test for declaration emit when exports paths are unreachable from the importer. |
| tsc/testdata/baselines/reference/compiler/declarationEmitUnreachablePackageExports(module=preserve).js | Baseline output for the new test under module=preserve. |
| tsc/testdata/baselines/reference/compiler/declarationEmitUnreachablePackageExports(module=preserve).errors.txt | Baseline errors for the new test under module=preserve. |
| tsc/testdata/baselines/reference/compiler/declarationEmitUnreachablePackageExports(module=nodenext).js | Baseline output for the new test under module=nodenext. |
| tsc/testdata/baselines/reference/compiler/declarationEmitUnreachablePackageExports(module=nodenext).errors.txt | Baseline errors for the new test under module=nodenext. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| if !stringutil.HasPrefix(info.SourceDirectory, pathToTopLevelNodeModules, caseSensitive) || len(globalTypingsCacheLocation) > 0 && stringutil.HasPrefix(globalTypingsCacheLocation, pathToTopLevelNodeModules, caseSensitive) { |
| // Check reachability before consulting package.json exports, which can return | ||
| // a bare specifier directly. An exported path is only usable if the importing | ||
| // file can reach the package through node_modules. | ||
| pathToTopLevelNodeModules := pathObj.FileName[0:parts.TopLevelNodeModulesIndex] | ||
|
|
||
| if !stringutil.HasPrefix(info.SourceDirectory, pathToTopLevelNodeModules, caseSensitive) || len(globalTypingsCacheLocation) > 0 && stringutil.HasPrefix(globalTypingsCacheLocation, pathToTopLevelNodeModules, caseSensitive) { | ||
| return "" | ||
| } |


fixes #64590
The issue was causedd by an early return~, the code sequence was roughly was:
So the step 2 bypassed the step 3's validation~ entirely. The fix simply relies on reordering the steps listed above. It now validates the reachability before checking if the exports have the specifier.