diff --git a/internal/checker/checker.go b/internal/checker/checker.go
index 8f5065c9be..f594f9de68 100644
--- a/internal/checker/checker.go
+++ b/internal/checker/checker.go
@@ -544,6 +544,7 @@ type Program interface {
GetProjectReferenceFromOutputDts(path tspath.Path) *tsoptions.SourceOutputAndProjectReference
GetRedirectForResolution(file ast.HasFileName) *tsoptions.ParsedCommandLine
CommonSourceDirectory() string
+ GetDeduplicatedPackagePath(path tspath.Path) tspath.Path
}
type Host interface {
@@ -26975,8 +26976,14 @@ func (c *Checker) compareProperties(sourceProp *ast.Symbol, targetProp *ast.Symb
return TernaryFalse
}
if sourcePropAccessibility != ast.ModifierFlagsNone {
- if c.getTargetSymbol(sourceProp) != c.getTargetSymbol(targetProp) {
- return TernaryFalse
+ sourceTarget := c.getTargetSymbol(sourceProp)
+ targetTarget := c.getTargetSymbol(targetProp)
+ if sourceTarget != targetTarget {
+ // Check if these symbols are from duplicate package instances (same package installed
+ // in different locations). If they map to the same canonical file, treat them as identical.
+ if !c.areSymbolsFromSamePackageFile(sourceTarget, targetTarget) {
+ return TernaryFalse
+ }
}
} else {
if (sourceProp.Flags & ast.SymbolFlagsOptional) != (targetProp.Flags & ast.SymbolFlagsOptional) {
@@ -26989,6 +26996,27 @@ func (c *Checker) compareProperties(sourceProp *ast.Symbol, targetProp *ast.Symb
return compareTypes(c.getTypeOfSymbol(sourceProp), c.getTypeOfSymbol(targetProp))
}
+// areSymbolsFromSamePackageFile checks if two symbols come from files that are duplicates
+// of the same package file (same package name@version installed in different locations).
+func (c *Checker) areSymbolsFromSamePackageFile(source *ast.Symbol, target *ast.Symbol) bool {
+ // If package deduplication is disabled, don't treat any files as duplicates
+ if c.compilerOptions.DisablePackageDeduplication.IsTrue() {
+ return false
+ }
+ sourceDecl := source.ValueDeclaration
+ targetDecl := target.ValueDeclaration
+ if sourceDecl == nil || targetDecl == nil {
+ return false
+ }
+ sourceFile := ast.GetSourceFileOfNode(sourceDecl)
+ targetFile := ast.GetSourceFileOfNode(targetDecl)
+ // If they're from the same file, they can't have been deduplicated.
+ if sourceFile == targetFile {
+ return false
+ }
+ return c.program.GetDeduplicatedPackagePath(sourceFile.Path()) == c.program.GetDeduplicatedPackagePath(targetFile.Path())
+}
+
func compareTypesEqual(s *Type, t *Type) Ternary {
if s == t {
return TernaryTrue
diff --git a/internal/checker/relater.go b/internal/checker/relater.go
index db83af0745..b55d891e54 100644
--- a/internal/checker/relater.go
+++ b/internal/checker/relater.go
@@ -4203,7 +4203,7 @@ func (r *Relater) propertyRelatedTo(source *Type, target *Type, sourceProp *ast.
targetPropFlags := getDeclarationModifierFlagsFromSymbol(targetProp)
switch {
case sourcePropFlags&ast.ModifierFlagsPrivate != 0 || targetPropFlags&ast.ModifierFlagsPrivate != 0:
- if sourceProp.ValueDeclaration != targetProp.ValueDeclaration {
+ if sourceProp.ValueDeclaration != targetProp.ValueDeclaration && !r.c.areSymbolsFromSamePackageFile(sourceProp, targetProp) {
if reportErrors {
if sourcePropFlags&ast.ModifierFlagsPrivate != 0 && targetPropFlags&ast.ModifierFlagsPrivate != 0 {
r.reportError(diagnostics.Types_have_separate_declarations_of_a_private_property_0, r.c.symbolToString(targetProp))
diff --git a/internal/compiler/fileloader.go b/internal/compiler/fileloader.go
index 6fdbf008ea..0b69107b01 100644
--- a/internal/compiler/fileloader.go
+++ b/internal/compiler/fileloader.go
@@ -68,7 +68,14 @@ type processedFiles struct {
// if file was included using source file and its output is actually part of program
// this contains mapping from output to source file
outputFileToProjectReferenceSource map[tspath.Path]string
- finishedProcessing bool
+ // Maps a source file path to the name of the package it was imported with
+ sourceFileToPackageName map[tspath.Path]string
+ // Key is a file path. Value is the list of files that redirect to it (same package, different install location)
+ redirectTargetsMap map[tspath.Path][]string
+ // Maps any path (canonical or redirect target) to its canonical path.
+ // Canonical paths map to themselves; redirect targets map to their canonical path.
+ deduplicatedPathMap map[tspath.Path]tspath.Path
+ finishedProcessing bool
}
type jsxRuntimeImportSpecifier struct {
diff --git a/internal/compiler/filesparser.go b/internal/compiler/filesparser.go
index 307e6ccd65..904774560f 100644
--- a/internal/compiler/filesparser.go
+++ b/internal/compiler/filesparser.go
@@ -1,6 +1,8 @@
package compiler
import (
+ "cmp"
+ "maps"
"math"
"slices"
"sync"
@@ -408,6 +410,16 @@ func (w *filesParser) getProcessedFiles(loader *fileLoader) processedFiles {
}
}
+ // Build sourceFileToPackageName and redirectTargetsMap by scanning all resolved modules.
+ // This is done after loading is complete to ensure determinism regardless of load order.
+ // Skip this if package deduplication is disabled.
+ var sourceFileToPackageName map[tspath.Path]string
+ var redirectTargetsMap map[tspath.Path][]string
+ var deduplicatedPathMap map[tspath.Path]tspath.Path
+ if !loader.opts.Config.CompilerOptions().DisablePackageDeduplication.IsTrue() {
+ sourceFileToPackageName, redirectTargetsMap, deduplicatedPathMap = computePackageRedirects(resolvedModules, loader.toPath)
+ }
+
return processedFiles{
finishedProcessing: true,
resolver: loader.resolver,
@@ -424,7 +436,88 @@ func (w *filesParser) getProcessedFiles(loader *fileLoader) processedFiles {
missingFiles: missingFiles,
includeProcessor: includeProcessor,
outputFileToProjectReferenceSource: outputFileToProjectReferenceSource,
+ sourceFileToPackageName: sourceFileToPackageName,
+ redirectTargetsMap: redirectTargetsMap,
+ deduplicatedPathMap: deduplicatedPathMap,
+ }
+}
+
+// computePackageRedirects builds the sourceFileToPackageName and redirectTargetsMap by scanning
+// all resolved modules. Files from the same package (same name@version) are deduplicated:
+// the lexicographically first path becomes the "canonical" one and others redirect to it.
+// This is done after loading completes to ensure determinism regardless of concurrent load order.
+func computePackageRedirects(
+ resolvedModules map[tspath.Path]module.ModeAwareCache[*module.ResolvedModule],
+ toPath func(string) tspath.Path,
+) (sourceFileToPackageName map[tspath.Path]string, redirectTargetsMap map[tspath.Path][]string, deduplicatedPathMap map[tspath.Path]tspath.Path) {
+ // Collect all resolved files with package IDs
+ // packageIdKey -> list of (resolvedPath, packageName)
+ type fileInfo struct {
+ path tspath.Path
+ fileName string
+ packageName string
+ }
+ packageIdToFiles := make(map[module.PackageId][]fileInfo)
+
+ containingFilePaths := slices.AppendSeq(make([]tspath.Path, 0, len(resolvedModules)), maps.Keys(resolvedModules))
+ slices.Sort(containingFilePaths)
+
+ for _, containingPath := range containingFilePaths {
+ resolutions := resolvedModules[containingPath]
+ for _, resolution := range resolutions {
+ if !resolution.IsResolved() {
+ continue
+ }
+ pkgId := resolution.PackageId
+ if pkgId.Name == "" {
+ continue
+ }
+ resolvedFileName := resolution.ResolvedFileName
+ resolvedPath := toPath(resolvedFileName)
+ packageName := pkgId.PackageName()
+
+ // Check if we've already recorded this path for this package
+ files := packageIdToFiles[pkgId]
+ if !slices.ContainsFunc(files, func(f fileInfo) bool { return f.path == resolvedPath }) {
+ packageIdToFiles[pkgId] = append(files, fileInfo{path: resolvedPath, fileName: resolvedFileName, packageName: packageName})
+ }
+ }
}
+
+ // Now for each packageIdKey with multiple files, pick the canonical one (lexicographically first)
+ // and build the redirect map
+ sourceFileToPackageName = make(map[tspath.Path]string)
+ redirectTargetsMap = make(map[tspath.Path][]string)
+ deduplicatedPathMap = make(map[tspath.Path]tspath.Path)
+
+ for _, files := range packageIdToFiles {
+ if len(files) == 0 {
+ continue
+ }
+
+ slices.SortFunc(files, func(a, b fileInfo) int { return cmp.Compare(a.path, b.path) })
+
+ canonicalPath := files[0].path
+ packageName := files[0].packageName
+
+ // Record package name for all files from this package
+ for _, f := range files {
+ sourceFileToPackageName[f.path] = packageName
+ }
+
+ // If there are multiple files, the others redirect to the canonical one
+ if len(files) > 1 {
+ // Canonical path maps to itself
+ deduplicatedPathMap[canonicalPath] = canonicalPath
+ for _, f := range files[1:] {
+ redirectTargetsMap[canonicalPath] = append(redirectTargetsMap[canonicalPath], f.fileName)
+ // Redirect target maps to canonical
+ deduplicatedPathMap[f.path] = canonicalPath
+ }
+ }
+ }
+
+ return sourceFileToPackageName, redirectTargetsMap, deduplicatedPathMap
}
func (w *filesParser) addIncludeReason(includeProcessor *includeProcessor, task *parseTask, reason *FileIncludeReason) {
diff --git a/internal/compiler/program.go b/internal/compiler/program.go
index a9a6b47f3e..97ecee2dee 100644
--- a/internal/compiler/program.go
+++ b/internal/compiler/program.go
@@ -110,9 +110,21 @@ func (p *Program) GetPackageJsonInfo(pkgJsonPath string) *packagejson.InfoCacheE
return nil
}
-// GetRedirectTargets implements checker.Program.
+// GetRedirectTargets returns the list of file paths that redirect to the given path.
+// These are files from the same package (same name@version) installed in different locations.
func (p *Program) GetRedirectTargets(path tspath.Path) []string {
- return nil // !!! TODO: project references support
+ return p.redirectTargetsMap[path]
+}
+
+// GetDeduplicatedPackagePath returns the canonical path for a file that may be a duplicate package.
+// If the file is a redirect target (i.e., it redirects to a canonical file), returns the canonical path.
+// Otherwise, returns the path unchanged.
+func (p *Program) GetDeduplicatedPackagePath(path tspath.Path) tspath.Path {
+ if canonicalPath, ok := p.deduplicatedPathMap[path]; ok {
+ return canonicalPath
+ }
+ // Not part of any redirect group, return as-is
+ return path
}
// gets the original file that was included in program
@@ -241,6 +253,21 @@ func (p *Program) UpdateProgram(changedFilePath tspath.Path, newHost CompilerHos
if !canReplaceFileInProgram(oldFile, newFile) {
return NewProgram(newOpts), false
}
+ // TODO: CHECK THIS
+ // If this file is part of a package redirect group (same package installed in multiple
+ // node_modules locations), we need to rebuild the program because the redirect targets
+ // might need recalculation. A file is in a redirect group if it's either a canonical
+ // file that others redirect to, or if it redirects to another file.
+ // if _, isCanonical := p.redirectTargetsMap[changedFilePath]; isCanonical {
+ // return NewProgram(newOpts), false
+ // }
+ // for _, targets := range p.redirectTargetsMap {
+ // for _, target := range targets {
+ // if tspath.Path(target) == changedFilePath {
+ // return NewProgram(newOpts), false
+ // }
+ // }
+ // }
// TODO: reverify compiler options when config has changed?
result := &Program{
opts: newOpts,
diff --git a/internal/core/compileroptions.go b/internal/core/compileroptions.go
index ad6a4ceeca..0ba810403c 100644
--- a/internal/core/compileroptions.go
+++ b/internal/core/compileroptions.go
@@ -40,6 +40,7 @@ type CompilerOptions struct {
DisableSourceOfProjectReferenceRedirect Tristate `json:"disableSourceOfProjectReferenceRedirect,omitzero"`
DisableSolutionSearching Tristate `json:"disableSolutionSearching,omitzero"`
DisableReferencedProjectLoad Tristate `json:"disableReferencedProjectLoad,omitzero"`
+ DisablePackageDeduplication Tristate `json:"disablePackageDeduplication,omitzero"`
ErasableSyntaxOnly Tristate `json:"erasableSyntaxOnly,omitzero"`
ESModuleInterop Tristate `json:"esModuleInterop,omitzero"`
ExactOptionalPropertyTypes Tristate `json:"exactOptionalPropertyTypes,omitzero"`
diff --git a/internal/diagnostics/diagnostics_generated.go b/internal/diagnostics/diagnostics_generated.go
index 14c2a9b0f4..a84cb59248 100644
--- a/internal/diagnostics/diagnostics_generated.go
+++ b/internal/diagnostics/diagnostics_generated.go
@@ -4276,6 +4276,8 @@ var Set_the_number_of_projects_to_build_concurrently = &Message{code: 100009, ca
var X_all_unless_singleThreaded_is_passed = &Message{code: 100010, category: CategoryMessage, key: "all_unless_singleThreaded_is_passed_100010", text: "all, unless --singleThreaded is passed."}
+var Disable_deduplication_of_packages_with_the_same_name_and_version = &Message{code: 100011, category: CategoryMessage, key: "Disable_deduplication_of_packages_with_the_same_name_and_version_100011", text: "Disable deduplication of packages with the same name and version."}
+
func keyToMessage(key Key) *Message {
switch key {
case "Unterminated_string_literal_1002":
@@ -8552,6 +8554,8 @@ func keyToMessage(key Key) *Message {
return Set_the_number_of_projects_to_build_concurrently
case "all_unless_singleThreaded_is_passed_100010":
return X_all_unless_singleThreaded_is_passed
+ case "Disable_deduplication_of_packages_with_the_same_name_and_version_100011":
+ return Disable_deduplication_of_packages_with_the_same_name_and_version
default:
return nil
}
diff --git a/internal/diagnostics/extraDiagnosticMessages.json b/internal/diagnostics/extraDiagnosticMessages.json
index 2566d6ff53..4c51b0c450 100644
--- a/internal/diagnostics/extraDiagnosticMessages.json
+++ b/internal/diagnostics/extraDiagnosticMessages.json
@@ -86,5 +86,9 @@
"Option '{0}' requires value to be greater than '{1}'.": {
"category": "Error",
"code": 5002
+ },
+ "Disable deduplication of packages with the same name and version.": {
+ "category": "Message",
+ "code": 100011
}
}
diff --git a/internal/fourslash/_scripts/failingTests.txt b/internal/fourslash/_scripts/failingTests.txt
index be20094672..290e2e66c7 100644
--- a/internal/fourslash/_scripts/failingTests.txt
+++ b/internal/fourslash/_scripts/failingTests.txt
@@ -246,7 +246,6 @@ TestContextuallyTypedFunctionExpressionGeneric1
TestContextualTypingOfGenericCallSignatures2
TestCrossFileQuickInfoExportedTypeDoesNotUseImportType
TestDoubleUnderscoreCompletions
-TestDuplicatePackageServices
TestEditJsdocType
TestErrorsAfterResolvingVariableDeclOfMergedVariableAndClassDecl
TestExportDefaultClass
diff --git a/internal/fourslash/_scripts/manualTests.txt b/internal/fourslash/_scripts/manualTests.txt
index 5373890ae0..cbbe91801b 100644
--- a/internal/fourslash/_scripts/manualTests.txt
+++ b/internal/fourslash/_scripts/manualTests.txt
@@ -2,6 +2,7 @@ completionListInClosedFunction05
completionsAtIncompleteObjectLiteralProperty
completionsSelfDeclaring1
completionsWithDeprecatedTag4
+duplicatePackageServices_fileChanges
navigationBarFunctionPrototype
navigationBarFunctionPrototype2
navigationBarFunctionPrototype3
@@ -26,4 +27,4 @@ jsDocFunctionSignatures12
outliningHintSpansForFunction
getOutliningSpans
outliningForNonCompleteInterfaceDeclaration
-incrementalParsingWithJsDoc
\ No newline at end of file
+incrementalParsingWithJsDoc
diff --git a/internal/fourslash/tests/manual/duplicatePackageServices_fileChanges_test.go b/internal/fourslash/tests/manual/duplicatePackageServices_fileChanges_test.go
new file mode 100644
index 0000000000..a3aed4e54a
--- /dev/null
+++ b/internal/fourslash/tests/manual/duplicatePackageServices_fileChanges_test.go
@@ -0,0 +1,68 @@
+package fourslash_test
+
+import (
+ "testing"
+
+ "github.com/microsoft/typescript-go/internal/fourslash"
+ "github.com/microsoft/typescript-go/internal/testutil"
+)
+
+func TestDuplicatePackageServices_fileChanges(t *testing.T) {
+ t.Parallel()
+
+ defer testutil.RecoverAndFail(t, "Panic on fourslash test")
+ const content = `// @noImplicitReferences: true
+// @Filename: /node_modules/a/index.d.ts
+import X from "x";
+export function a(x: X): void;
+// @Filename: /node_modules/a/node_modules/x/index.d.ts
+export default class /*defAX*/X {
+ private x: number;
+}
+// @Filename: /node_modules/a/node_modules/x/package.json
+{ "name": "x", "version": "1.2./*aVersionPatch*/3" }
+// @Filename: /node_modules/b/index.d.ts
+import X from "x";
+export const b: X;
+// @Filename: /node_modules/b/node_modules/x/index.d.ts
+export default class /*defBX*/X {
+ private x: number;
+}
+// @Filename: /node_modules/b/node_modules/x/package.json
+{ "name": "x", "version": "1.2./*bVersionPatch*/3" }
+// @Filename: /src/a.ts
+import { a } from "a";
+import { b } from "b";
+a(/*error*/b);`
+ f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
+ defer done()
+
+ f.GoToFile(t, "/src/a.ts")
+ f.VerifyNumberOfErrorsInCurrentFile(t, 0)
+
+ testChangeAndChangeBack := func(versionPatch string, def string) {
+ // Insert "4" after the version patch marker, changing version from 1.2.3 to 1.2.43
+ f.GoToMarker(t, versionPatch)
+ f.Insert(t, "4")
+
+ // Insert a space after the definition marker to trigger a recheck
+ f.GoToMarker(t, def)
+ f.Insert(t, " ")
+
+ // No longer have identical packageId, so we get errors.
+ f.VerifyErrorExistsAfterMarker(t, "error")
+
+ // Undo the changes
+ f.GoToMarker(t, versionPatch)
+ f.DeleteAtCaret(t, 1)
+ f.GoToMarker(t, def)
+ f.DeleteAtCaret(t, 1)
+
+ // Back to being identical.
+ f.GoToFile(t, "/src/a.ts")
+ f.VerifyNumberOfErrorsInCurrentFile(t, 0)
+ }
+
+ testChangeAndChangeBack("aVersionPatch", "defAX")
+ testChangeAndChangeBack("bVersionPatch", "defBX")
+}
diff --git a/internal/module/resolver.go b/internal/module/resolver.go
index f5ae94746f..2114f3c564 100644
--- a/internal/module/resolver.go
+++ b/internal/module/resolver.go
@@ -985,7 +985,7 @@ func (r *resolutionState) loadModuleFromSpecificNodeModulesDirectory(ext extensi
}
if fromDirectory := r.loadNodeModuleFromDirectoryWorker(ext, candidate, !nodeModulesDirectoryExists, packageInfo); !fromDirectory.shouldContinueSearching() {
- fromDirectory.packageId = r.getPackageId(packageDirectory, packageInfo)
+ fromDirectory.packageId = r.getPackageId(fromDirectory.path, packageInfo)
return fromDirectory
}
}
@@ -994,12 +994,12 @@ func (r *resolutionState) loadModuleFromSpecificNodeModulesDirectory(ext extensi
loader := func(extensions extensions, candidate string, onlyRecordFailures bool) *resolved {
if rest != "" || !r.esmMode {
if fromFile := r.loadModuleFromFile(extensions, candidate, onlyRecordFailures); !fromFile.shouldContinueSearching() {
- fromFile.packageId = r.getPackageId(packageDirectory, packageInfo)
+ fromFile.packageId = r.getPackageId(fromFile.path, packageInfo)
return fromFile
}
}
if fromDirectory := r.loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, packageInfo); !fromDirectory.shouldContinueSearching() {
- fromDirectory.packageId = r.getPackageId(packageDirectory, packageInfo)
+ fromDirectory.packageId = r.getPackageId(fromDirectory.path, packageInfo)
return fromDirectory
}
// !!! this is ported exactly, but checking for null seems wrong?
@@ -1009,7 +1009,7 @@ func (r *resolutionState) loadModuleFromSpecificNodeModulesDirectory(ext extensi
// EsmMode disables index lookup in `loadNodeModuleFromDirectoryWorker` generally, however non-relative package resolutions still assume
// a default `index.js` entrypoint if no `main` or `exports` are present
if indexResult := r.loadModuleFromFile(extensions, tspath.CombinePaths(candidate, "index.js"), onlyRecordFailures); !indexResult.shouldContinueSearching() {
- indexResult.packageId = r.getPackageId(packageDirectory, packageInfo)
+ indexResult.packageId = r.getPackageId(indexResult.path, packageInfo)
return indexResult
}
}
diff --git a/internal/transformers/tstransforms/importelision_test.go b/internal/transformers/tstransforms/importelision_test.go
index 68c18aa71f..d17c058f78 100644
--- a/internal/transformers/tstransforms/importelision_test.go
+++ b/internal/transformers/tstransforms/importelision_test.go
@@ -86,6 +86,10 @@ func (p *fakeProgram) GetRedirectTargets(path tspath.Path) []string {
return nil
}
+func (p *fakeProgram) GetDeduplicatedPackagePath(path tspath.Path) tspath.Path {
+ return path
+}
+
func (p *fakeProgram) GetSourceOfProjectReferenceIfOutputIncluded(file ast.HasFileName) string {
return ""
}
diff --git a/internal/tsoptions/declscompiler.go b/internal/tsoptions/declscompiler.go
index 1550e1680d..a6bb2733d0 100644
--- a/internal/tsoptions/declscompiler.go
+++ b/internal/tsoptions/declscompiler.go
@@ -185,6 +185,15 @@ var commonOptionsWithBuild = []*CommandLineOption{
DefaultValueDescription: false,
// Not setting affectsSemanticDiagnostics or affectsBuildInfo because we dont want all diagnostics to go away, its handled in builder
},
+ {
+ Name: "disablePackageDeduplication",
+ Kind: CommandLineOptionTypeBoolean,
+ Category: diagnostics.Type_Checking,
+ Description: diagnostics.Disable_deduplication_of_packages_with_the_same_name_and_version,
+ DefaultValueDescription: false,
+ AffectsSemanticDiagnostics: true,
+ AffectsBuildInfo: true,
+ },
{
Name: "noEmit",
Kind: CommandLineOptionTypeBoolean,
diff --git a/internal/tsoptions/parsinghelpers.go b/internal/tsoptions/parsinghelpers.go
index 4a3763168a..3006411d8c 100644
--- a/internal/tsoptions/parsinghelpers.go
+++ b/internal/tsoptions/parsinghelpers.go
@@ -227,6 +227,8 @@ func parseCompilerOptions(key string, value any, allOptions *core.CompilerOption
allOptions.DisableSolutionSearching = ParseTristate(value)
case "disableReferencedProjectLoad":
allOptions.DisableReferencedProjectLoad = ParseTristate(value)
+ case "disablePackageDeduplication":
+ allOptions.DisablePackageDeduplication = ParseTristate(value)
case "declarationMap":
allOptions.DeclarationMap = ParseTristate(value)
case "declaration":
diff --git a/testdata/baselines/reference/fourslash/findAllReferences/duplicatePackageServices.baseline.jsonc b/testdata/baselines/reference/fourslash/findAllReferences/duplicatePackageServices.baseline.jsonc
new file mode 100644
index 0000000000..a2324c9269
--- /dev/null
+++ b/testdata/baselines/reference/fourslash/findAllReferences/duplicatePackageServices.baseline.jsonc
@@ -0,0 +1,33 @@
+// === findAllReferences ===
+// === /node_modules/a/index.d.ts ===
+// import [|X|]/*FIND ALL REFS*/ from "x";
+// export function a(x: [|X|]): void;
+
+// === /node_modules/a/node_modules/x/index.d.ts ===
+// export default class [|X|] {
+// private x: number;
+// }
+
+
+
+// === findAllReferences ===
+// === /node_modules/a/index.d.ts ===
+// import [|X|] from "x";
+// export function a(x: [|X|]): void;
+
+// === /node_modules/a/node_modules/x/index.d.ts ===
+// export default class /*FIND ALL REFS*/[|X|] {
+// private x: number;
+// }
+
+
+
+// === findAllReferences ===
+// === /node_modules/b/index.d.ts ===
+// import [|X|]/*FIND ALL REFS*/ from "x";
+// export const b: [|X|];
+
+// === /node_modules/b/node_modules/x/index.d.ts ===
+// export default class [|X|] {
+// private x: number;
+// }
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/duplicatePackage_referenceTypes.errors.txt b/testdata/baselines/reference/submodule/compiler/duplicatePackage_referenceTypes.errors.txt
deleted file mode 100644
index 954f20ec44..0000000000
--- a/testdata/baselines/reference/submodule/compiler/duplicatePackage_referenceTypes.errors.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-/index.ts(4,5): error TS2322: Type 'import("/node_modules/a/node_modules/foo/index").Foo' is not assignable to type 'import("/node_modules/@types/foo/index").Foo'.
- Types have separate declarations of a private property 'x'.
-
-
-==== /index.ts (1 errors) ====
- import * as a from "a";
- import { Foo } from "foo";
-
- let foo: Foo = a.foo;
- ~~~
-!!! error TS2322: Type 'import("/node_modules/a/node_modules/foo/index").Foo' is not assignable to type 'import("/node_modules/@types/foo/index").Foo'.
-!!! error TS2322: Types have separate declarations of a private property 'x'.
-
-==== /node_modules/a/index.d.ts (0 errors) ====
- ///
- import { Foo } from "foo";
- export const foo: Foo;
-
-==== /node_modules/a/node_modules/foo/index.d.ts (0 errors) ====
- export class Foo { private x; }
-
-==== /node_modules/a/node_modules/foo/package.json (0 errors) ====
- { "name": "foo", "version": "1.2.3" }
-
-==== /node_modules/@types/foo/index.d.ts (0 errors) ====
- export class Foo { private x; }
-
-==== /node_modules/@types/foo/package.json (0 errors) ====
- { "name": "foo", "version": "1.2.3" }
-
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/duplicatePackage_referenceTypes.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/duplicatePackage_referenceTypes.errors.txt.diff
deleted file mode 100644
index 58e5b61220..0000000000
--- a/testdata/baselines/reference/submodule/compiler/duplicatePackage_referenceTypes.errors.txt.diff
+++ /dev/null
@@ -1,34 +0,0 @@
---- old.duplicatePackage_referenceTypes.errors.txt
-+++ new.duplicatePackage_referenceTypes.errors.txt
-@@= skipped -0, +0 lines =@@
--
-+/index.ts(4,5): error TS2322: Type 'import("/node_modules/a/node_modules/foo/index").Foo' is not assignable to type 'import("/node_modules/@types/foo/index").Foo'.
-+ Types have separate declarations of a private property 'x'.
-+
-+
-+==== /index.ts (1 errors) ====
-+ import * as a from "a";
-+ import { Foo } from "foo";
-+
-+ let foo: Foo = a.foo;
-+ ~~~
-+!!! error TS2322: Type 'import("/node_modules/a/node_modules/foo/index").Foo' is not assignable to type 'import("/node_modules/@types/foo/index").Foo'.
-+!!! error TS2322: Types have separate declarations of a private property 'x'.
-+
-+==== /node_modules/a/index.d.ts (0 errors) ====
-+ ///
-+ import { Foo } from "foo";
-+ export const foo: Foo;
-+
-+==== /node_modules/a/node_modules/foo/index.d.ts (0 errors) ====
-+ export class Foo { private x; }
-+
-+==== /node_modules/a/node_modules/foo/package.json (0 errors) ====
-+ { "name": "foo", "version": "1.2.3" }
-+
-+==== /node_modules/@types/foo/index.d.ts (0 errors) ====
-+ export class Foo { private x; }
-+
-+==== /node_modules/@types/foo/package.json (0 errors) ====
-+ { "name": "foo", "version": "1.2.3" }
-+
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.errors.txt b/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.errors.txt
deleted file mode 100644
index 9f4f6d7f9b..0000000000
--- a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.errors.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-/index.ts(4,5): error TS2345: Argument of type 'import("/node_modules/a/node_modules/foo/index").C' is not assignable to parameter of type 'import("/node_modules/foo/index").C'.
- Types have separate declarations of a private property 'x'.
-
-
-==== /index.ts (1 errors) ====
- import { use } from "foo/use";
- import { o } from "a";
-
- use(o);
- ~
-!!! error TS2345: Argument of type 'import("/node_modules/a/node_modules/foo/index").C' is not assignable to parameter of type 'import("/node_modules/foo/index").C'.
-!!! error TS2345: Types have separate declarations of a private property 'x'.
-
-==== /node_modules/a/node_modules/foo/package.json (0 errors) ====
- {
- "name": "foo",
- "version": "1.2.3"
- }
-
-==== /node_modules/a/node_modules/foo/index.d.ts (0 errors) ====
- export class C {
- private x: number;
- }
-
-==== /node_modules/a/index.d.ts (0 errors) ====
- import { C } from "foo";
- export const o: C;
-
-==== /node_modules/foo/use.d.ts (0 errors) ====
- import { C } from "./index";
- export function use(o: C): void;
-
-==== /node_modules/foo/index.d.ts (0 errors) ====
- export class C {
- private x: number;
- }
-
-==== /node_modules/foo/package.json (0 errors) ====
- {
- "name": "foo",
- "version": "1.2.3"
- }
-
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.errors.txt.diff
deleted file mode 100644
index 6be7c60fc7..0000000000
--- a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.errors.txt.diff
+++ /dev/null
@@ -1,47 +0,0 @@
---- old.duplicatePackage_relativeImportWithinPackage.errors.txt
-+++ new.duplicatePackage_relativeImportWithinPackage.errors.txt
-@@= skipped -0, +0 lines =@@
--
-+/index.ts(4,5): error TS2345: Argument of type 'import("/node_modules/a/node_modules/foo/index").C' is not assignable to parameter of type 'import("/node_modules/foo/index").C'.
-+ Types have separate declarations of a private property 'x'.
-+
-+
-+==== /index.ts (1 errors) ====
-+ import { use } from "foo/use";
-+ import { o } from "a";
-+
-+ use(o);
-+ ~
-+!!! error TS2345: Argument of type 'import("/node_modules/a/node_modules/foo/index").C' is not assignable to parameter of type 'import("/node_modules/foo/index").C'.
-+!!! error TS2345: Types have separate declarations of a private property 'x'.
-+
-+==== /node_modules/a/node_modules/foo/package.json (0 errors) ====
-+ {
-+ "name": "foo",
-+ "version": "1.2.3"
-+ }
-+
-+==== /node_modules/a/node_modules/foo/index.d.ts (0 errors) ====
-+ export class C {
-+ private x: number;
-+ }
-+
-+==== /node_modules/a/index.d.ts (0 errors) ====
-+ import { C } from "foo";
-+ export const o: C;
-+
-+==== /node_modules/foo/use.d.ts (0 errors) ====
-+ import { C } from "./index";
-+ export function use(o: C): void;
-+
-+==== /node_modules/foo/index.d.ts (0 errors) ====
-+ export class C {
-+ private x: number;
-+ }
-+
-+==== /node_modules/foo/package.json (0 errors) ====
-+ {
-+ "name": "foo",
-+ "version": "1.2.3"
-+ }
-+
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.trace.json b/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.trace.json
index dc6e3a92cf..8de27591a1 100644
--- a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.trace.json
+++ b/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage.trace.json
@@ -11,7 +11,7 @@ File '/node_modules/foo/use.tsx' does not exist.
File '/node_modules/foo/use.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/node_modules/foo/use.d.ts', result '/node_modules/foo/use.d.ts'.
-======== Module name 'foo/use' was successfully resolved to '/node_modules/foo/use.d.ts' with Package ID 'foo@1.2.3'. ========
+======== Module name 'foo/use' was successfully resolved to '/node_modules/foo/use.d.ts' with Package ID 'foo/use.d.ts@1.2.3'. ========
======== Resolving module 'a' from '/index.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -58,4 +58,4 @@ File '/node_modules/a/node_modules/foo/index.tsx' does not exist.
File '/node_modules/a/node_modules/foo/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/node_modules/a/node_modules/foo/index.d.ts', result '/node_modules/a/node_modules/foo/index.d.ts'.
-======== Module name 'foo' was successfully resolved to '/node_modules/a/node_modules/foo/index.d.ts' with Package ID 'foo@1.2.3'. ========
+======== Module name 'foo' was successfully resolved to '/node_modules/a/node_modules/foo/index.d.ts' with Package ID 'foo/index.d.ts@1.2.3'. ========
diff --git a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.errors.txt b/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.errors.txt
deleted file mode 100644
index 19026366ac..0000000000
--- a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.errors.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-/index.ts(4,5): error TS2345: Argument of type 'import("/node_modules/a/node_modules/@foo/bar/index").C' is not assignable to parameter of type 'import("/node_modules/@foo/bar/index").C'.
- Types have separate declarations of a private property 'x'.
-
-
-==== /index.ts (1 errors) ====
- import { use } from "@foo/bar/use";
- import { o } from "a";
-
- use(o);
- ~
-!!! error TS2345: Argument of type 'import("/node_modules/a/node_modules/@foo/bar/index").C' is not assignable to parameter of type 'import("/node_modules/@foo/bar/index").C'.
-!!! error TS2345: Types have separate declarations of a private property 'x'.
-
-==== /node_modules/a/node_modules/@foo/bar/package.json (0 errors) ====
- {
- "name": "@foo/bar",
- "version": "1.2.3"
- }
-
-==== /node_modules/a/node_modules/@foo/bar/index.d.ts (0 errors) ====
- export class C {
- private x: number;
- }
-
-==== /node_modules/a/index.d.ts (0 errors) ====
- import { C } from "@foo/bar";
- export const o: C;
-
-==== /node_modules/@foo/bar/use.d.ts (0 errors) ====
- import { C } from "./index";
- export function use(o: C): void;
-
-==== /node_modules/@foo/bar/index.d.ts (0 errors) ====
- export class C {
- private x: number;
- }
-
-==== /node_modules/@foo/bar/package.json (0 errors) ====
- {
- "name": "@foo/bar",
- "version": "1.2.3"
- }
-
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.errors.txt.diff
deleted file mode 100644
index 5fd8e03f0b..0000000000
--- a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.errors.txt.diff
+++ /dev/null
@@ -1,47 +0,0 @@
---- old.duplicatePackage_relativeImportWithinPackage_scoped.errors.txt
-+++ new.duplicatePackage_relativeImportWithinPackage_scoped.errors.txt
-@@= skipped -0, +0 lines =@@
--
-+/index.ts(4,5): error TS2345: Argument of type 'import("/node_modules/a/node_modules/@foo/bar/index").C' is not assignable to parameter of type 'import("/node_modules/@foo/bar/index").C'.
-+ Types have separate declarations of a private property 'x'.
-+
-+
-+==== /index.ts (1 errors) ====
-+ import { use } from "@foo/bar/use";
-+ import { o } from "a";
-+
-+ use(o);
-+ ~
-+!!! error TS2345: Argument of type 'import("/node_modules/a/node_modules/@foo/bar/index").C' is not assignable to parameter of type 'import("/node_modules/@foo/bar/index").C'.
-+!!! error TS2345: Types have separate declarations of a private property 'x'.
-+
-+==== /node_modules/a/node_modules/@foo/bar/package.json (0 errors) ====
-+ {
-+ "name": "@foo/bar",
-+ "version": "1.2.3"
-+ }
-+
-+==== /node_modules/a/node_modules/@foo/bar/index.d.ts (0 errors) ====
-+ export class C {
-+ private x: number;
-+ }
-+
-+==== /node_modules/a/index.d.ts (0 errors) ====
-+ import { C } from "@foo/bar";
-+ export const o: C;
-+
-+==== /node_modules/@foo/bar/use.d.ts (0 errors) ====
-+ import { C } from "./index";
-+ export function use(o: C): void;
-+
-+==== /node_modules/@foo/bar/index.d.ts (0 errors) ====
-+ export class C {
-+ private x: number;
-+ }
-+
-+==== /node_modules/@foo/bar/package.json (0 errors) ====
-+ {
-+ "name": "@foo/bar",
-+ "version": "1.2.3"
-+ }
-+
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.trace.json b/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.trace.json
index 9e9981afde..39f2d2b98b 100644
--- a/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.trace.json
+++ b/testdata/baselines/reference/submodule/compiler/duplicatePackage_relativeImportWithinPackage_scoped.trace.json
@@ -11,7 +11,7 @@ File '/node_modules/@foo/bar/use.tsx' does not exist.
File '/node_modules/@foo/bar/use.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/node_modules/@foo/bar/use.d.ts', result '/node_modules/@foo/bar/use.d.ts'.
-======== Module name '@foo/bar/use' was successfully resolved to '/node_modules/@foo/bar/use.d.ts' with Package ID '@foo/bar@1.2.3'. ========
+======== Module name '@foo/bar/use' was successfully resolved to '/node_modules/@foo/bar/use.d.ts' with Package ID '@foo/bar/use.d.ts@1.2.3'. ========
======== Resolving module 'a' from '/index.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -58,4 +58,4 @@ File '/node_modules/a/node_modules/@foo/bar/index.tsx' does not exist.
File '/node_modules/a/node_modules/@foo/bar/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/node_modules/a/node_modules/@foo/bar/index.d.ts', result '/node_modules/a/node_modules/@foo/bar/index.d.ts'.
-======== Module name '@foo/bar' was successfully resolved to '/node_modules/a/node_modules/@foo/bar/index.d.ts' with Package ID '@foo/bar@1.2.3'. ========
+======== Module name '@foo/bar' was successfully resolved to '/node_modules/a/node_modules/@foo/bar/index.d.ts' with Package ID '@foo/bar/index.d.ts@1.2.3'. ========
diff --git a/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot.trace.json b/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot.trace.json
index f47943dc9e..642813b1a2 100644
--- a/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot.trace.json
+++ b/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot.trace.json
@@ -25,4 +25,4 @@ File '/node_modules/foo/bar.jsx' does not exist.
File '/node_modules/foo/bar/index.js' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/node_modules/foo/bar/index.js', result '/node_modules/foo/bar/index.js'.
-======== Module name 'foo/bar' was successfully resolved to '/node_modules/foo/bar/index.js' with Package ID 'foo@1.2.3'. ========
+======== Module name 'foo/bar' was successfully resolved to '/node_modules/foo/bar/index.js' with Package ID 'foo/bar/index.js@1.2.3'. ========
diff --git a/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json b/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json
index 6dd76efa8d..c75b64190d 100644
--- a/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json
+++ b/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json
@@ -25,4 +25,4 @@ File '/node_modules/foo/@bar.jsx' does not exist.
File '/node_modules/foo/@bar/index.js' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/node_modules/foo/@bar/index.js', result '/node_modules/foo/@bar/index.js'.
-======== Module name 'foo/@bar' was successfully resolved to '/node_modules/foo/@bar/index.js' with Package ID 'foo@1.2.3'. ========
+======== Module name 'foo/@bar' was successfully resolved to '/node_modules/foo/@bar/index.js' with Package ID 'foo/@bar/index.js@1.2.3'. ========
diff --git a/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot_mainFieldInSubDirectory.trace.json b/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot_mainFieldInSubDirectory.trace.json
index eeba5d48f4..9ab3791dde 100644
--- a/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot_mainFieldInSubDirectory.trace.json
+++ b/testdata/baselines/reference/submodule/compiler/moduleResolution_packageJson_yesAtPackageRoot_mainFieldInSubDirectory.trace.json
@@ -18,4 +18,4 @@ File '/node_modules/foo/src/index.tsx' does not exist.
File '/node_modules/foo/src/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/node_modules/foo/src/index.d.ts', result '/node_modules/foo/src/index.d.ts'.
-======== Module name 'foo' was successfully resolved to '/node_modules/foo/src/index.d.ts' with Package ID 'foo@1.2.3'. ========
+======== Module name 'foo' was successfully resolved to '/node_modules/foo/src/index.d.ts' with Package ID 'foo/src/index.d.ts@1.2.3'. ========
diff --git a/testdata/baselines/reference/submodule/compiler/reactJsxReactResolvedNodeNext.trace.json b/testdata/baselines/reference/submodule/compiler/reactJsxReactResolvedNodeNext.trace.json
index 590f425b3a..028a3d5f62 100644
--- a/testdata/baselines/reference/submodule/compiler/reactJsxReactResolvedNodeNext.trace.json
+++ b/testdata/baselines/reference/submodule/compiler/reactJsxReactResolvedNodeNext.trace.json
@@ -10,7 +10,7 @@ Found 'package.json' at '/.src/node_modules/@types/react/package.json'.
File '/.src/node_modules/@types/react/jsx-runtime.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/@types/react/jsx-runtime.d.ts', result '/.src/node_modules/@types/react/jsx-runtime.d.ts'.
-======== Module name 'react/jsx-runtime' was successfully resolved to '/.src/node_modules/@types/react/jsx-runtime.d.ts' with Package ID '@types/react@0.0.1'. ========
+======== Module name 'react/jsx-runtime' was successfully resolved to '/.src/node_modules/@types/react/jsx-runtime.d.ts' with Package ID '@types/react/jsx-runtime.d.ts@0.0.1'. ========
======== Resolving module './' from '/.src/node_modules/@types/react/jsx-runtime.d.ts'. ========
Module resolution kind is not specified, using 'NodeNext'.
Resolving in CJS mode with conditions 'require', 'types', 'node'.
diff --git a/testdata/baselines/reference/submodule/conformance/customConditions(resolvepackagejsonexports=false).trace.json b/testdata/baselines/reference/submodule/conformance/customConditions(resolvepackagejsonexports=false).trace.json
index 2f3ee4888b..96a621363a 100644
--- a/testdata/baselines/reference/submodule/conformance/customConditions(resolvepackagejsonexports=false).trace.json
+++ b/testdata/baselines/reference/submodule/conformance/customConditions(resolvepackagejsonexports=false).trace.json
@@ -18,4 +18,4 @@ File '/node_modules/lodash/index.tsx' does not exist.
File '/node_modules/lodash/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/node_modules/lodash/index.d.ts', result '/node_modules/lodash/index.d.ts'.
-======== Module name 'lodash' was successfully resolved to '/node_modules/lodash/index.d.ts' with Package ID 'lodash@1.0.0'. ========
+======== Module name 'lodash' was successfully resolved to '/node_modules/lodash/index.d.ts' with Package ID 'lodash/index.d.ts@1.0.0'. ========
diff --git a/testdata/baselines/reference/submodule/conformance/typesVersions.ambientModules.trace.json b/testdata/baselines/reference/submodule/conformance/typesVersions.ambientModules.trace.json
index 3880078ee4..3cd5db8e87 100644
--- a/testdata/baselines/reference/submodule/conformance/typesVersions.ambientModules.trace.json
+++ b/testdata/baselines/reference/submodule/conformance/typesVersions.ambientModules.trace.json
@@ -21,7 +21,7 @@ File '/.src/node_modules/ext/ts3.1/index.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/index.d.ts', result '/.src/node_modules/ext/ts3.1/index.d.ts'.
-======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext/ts3.1/index.d.ts@1.0.0'. ========
======== Resolving module 'ext/other' from '/.src/main.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
diff --git a/testdata/baselines/reference/submodule/conformance/typesVersions.multiFile.trace.json b/testdata/baselines/reference/submodule/conformance/typesVersions.multiFile.trace.json
index 27fef0f583..dd86ae732a 100644
--- a/testdata/baselines/reference/submodule/conformance/typesVersions.multiFile.trace.json
+++ b/testdata/baselines/reference/submodule/conformance/typesVersions.multiFile.trace.json
@@ -21,7 +21,7 @@ File '/.src/node_modules/ext/ts3.1/index.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/index.d.ts', result '/.src/node_modules/ext/ts3.1/index.d.ts'.
-======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext/ts3.1/index.d.ts@1.0.0'. ========
======== Resolving module 'ext/other' from '/.src/main.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -39,4 +39,4 @@ File '/.src/node_modules/ext/ts3.1/other.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/other.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/other.d.ts', result '/.src/node_modules/ext/ts3.1/other.d.ts'.
-======== Module name 'ext/other' was successfully resolved to '/.src/node_modules/ext/ts3.1/other.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext/other' was successfully resolved to '/.src/node_modules/ext/ts3.1/other.d.ts' with Package ID 'ext/ts3.1/other.d.ts@1.0.0'. ========
diff --git a/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.ambient.trace.json b/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.ambient.trace.json
index 3880078ee4..3cd5db8e87 100644
--- a/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.ambient.trace.json
+++ b/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.ambient.trace.json
@@ -21,7 +21,7 @@ File '/.src/node_modules/ext/ts3.1/index.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/index.d.ts', result '/.src/node_modules/ext/ts3.1/index.d.ts'.
-======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext/ts3.1/index.d.ts@1.0.0'. ========
======== Resolving module 'ext/other' from '/.src/main.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
diff --git a/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFile.trace.json b/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFile.trace.json
index 27fef0f583..dd86ae732a 100644
--- a/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFile.trace.json
+++ b/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFile.trace.json
@@ -21,7 +21,7 @@ File '/.src/node_modules/ext/ts3.1/index.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/index.d.ts', result '/.src/node_modules/ext/ts3.1/index.d.ts'.
-======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext/ts3.1/index.d.ts@1.0.0'. ========
======== Resolving module 'ext/other' from '/.src/main.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -39,4 +39,4 @@ File '/.src/node_modules/ext/ts3.1/other.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/other.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/other.d.ts', result '/.src/node_modules/ext/ts3.1/other.d.ts'.
-======== Module name 'ext/other' was successfully resolved to '/.src/node_modules/ext/ts3.1/other.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext/other' was successfully resolved to '/.src/node_modules/ext/ts3.1/other.d.ts' with Package ID 'ext/ts3.1/other.d.ts@1.0.0'. ========
diff --git a/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.trace.json b/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.trace.json
index e5390b7825..539fad4d83 100644
--- a/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.trace.json
+++ b/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.trace.json
@@ -21,7 +21,7 @@ File '/.src/node_modules/ext/ts3.1/index.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/index.d.ts', result '/.src/node_modules/ext/ts3.1/index.d.ts'.
-======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext/ts3.1/index.d.ts@1.0.0'. ========
======== Resolving module 'ext/other' from '/.src/main.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -39,7 +39,7 @@ File '/.src/node_modules/ext/ts3.1/other.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/other.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/other.d.ts', result '/.src/node_modules/ext/ts3.1/other.d.ts'.
-======== Module name 'ext/other' was successfully resolved to '/.src/node_modules/ext/ts3.1/other.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext/other' was successfully resolved to '/.src/node_modules/ext/ts3.1/other.d.ts' with Package ID 'ext/ts3.1/other.d.ts@1.0.0'. ========
======== Resolving module '../' from '/.src/node_modules/ext/ts3.1/index.d.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
diff --git a/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFileBackReferenceToUnmapped.trace.json b/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFileBackReferenceToUnmapped.trace.json
index 59839558cf..1147e4d6c5 100644
--- a/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFileBackReferenceToUnmapped.trace.json
+++ b/testdata/baselines/reference/submodule/conformance/typesVersionsDeclarationEmit.multiFileBackReferenceToUnmapped.trace.json
@@ -21,7 +21,7 @@ File '/.src/node_modules/ext/ts3.1/index.tsx' does not exist.
File '/.src/node_modules/ext/ts3.1/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/ts3.1/index.d.ts', result '/.src/node_modules/ext/ts3.1/index.d.ts'.
-======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext' was successfully resolved to '/.src/node_modules/ext/ts3.1/index.d.ts' with Package ID 'ext/ts3.1/index.d.ts@1.0.0'. ========
======== Resolving module 'ext/other' from '/.src/main.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -37,7 +37,7 @@ File '/.src/node_modules/ext/other.tsx' does not exist.
File '/.src/node_modules/ext/other.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/.src/node_modules/ext/other.d.ts', result '/.src/node_modules/ext/other.d.ts'.
-======== Module name 'ext/other' was successfully resolved to '/.src/node_modules/ext/other.d.ts' with Package ID 'ext@1.0.0'. ========
+======== Module name 'ext/other' was successfully resolved to '/.src/node_modules/ext/other.d.ts' with Package ID 'ext/other.d.ts@1.0.0'. ========
======== Resolving module '../other' from '/.src/node_modules/ext/ts3.1/index.d.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
diff --git a/testdata/baselines/reference/submodule/fourslash/goToDefinition/duplicatePackageServices.baseline.jsonc b/testdata/baselines/reference/submodule/fourslash/goToDefinition/duplicatePackageServices.baseline.jsonc
new file mode 100644
index 0000000000..f2710c3963
--- /dev/null
+++ b/testdata/baselines/reference/submodule/fourslash/goToDefinition/duplicatePackageServices.baseline.jsonc
@@ -0,0 +1,21 @@
+// === goToDefinition ===
+// === /node_modules/a/node_modules/x/index.d.ts ===
+// <|export default class [|X|] {
+// private x: number;
+// }|>
+
+// === /node_modules/a/index.d.ts ===
+// import [|X|]/*GOTO DEF*/ from "x";
+// export function a(x: X): void;
+
+
+
+// === goToDefinition ===
+// === /node_modules/b/node_modules/x/index.d.ts ===
+// <|export default class [|X|] {
+// private x: number;
+// }|>
+
+// === /node_modules/b/index.d.ts ===
+// import [|X|]/*GOTO DEF*/ from "x";
+// export const b: X;
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/fourslash/goToDefinition/duplicatePackageServices.baseline.jsonc.diff b/testdata/baselines/reference/submodule/fourslash/goToDefinition/duplicatePackageServices.baseline.jsonc.diff
new file mode 100644
index 0000000000..15df7ad52a
--- /dev/null
+++ b/testdata/baselines/reference/submodule/fourslash/goToDefinition/duplicatePackageServices.baseline.jsonc.diff
@@ -0,0 +1,11 @@
+--- old.duplicatePackageServices.baseline.jsonc
++++ new.duplicatePackageServices.baseline.jsonc
+@@= skipped -10, +10 lines =@@
+
+
+ // === goToDefinition ===
+-// === /node_modules/a/node_modules/x/index.d.ts ===
++// === /node_modules/b/node_modules/x/index.d.ts ===
+ // <|export default class [|X|] {
+ // private x: number;
+ // }|>
\ No newline at end of file
diff --git a/testdata/baselines/reference/tsbuild/commandLine/help.js b/testdata/baselines/reference/tsbuild/commandLine/help.js
index 856a112bfc..e265cee7a4 100644
--- a/testdata/baselines/reference/tsbuild/commandLine/help.js
+++ b/testdata/baselines/reference/tsbuild/commandLine/help.js
@@ -104,6 +104,11 @@ Disable full type checking (only critical parse and emit errors will be reported
type: boolean
default: false
+[94m--disablePackageDeduplication[39m
+Disable deduplication of packages with the same name and version.
+type: boolean
+default: false
+
[94m--noEmit[39m
Disable emitting files from a compilation.
type: boolean
diff --git a/testdata/baselines/reference/tsbuild/commandLine/locale.js b/testdata/baselines/reference/tsbuild/commandLine/locale.js
index 26271d5f01..002c429519 100644
--- a/testdata/baselines/reference/tsbuild/commandLine/locale.js
+++ b/testdata/baselines/reference/tsbuild/commandLine/locale.js
@@ -104,6 +104,11 @@ Disable full type checking (only critical parse and emit errors will be reported
type: boolean
default: false
+[94m--disablePackageDeduplication[39m
+Disable deduplication of packages with the same name and version.
+type: boolean
+default: false
+
[94m--noEmit[39m
Disable emitting files from a compilation.
type: boolean
diff --git a/testdata/baselines/reference/tsbuild/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-preserveSymlinks.js b/testdata/baselines/reference/tsbuild/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-preserveSymlinks.js
index 45b4bc5898..034091b199 100644
--- a/testdata/baselines/reference/tsbuild/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-preserveSymlinks.js
+++ b/testdata/baselines/reference/tsbuild/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-preserveSymlinks.js
@@ -88,7 +88,7 @@ File '/user/username/projects/myproject/node_modules/pkg2/build/index.ts' does n
File '/user/username/projects/myproject/node_modules/pkg2/build/index.tsx' does not exist.
File '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
-======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts' with Package ID 'pkg2@1.0.0'. ========
+======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts' with Package ID 'pkg2/build/index.d.ts@1.0.0'. ========
======== Resolving module 'const' from '/user/username/projects/myproject/packages/pkg2/index.ts'. ========
Using compiler options of project reference redirect '/user/username/projects/myproject/packages/pkg2/tsconfig.json'.
Module resolution kind is not specified, using 'Bundler'.
diff --git a/testdata/baselines/reference/tsbuild/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly.js b/testdata/baselines/reference/tsbuild/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly.js
index 3744082d9d..e121e2932d 100644
--- a/testdata/baselines/reference/tsbuild/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly.js
+++ b/testdata/baselines/reference/tsbuild/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly.js
@@ -89,7 +89,7 @@ File '/user/username/projects/myproject/node_modules/pkg2/build/index.tsx' does
File '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts', result '/user/username/projects/myproject/packages/pkg2/build/index.d.ts'.
-======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/packages/pkg2/build/index.d.ts' with Package ID 'pkg2@1.0.0'. ========
+======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/packages/pkg2/build/index.d.ts' with Package ID 'pkg2/build/index.d.ts@1.0.0'. ========
======== Resolving module 'const' from '/user/username/projects/myproject/packages/pkg2/index.ts'. ========
Using compiler options of project reference redirect '/user/username/projects/myproject/packages/pkg2/tsconfig.json'.
Module resolution kind is not specified, using 'Bundler'.
diff --git a/testdata/baselines/reference/tsbuildWatch/moduleResolution/build-mode-watches-for-changes-to-package-json-main-fields.js b/testdata/baselines/reference/tsbuildWatch/moduleResolution/build-mode-watches-for-changes-to-package-json-main-fields.js
index e9cdbb7c50..098eebd9bc 100644
--- a/testdata/baselines/reference/tsbuildWatch/moduleResolution/build-mode-watches-for-changes-to-package-json-main-fields.js
+++ b/testdata/baselines/reference/tsbuildWatch/moduleResolution/build-mode-watches-for-changes-to-package-json-main-fields.js
@@ -86,7 +86,7 @@ File '/user/username/projects/myproject/node_modules/pkg2/build/index.tsx' does
File '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts', result '/user/username/projects/myproject/packages/pkg2/build/index.d.ts'.
-======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/packages/pkg2/build/index.d.ts' with Package ID 'pkg2@1.0.0'. ========
+======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/packages/pkg2/build/index.d.ts' with Package ID 'pkg2/build/index.d.ts@1.0.0'. ========
======== Resolving module './const.js' from '/user/username/projects/myproject/packages/pkg2/index.ts'. ========
Using compiler options of project reference redirect '/user/username/projects/myproject/packages/pkg2/tsconfig.json'.
Module resolution kind is not specified, using 'Bundler'.
diff --git a/testdata/baselines/reference/tsbuildWatch/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-cts-and-mts-extensions.js b/testdata/baselines/reference/tsbuildWatch/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-cts-and-mts-extensions.js
index 44005f7815..c9827a6f33 100644
--- a/testdata/baselines/reference/tsbuildWatch/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-cts-and-mts-extensions.js
+++ b/testdata/baselines/reference/tsbuildWatch/moduleResolution/resolves-specifier-in-output-declaration-file-from-referenced-project-correctly-with-cts-and-mts-extensions.js
@@ -85,7 +85,7 @@ File '/user/username/projects/myproject/node_modules/pkg2/build/index.tsx' does
File '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/node_modules/pkg2/build/index.d.ts', result '/user/username/projects/myproject/packages/pkg2/build/index.d.ts'.
-======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/packages/pkg2/build/index.d.ts' with Package ID 'pkg2@1.0.0'. ========
+======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/packages/pkg2/build/index.d.ts' with Package ID 'pkg2/build/index.d.ts@1.0.0'. ========
======== Resolving module './const.cjs' from '/user/username/projects/myproject/packages/pkg2/index.ts'. ========
Using compiler options of project reference redirect '/user/username/projects/myproject/packages/pkg2/tsconfig.json'.
Module resolution kind is not specified, using 'Node16'.
@@ -383,7 +383,7 @@ File '/user/username/projects/myproject/node_modules/pkg2/build/index.cts' does
File '/user/username/projects/myproject/node_modules/pkg2/build/index.d.cts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/node_modules/pkg2/build/index.d.cts', result '/user/username/projects/myproject/packages/pkg2/build/index.d.cts'.
-======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/packages/pkg2/build/index.d.cts' with Package ID 'pkg2@1.0.0'. ========
+======== Module name 'pkg2' was successfully resolved to '/user/username/projects/myproject/packages/pkg2/build/index.d.cts' with Package ID 'pkg2/build/index.d.cts@1.0.0'. ========
======== Resolving module './const.cjs' from '/user/username/projects/myproject/packages/pkg2/index.cts'. ========
Using compiler options of project reference redirect '/user/username/projects/myproject/packages/pkg2/tsconfig.json'.
Module resolution kind is not specified, using 'Node16'.
diff --git a/testdata/baselines/reference/tsc/commandLine/help-all.js b/testdata/baselines/reference/tsc/commandLine/help-all.js
index 5e561d8833..426564f638 100644
--- a/testdata/baselines/reference/tsc/commandLine/help-all.js
+++ b/testdata/baselines/reference/tsc/commandLine/help-all.js
@@ -221,6 +221,11 @@ Ensure 'use strict' is always emitted.
type: boolean
default: `false`, unless `strict` is set
+[94m--disablePackageDeduplication[39m
+Disable deduplication of packages with the same name and version.
+type: boolean
+default: false
+
[94m--exactOptionalPropertyTypes[39m
Interpret optional property types as written, rather than adding 'undefined'.
type: boolean
diff --git a/testdata/baselines/reference/tsc/declarationEmit/when-pkg-references-sibling-package-through-indirect-symlink.js b/testdata/baselines/reference/tsc/declarationEmit/when-pkg-references-sibling-package-through-indirect-symlink.js
index 710a6e7b26..914182b948 100644
--- a/testdata/baselines/reference/tsc/declarationEmit/when-pkg-references-sibling-package-through-indirect-symlink.js
+++ b/testdata/baselines/reference/tsc/declarationEmit/when-pkg-references-sibling-package-through-indirect-symlink.js
@@ -68,11 +68,11 @@ Output::
pkg1/dist/types.d.ts
Imported via './types' from file 'pkg1/dist/index.d.ts'
pkg1/dist/index.d.ts
- Imported via '@raymondfeng/pkg1' from file 'pkg2/dist/types.d.ts' with packageId '@raymondfeng/pkg1@1.0.0'
+ Imported via '@raymondfeng/pkg1' from file 'pkg2/dist/types.d.ts' with packageId '@raymondfeng/pkg1/dist/index.d.ts@1.0.0'
pkg2/dist/types.d.ts
Imported via './types' from file 'pkg2/dist/index.d.ts'
pkg2/dist/index.d.ts
- Imported via "@raymondfeng/pkg2" from file 'pkg3/src/keys.ts' with packageId '@raymondfeng/pkg2@1.0.0'
+ Imported via "@raymondfeng/pkg2" from file 'pkg3/src/keys.ts' with packageId '@raymondfeng/pkg2/dist/index.d.ts@1.0.0'
pkg3/src/keys.ts
Imported via './keys' from file 'pkg3/src/index.ts'
Matched by default include pattern '**/*'
diff --git a/testdata/baselines/reference/tsc/declarationEmit/when-same-version-is-referenced-through-source-and-another-symlinked-package-with-indirect-link.js b/testdata/baselines/reference/tsc/declarationEmit/when-same-version-is-referenced-through-source-and-another-symlinked-package-with-indirect-link.js
index 5cfa0d4d57..cef83d3a2d 100644
--- a/testdata/baselines/reference/tsc/declarationEmit/when-same-version-is-referenced-through-source-and-another-symlinked-package-with-indirect-link.js
+++ b/testdata/baselines/reference/tsc/declarationEmit/when-same-version-is-referenced-through-source-and-another-symlinked-package-with-indirect-link.js
@@ -112,7 +112,7 @@ File '/user/username/projects/myproject/plugin-one/node_modules/plugin-two/dist/
File '/user/username/projects/myproject/plugin-one/node_modules/plugin-two/dist/commonjs/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/plugin-one/node_modules/plugin-two/dist/commonjs/index.d.ts', result '/user/username/projects/myproject/plugin-two/dist/commonjs/index.d.ts'.
-======== Module name 'plugin-two' was successfully resolved to '/user/username/projects/myproject/plugin-two/dist/commonjs/index.d.ts' with Package ID 'plugin-two@0.1.3'. ========
+======== Module name 'plugin-two' was successfully resolved to '/user/username/projects/myproject/plugin-two/dist/commonjs/index.d.ts' with Package ID 'plugin-two/dist/commonjs/index.d.ts@0.1.3'. ========
======== Resolving module 'typescript-fsa' from '/user/username/projects/myproject/plugin-one/index.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -137,7 +137,7 @@ File '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/i
File '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts', result '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts'.
-======== Module name 'typescript-fsa' was successfully resolved to '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts' with Package ID 'typescript-fsa@3.0.0-beta-2'. ========
+======== Module name 'typescript-fsa' was successfully resolved to '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts' with Package ID 'typescript-fsa/index.d.ts@3.0.0-beta-2'. ========
======== Resolving module 'typescript-fsa' from '/user/username/projects/myproject/plugin-two/dist/commonjs/index.d.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -163,15 +163,15 @@ File '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/i
File '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts', result '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts'.
-======== Module name 'typescript-fsa' was successfully resolved to '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts' with Package ID 'typescript-fsa@3.0.0-beta-2'. ========
+======== Module name 'typescript-fsa' was successfully resolved to '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts' with Package ID 'typescript-fsa/index.d.ts@3.0.0-beta-2'. ========
../../../../home/src/tslibs/TS/Lib/lib.d.ts
Default library for target 'ES5'
plugin-two/node_modules/typescript-fsa/index.d.ts
- Imported via "typescript-fsa" from file 'plugin-two/dist/commonjs/index.d.ts' with packageId 'typescript-fsa@3.0.0-beta-2'
+ Imported via "typescript-fsa" from file 'plugin-two/dist/commonjs/index.d.ts' with packageId 'typescript-fsa/index.d.ts@3.0.0-beta-2'
plugin-two/dist/commonjs/index.d.ts
- Imported via "plugin-two" from file 'plugin-one/index.ts' with packageId 'plugin-two@0.1.3'
+ Imported via "plugin-two" from file 'plugin-one/index.ts' with packageId 'plugin-two/dist/commonjs/index.d.ts@0.1.3'
plugin-one/node_modules/typescript-fsa/index.d.ts
- Imported via "typescript-fsa" from file 'plugin-one/index.ts' with packageId 'typescript-fsa@3.0.0-beta-2'
+ Imported via "typescript-fsa" from file 'plugin-one/index.ts' with packageId 'typescript-fsa/index.d.ts@3.0.0-beta-2'
plugin-one/index.ts
Matched by default include pattern '**/*'
//// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib*
diff --git a/testdata/baselines/reference/tsc/declarationEmit/when-same-version-is-referenced-through-source-and-another-symlinked-package.js b/testdata/baselines/reference/tsc/declarationEmit/when-same-version-is-referenced-through-source-and-another-symlinked-package.js
index 83b1575d13..983c7cf391 100644
--- a/testdata/baselines/reference/tsc/declarationEmit/when-same-version-is-referenced-through-source-and-another-symlinked-package.js
+++ b/testdata/baselines/reference/tsc/declarationEmit/when-same-version-is-referenced-through-source-and-another-symlinked-package.js
@@ -105,7 +105,7 @@ File '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/i
File '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts', result '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts'.
-======== Module name 'typescript-fsa' was successfully resolved to '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts' with Package ID 'typescript-fsa@3.0.0-beta-2'. ========
+======== Module name 'typescript-fsa' was successfully resolved to '/user/username/projects/myproject/plugin-one/node_modules/typescript-fsa/index.d.ts' with Package ID 'typescript-fsa/index.d.ts@3.0.0-beta-2'. ========
======== Resolving module 'plugin-two' from '/user/username/projects/myproject/plugin-one/index.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'require', 'types'.
@@ -150,15 +150,15 @@ File '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/i
File '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts', result '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts'.
-======== Module name 'typescript-fsa' was successfully resolved to '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts' with Package ID 'typescript-fsa@3.0.0-beta-2'. ========
+======== Module name 'typescript-fsa' was successfully resolved to '/user/username/projects/myproject/plugin-two/node_modules/typescript-fsa/index.d.ts' with Package ID 'typescript-fsa/index.d.ts@3.0.0-beta-2'. ========
../../../../home/src/tslibs/TS/Lib/lib.d.ts
Default library for target 'ES5'
plugin-one/node_modules/typescript-fsa/index.d.ts
- Imported via "typescript-fsa" from file 'plugin-one/action.ts' with packageId 'typescript-fsa@3.0.0-beta-2'
+ Imported via "typescript-fsa" from file 'plugin-one/action.ts' with packageId 'typescript-fsa/index.d.ts@3.0.0-beta-2'
plugin-one/action.ts
Matched by default include pattern '**/*'
plugin-two/node_modules/typescript-fsa/index.d.ts
- Imported via "typescript-fsa" from file 'plugin-two/index.d.ts' with packageId 'typescript-fsa@3.0.0-beta-2'
+ Imported via "typescript-fsa" from file 'plugin-two/index.d.ts' with packageId 'typescript-fsa/index.d.ts@3.0.0-beta-2'
plugin-two/index.d.ts
Imported via "plugin-two" from file 'plugin-one/index.ts'
plugin-one/index.ts
diff --git a/testdata/baselines/reference/tsc/moduleResolution/pnpm-style-layout.js b/testdata/baselines/reference/tsc/moduleResolution/pnpm-style-layout.js
index 01e668625c..3c2149a1b2 100644
--- a/testdata/baselines/reference/tsc/moduleResolution/pnpm-style-layout.js
+++ b/testdata/baselines/reference/tsc/moduleResolution/pnpm-style-layout.js
@@ -134,7 +134,7 @@ File '/home/src/projects/component-type-checker/packages/app/node_modules/@compo
File '/home/src/projects/component-type-checker/packages/app/node_modules/@component-type-checker/sdk/src/index.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/home/src/projects/component-type-checker/packages/app/node_modules/@component-type-checker/sdk/src/index.ts', result '/home/src/projects/component-type-checker/packages/sdk/src/index.ts'.
-======== Module name '@component-type-checker/sdk' was successfully resolved to '/home/src/projects/component-type-checker/packages/sdk/src/index.ts' with Package ID '@component-type-checker/sdk1@0.0.2'. ========
+======== Module name '@component-type-checker/sdk' was successfully resolved to '/home/src/projects/component-type-checker/packages/sdk/src/index.ts' with Package ID '@component-type-checker/sdk1/src/index.ts@0.0.2'. ========
======== Resolving module '@component-type-checker/components' from '/home/src/projects/component-type-checker/packages/app/src/app.tsx'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
@@ -159,7 +159,7 @@ Resolving real path for '/home/src/projects/component-type-checker/packages/app/
Found 'package.json' at '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/package.json'.
Found peerDependency '@component-type-checker/button' with '0.0.2' version.
Resolving real path for '/home/src/projects/component-type-checker/packages/app/node_modules/@component-type-checker/components/src/index.ts', result '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/components/src/index.ts'.
-======== Module name '@component-type-checker/components' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/components/src/index.ts' with Package ID '@component-type-checker/components@0.0.1+@component-type-checker/button@0.0.2'. ========
+======== Module name '@component-type-checker/components' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/components/src/index.ts' with Package ID '@component-type-checker/components/src/index.ts@0.0.1+@component-type-checker/button@0.0.2'. ========
======== Resolving module '@component-type-checker/button' from '/home/src/projects/component-type-checker/packages/app/src/app.tsx'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
@@ -181,7 +181,7 @@ File '/home/src/projects/component-type-checker/packages/app/node_modules/@compo
File '/home/src/projects/component-type-checker/packages/app/node_modules/@component-type-checker/button/src/index.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/home/src/projects/component-type-checker/packages/app/node_modules/@component-type-checker/button/src/index.ts', result '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts'.
-======== Module name '@component-type-checker/button' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts' with Package ID '@component-type-checker/button@0.0.2'. ========
+======== Module name '@component-type-checker/button' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts' with Package ID '@component-type-checker/button/src/index.ts@0.0.2'. ========
======== Resolving module '@component-type-checker/components' from '/home/src/projects/component-type-checker/packages/sdk/src/index.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
@@ -206,7 +206,7 @@ Resolving real path for '/home/src/projects/component-type-checker/packages/sdk/
Found 'package.json' at '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/button/package.json'.
Found peerDependency '@component-type-checker/button' with '0.0.1' version.
Resolving real path for '/home/src/projects/component-type-checker/packages/sdk/node_modules/@component-type-checker/components/src/index.ts', result '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/components/src/index.ts'.
-======== Module name '@component-type-checker/components' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/components/src/index.ts' with Package ID '@component-type-checker/components@0.0.1+@component-type-checker/button@0.0.1'. ========
+======== Module name '@component-type-checker/components' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/components/src/index.ts' with Package ID '@component-type-checker/components/src/index.ts@0.0.1+@component-type-checker/button@0.0.1'. ========
======== Resolving module '@component-type-checker/button' from '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/components/src/index.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
@@ -234,7 +234,7 @@ File '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-ty
File '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/button/src/index.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/button/src/index.ts', result '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.1/node_modules/@component-type-checker/button/src/index.ts'.
-======== Module name '@component-type-checker/button' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.1/node_modules/@component-type-checker/button/src/index.ts' with Package ID '@component-type-checker/button@0.0.1'. ========
+======== Module name '@component-type-checker/button' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.1/node_modules/@component-type-checker/button/src/index.ts' with Package ID '@component-type-checker/button/src/index.ts@0.0.1'. ========
======== Resolving module '@component-type-checker/button' from '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/components/src/index.ts'. ========
Module resolution kind is not specified, using 'Bundler'.
Resolving in CJS mode with conditions 'import', 'types'.
@@ -262,20 +262,20 @@ File '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-ty
File '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts' exists - use it as a name resolution result.
'package.json' does not have a 'peerDependencies' field.
Resolving real path for '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts', result '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts'.
-======== Module name '@component-type-checker/button' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts' with Package ID '@component-type-checker/button@0.0.2'. ========
+======== Module name '@component-type-checker/button' was successfully resolved to '/home/src/projects/component-type-checker/node_modules/.pnpm/@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts' with Package ID '@component-type-checker/button/src/index.ts@0.0.2'. ========
../../../../tslibs/TS/Lib/lib.es5.d.ts
Library 'lib.es5.d.ts' specified in compilerOptions
../../node_modules/.pnpm/@component-type-checker+button@0.0.1/node_modules/@component-type-checker/button/src/index.ts
- Imported via "@component-type-checker/button" from file '../../node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/components/src/index.ts' with packageId '@component-type-checker/button@0.0.1'
+ Imported via "@component-type-checker/button" from file '../../node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/components/src/index.ts' with packageId '@component-type-checker/button/src/index.ts@0.0.1'
../../node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.1/node_modules/@component-type-checker/components/src/index.ts
- Imported via "@component-type-checker/components" from file '../sdk/src/index.ts' with packageId '@component-type-checker/components@0.0.1+@component-type-checker/button@0.0.1'
+ Imported via "@component-type-checker/components" from file '../sdk/src/index.ts' with packageId '@component-type-checker/components/src/index.ts@0.0.1+@component-type-checker/button@0.0.1'
../sdk/src/index.ts
- Imported via "@component-type-checker/sdk" from file 'src/app.tsx' with packageId '@component-type-checker/sdk1@0.0.2'
+ Imported via "@component-type-checker/sdk" from file 'src/app.tsx' with packageId '@component-type-checker/sdk1/src/index.ts@0.0.2'
../../node_modules/.pnpm/@component-type-checker+button@0.0.2/node_modules/@component-type-checker/button/src/index.ts
- Imported via "@component-type-checker/button" from file '../../node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/components/src/index.ts' with packageId '@component-type-checker/button@0.0.2'
- Imported via "@component-type-checker/button" from file 'src/app.tsx' with packageId '@component-type-checker/button@0.0.2'
+ Imported via "@component-type-checker/button" from file '../../node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/components/src/index.ts' with packageId '@component-type-checker/button/src/index.ts@0.0.2'
+ Imported via "@component-type-checker/button" from file 'src/app.tsx' with packageId '@component-type-checker/button/src/index.ts@0.0.2'
../../node_modules/.pnpm/@component-type-checker+components@0.0.1_@component-type-checker+button@0.0.2/node_modules/@component-type-checker/components/src/index.ts
- Imported via "@component-type-checker/components" from file 'src/app.tsx' with packageId '@component-type-checker/components@0.0.1+@component-type-checker/button@0.0.2'
+ Imported via "@component-type-checker/components" from file 'src/app.tsx' with packageId '@component-type-checker/components/src/index.ts@0.0.1+@component-type-checker/button@0.0.2'
src/app.tsx
Matched by include pattern 'src' in 'tsconfig.json'
//// [/home/src/projects/component-type-checker/packages/app/dist/app.js] *new*