| import { createMatchPath } from "./match-path-sync"; |
| import { configLoader, ExplicitParams } from "./config-loader"; |
| import { options } from "./options"; |
| |
| const noOp = (): void => void 0; |
| |
| function getCoreModules( |
| builtinModules: string[] | undefined |
| ): { [key: string]: boolean } { |
| builtinModules = builtinModules || [ |
| "assert", |
| "buffer", |
| "child_process", |
| "cluster", |
| "crypto", |
| "dgram", |
| "dns", |
| "domain", |
| "events", |
| "fs", |
| "http", |
| "https", |
| "net", |
| "os", |
| "path", |
| "punycode", |
| "querystring", |
| "readline", |
| "stream", |
| "string_decoder", |
| "tls", |
| "tty", |
| "url", |
| "util", |
| "v8", |
| "vm", |
| "zlib", |
| ]; |
| |
| const coreModules: { [key: string]: boolean } = {}; |
| for (let module of builtinModules) { |
| coreModules[module] = true; |
| } |
| |
| return coreModules; |
| } |
| |
| /** |
| * Installs a custom module load function that can adhere to paths in tsconfig. |
| * Returns a function to undo paths registration. |
| */ |
| export function register(explicitParams: ExplicitParams): () => void { |
| const configLoaderResult = configLoader({ |
| cwd: options.cwd, |
| explicitParams, |
| }); |
| |
| if (configLoaderResult.resultType === "failed") { |
| console.warn( |
| `${configLoaderResult.message}. tsconfig-paths will be skipped` |
| ); |
| |
| return noOp; |
| } |
| |
| const matchPath = createMatchPath( |
| configLoaderResult.absoluteBaseUrl, |
| configLoaderResult.paths, |
| configLoaderResult.mainFields, |
| configLoaderResult.addMatchAll |
| ); |
| |
| // Patch node's module loading |
| // tslint:disable-next-line:no-require-imports variable-name |
| const Module = require("module"); |
| const originalResolveFilename = Module._resolveFilename; |
| const coreModules = getCoreModules(Module.builtinModules); |
| // tslint:disable-next-line:no-any |
| Module._resolveFilename = function (request: string, _parent: any): string { |
| const isCoreModule = coreModules.hasOwnProperty(request); |
| if (!isCoreModule) { |
| const found = matchPath(request); |
| if (found) { |
| const modifiedArguments = [found, ...[].slice.call(arguments, 1)]; // Passes all arguments. Even those that is not specified above. |
| // tslint:disable-next-line:no-invalid-this |
| return originalResolveFilename.apply(this, modifiedArguments); |
| } |
| } |
| // tslint:disable-next-line:no-invalid-this |
| return originalResolveFilename.apply(this, arguments); |
| }; |
| |
| return () => { |
| // Return node's module loading to original state. |
| Module._resolveFilename = originalResolveFilename; |
| }; |
| } |