diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts
index d511b31b331..f984c12fb68 100644
--- a/src/compiler/moduleNameResolver.ts
+++ b/src/compiler/moduleNameResolver.ts
@@ -2,7 +2,6 @@
///
namespace ts {
-
/* @internal */
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
export function trace(host: ModuleResolutionHost): void {
@@ -15,6 +14,7 @@ namespace ts {
}
/** Array that is only intended to be pushed to, never read. */
+ /* @internal */
export interface Push {
push(value: T): void;
}
@@ -675,12 +675,25 @@ namespace ts {
}
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
- return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /*jsOnly*/ false);
+ return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
}
+ /**
+ * Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations.
+ * No way to do this with `require()`: https://github.com/nodejs/node/issues/5963
+ * Throws an error if the module can't be resolved.
+ */
/* @internal */
- export function nodeModuleNameResolverWorker(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, jsOnly = false): ResolvedModuleWithFailedLookupLocations {
- const containingDirectory = getDirectoryPath(containingFile);
+ export function resolveJavaScriptModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string {
+ const { resolvedModule, failedLookupLocations } =
+ nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true);
+ if (!resolvedModule) {
+ throw new Error(`Could not resolve JS module ${moduleName} starting at ${initialDir}. Looked in: ${failedLookupLocations.join(", ")}`);
+ }
+ return resolvedModule.resolvedFileName;
+ }
+
+ function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
const failedLookupLocations: string[] = [];
diff --git a/src/server/server.ts b/src/server/server.ts
index 79cfc3882ae..67640e430d8 100644
--- a/src/server/server.ts
+++ b/src/server/server.ts
@@ -708,12 +708,11 @@ namespace ts.server {
}
sys.require = (initialDir: string, moduleName: string): RequireResult => {
- const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, /*cache*/ undefined, /*jsOnly*/ true);
try {
- return { module: require(result.resolvedModule.resolvedFileName), error: undefined };
+ return { module: require(resolveJavaScriptModule(moduleName, initialDir, sys)), error: undefined };
}
- catch (e) {
- return { module: undefined, error: e };
+ catch (error) {
+ return { module: undefined, error };
}
};