forked from theblacksmith/typescript-require
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
124 lines (105 loc) · 2.87 KB
/
index.js
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
var vm = require('vm');
var fs = require('fs');
var path = require('path');
var tsc = path.join(path.dirname(require.resolve("typescript")),"tsc.js");
var tscScript = vm.createScript(fs.readFileSync(tsc, "utf8"), tsc);
var libPath = path.join(path.dirname(require.resolve("typescript")), "lib.d.ts")
var options = {
nodeLib: false,
targetES5: true,
moduleKind: 'commonjs',
exitOnError: true
};
module.exports = function(opts) {
options = merge(options, opts);
};
require.extensions['.ts'] = function(module) {
var jsname = compileTS(module);
runJS(jsname, module);
};
function isModified(tsname, jsname) {
var tsMTime = fs.statSync(tsname).mtime;
try {
var jsMTime = fs.statSync(jsname).mtime;
} catch (e) { //catch if file does not exists
jsMTime = 0;
}
return tsMTime > jsMTime;
}
/**
* Compiles TypeScript file, returns js file path
* @return {string} js file path
*/
function compileTS (module) {
var exitCode = 0;
var tmpDir = path.join(process.cwd(), "tmp", "tsreq");
var relativeFolder = path.dirname(path.relative(process.cwd(), module.filename));
var jsname = path.join(tmpDir, relativeFolder, path.basename(module.filename, ".ts") + ".js");
if (!isModified(module.filename, jsname)) {
return jsname;
}
var argv = [
"node",
"tsc.js",
"--nolib",
"--target",
options.targetES5 ? "ES5" : "ES3", !! options.moduleKind ? "--module" : "", !! options.moduleKind ? options.moduleKind : "",
"--outDir",
path.join(tmpDir, relativeFolder),
libPath,
options.nodeLib ? path.resolve(__dirname, "typings/node.d.ts") : null,
module.filename
];
var proc = merge(merge({}, process), {
argv: compact(argv),
exit: function(code) {
if (code !== 0 && options.exitOnError) {
console.error('Fatal Error. Unable to compile TypeScript file. Exiting.');
process.exit(code);
}
exitCode = code;
}
});
var sandbox = {
process: proc,
require: require,
module: module,
Buffer: Buffer,
setTimeout: setTimeout
};
tscScript.runInNewContext(sandbox);
if (exitCode != 0) {
throw new Error('Unable to compile TypeScript file.');
}
return jsname;
}
function runJS (jsname, module) {
var content = fs.readFileSync(jsname, 'utf8');
var sandbox = {};
for (var k in global) {
sandbox[k] = global[k];
}
sandbox.require = module.require.bind(module);
sandbox.exports = module.exports;
sandbox.__filename = jsname;
sandbox.__dirname = path.dirname(module.filename);
sandbox.module = module;
sandbox.global = sandbox;
sandbox.root = root;
return vm.runInNewContext(content, sandbox, { filename: jsname });
}
function merge(a, b) {
if (a && b) {
for (var key in b) {
a[key] = b[key];
}
}
return a;
};
function compact(arr) {
var narr = [];
arr.forEach(function(data) {
if (data) narr.push(data);
});
return narr;
}