register.ts
2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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;
};
}