Skip to content

Commit da58fb5

Browse files
committed
JS: Resolve relative imports across real and virtual source roots
1 parent d3b9ebe commit da58fb5

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

javascript/extractor/lib/typescript/src/common.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,19 @@ export class Project {
7171
redirectedReference: ts.ResolvedProjectReference,
7272
options: ts.CompilerOptions) {
7373

74+
let oppositePath =
75+
this.virtualSourceRoot.toVirtualPath(containingFile) ||
76+
this.virtualSourceRoot.fromVirtualPath(containingFile);
77+
7478
const { host, resolutionCache } = this;
7579
return moduleNames.map((moduleName) => {
7680
let redirected = this.redirectModuleName(moduleName, containingFile, options);
7781
if (redirected != null) return redirected;
82+
if (oppositePath != null) {
83+
// If the containing file is in the virtual source root, try resolving from the real source root, and vice versa.
84+
redirected = ts.resolveModuleName(moduleName, oppositePath, options, host, resolutionCache).resolvedModule;
85+
if (redirected != null) return redirected;
86+
}
7887
return ts.resolveModuleName(moduleName, containingFile, options, host, resolutionCache).resolvedModule;
7988
});
8089
}
@@ -90,15 +99,7 @@ export class Project {
9099

91100
// Get the overridden location of this package, if one exists.
92101
let packageEntryPoint = this.packageEntryPoints.get(packageName);
93-
if (packageEntryPoint == null) {
94-
// The package is not overridden, but we have established that it begins with a valid package name.
95-
// Do a lookup in the virtual source root (where dependencies are installed) by changing the 'containing file'.
96-
let virtualContainingFile = this.virtualSourceRoot.toVirtualPath(containingFile);
97-
if (virtualContainingFile != null) {
98-
return ts.resolveModuleName(moduleName, virtualContainingFile, options, this.host, this.resolutionCache).resolvedModule;
99-
}
100-
return null;
101-
}
102+
if (packageEntryPoint == null) return null;
102103

103104
// If the requested module name is exactly the overridden package name,
104105
// return the entry point file (it is not necessarily called `index.ts`).

javascript/extractor/lib/typescript/src/virtual_source_root.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,25 @@ export class VirtualSourceRoot {
1616
private virtualSourceRoot: string | null,
1717
) {}
1818

19+
private static translate(oldRoot: string, newRoot: string, path: string) {
20+
if (!oldRoot || !newRoot) return null;
21+
let relative = pathlib.relative(oldRoot, path);
22+
if (relative.startsWith('..') || pathlib.isAbsolute(relative)) return null;
23+
return pathlib.join(newRoot, relative);
24+
}
25+
1926
/**
2027
* Maps a path under the real source root to the corresponding path in the virtual source root.
2128
*/
2229
public toVirtualPath(path: string) {
23-
if (!this.virtualSourceRoot || !this.sourceRoot) return null;
24-
let relative = pathlib.relative(this.sourceRoot, path);
25-
if (relative.startsWith('..') || pathlib.isAbsolute(relative)) return null;
26-
return pathlib.join(this.virtualSourceRoot, relative);
30+
return VirtualSourceRoot.translate(this.sourceRoot, this.virtualSourceRoot, path);
31+
}
32+
33+
/**
34+
* Maps a path under the virtual source root to the corresponding path in the real source root.
35+
*/
36+
public fromVirtualPath(path: string) {
37+
return VirtualSourceRoot.translate(this.virtualSourceRoot, this.sourceRoot, path);
2738
}
2839

2940
/**

0 commit comments

Comments
 (0)