-
Notifications
You must be signed in to change notification settings - Fork 787
/
node-require.ts
73 lines (60 loc) · 2.29 KB
/
node-require.ts
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
import { catchError, loadTypeScriptDiagnostic } from '@utils';
import ts from 'typescript';
import type { Diagnostic } from '../../declarations';
export const nodeRequire = (id: string) => {
const results = {
module: undefined as any,
id,
diagnostics: [] as Diagnostic[],
};
try {
const fs: typeof import('fs') = require('fs');
const path: typeof import('path') = require('path');
results.id = path.resolve(id);
// ensure we cleared out node's internal require() cache for this file
delete require.cache[results.id];
// let's override node's require for a second
// don't worry, we'll revert this when we're done
require.extensions['.ts'] = (module: NodeJS.Module, fileName: string) => {
let sourceText = fs.readFileSync(fileName, 'utf8');
if (fileName.endsWith('.ts')) {
// looks like we've got a typed config file
// let's transpile it to .js quick
const tsResults = ts.transpileModule(sourceText, {
fileName,
compilerOptions: {
module: ts.ModuleKind.CommonJS,
moduleResolution: ts.ModuleResolutionKind.NodeJs,
esModuleInterop: true,
target: ts.ScriptTarget.ES2017,
allowJs: true,
},
});
sourceText = tsResults.outputText;
results.diagnostics.push(...tsResults.diagnostics.map(loadTypeScriptDiagnostic));
} else {
// quick hack to turn a modern es module
// into and old school commonjs module
sourceText = sourceText.replace(/export\s+\w+\s+(\w+)/gm, 'exports.$1');
}
try {
// we need to coerce because of the requirements for the arguments to
// this function. It's safe enough since it's already wrapped in a
// `try { } catch`.
(module as NodeModuleWithCompile)._compile(sourceText, fileName);
} catch (e: any) {
catchError(results.diagnostics, e);
}
};
// let's do this!
results.module = require(results.id);
// all set, let's go ahead and reset the require back to the default
require.extensions['.ts'] = undefined;
} catch (e: any) {
catchError(results.diagnostics, e);
}
return results;
};
interface NodeModuleWithCompile extends NodeModule {
_compile(code: string, filename: string): any;
}