Skip to content

Commit 4a3b38b

Browse files
author
Andy Hanson
committed
Refactor how we (internally) expose JS module resolution
Also, provide a useful error if resolution fails.
1 parent dce7fca commit 4a3b38b

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

src/compiler/moduleNameResolver.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
/// <reference path="diagnosticInformationMap.generated.ts" />
33

44
namespace ts {
5-
65
/* @internal */
76
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
87
export function trace(host: ModuleResolutionHost): void {
@@ -15,6 +14,7 @@ namespace ts {
1514
}
1615

1716
/** Array that is only intended to be pushed to, never read. */
17+
/* @internal */
1818
export interface Push<T> {
1919
push(value: T): void;
2020
}
@@ -675,12 +675,25 @@ namespace ts {
675675
}
676676

677677
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
678-
return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /*jsOnly*/ false);
678+
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
679679
}
680680

681+
/**
682+
* Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations.
683+
* No way to do this with `require()`: https://github.com/nodejs/node/issues/5963
684+
* Throws an error if the module can't be resolved.
685+
*/
681686
/* @internal */
682-
export function nodeModuleNameResolverWorker(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, jsOnly = false): ResolvedModuleWithFailedLookupLocations {
683-
const containingDirectory = getDirectoryPath(containingFile);
687+
export function resolveJavaScriptModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string {
688+
const { resolvedModule, failedLookupLocations } =
689+
nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true);
690+
if (!resolvedModule) {
691+
throw new Error(`Could not resolve JS module ${moduleName} starting at ${initialDir}. Looked in: ${failedLookupLocations.join(", ")}`);
692+
}
693+
return resolvedModule.resolvedFileName;
694+
}
695+
696+
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations {
684697
const traceEnabled = isTraceEnabled(compilerOptions, host);
685698

686699
const failedLookupLocations: string[] = [];

src/server/server.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -702,12 +702,11 @@ namespace ts.server {
702702
}
703703

704704
sys.require = (initialDir: string, moduleName: string): RequireResult => {
705-
const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, undefined, /*jsOnly*/ true);
706705
try {
707-
return { module: require(result.resolvedModule.resolvedFileName), error: undefined };
706+
return { module: require(resolveJavaScriptModule(moduleName, initialDir, sys)), error: undefined };
708707
}
709-
catch (e) {
710-
return { module: undefined, error: e };
708+
catch (error) {
709+
return { module: undefined, error };
711710
}
712711
};
713712

0 commit comments

Comments
 (0)