child-require-hook.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. "use strict";
  2. var fs = require('fs');
  3. var getCompiledPath = require('./get-compiled-path').getCompiledPath;
  4. var sep = require('path').sep;
  5. var join = require('path').join;
  6. var extname = require('path').extname;
  7. var execSync = require('child_process').execSync;
  8. var Module = require('module');
  9. var compilationId = '';
  10. var timeThreshold = 0;
  11. var allowJs = false;
  12. var compiledDir = '';
  13. var preferTs = false;
  14. var ignore = [/node_modules/];
  15. var readyFile = '';
  16. var execCheck = false;
  17. var exitChild = false;
  18. var sourceMapSupportPath = '';
  19. var libPath = '';
  20. var checkFileScript = join(__dirname, 'check-file-exists.js');
  21. var waitForFile = function (fileName) {
  22. var start = new Date().getTime();
  23. while (true) {
  24. var exists = execCheck
  25. ? execSync(['node', checkFileScript, '"' + fileName + '"'].join(' '), {
  26. stdio: 'inherit',
  27. }) || true
  28. : fs.existsSync(fileName);
  29. if (exists) {
  30. return;
  31. }
  32. var passed = new Date().getTime() - start;
  33. if (timeThreshold && passed > timeThreshold) {
  34. throw new Error('Could not require ' + fileName);
  35. }
  36. }
  37. };
  38. var sendFsCompileRequest = function (fileName, compiledPath) {
  39. var compileRequestFile = [compiledDir, compilationId + '.req'].join(sep);
  40. fs.writeFileSync(compileRequestFile, [fileName, compiledPath].join('\n'));
  41. };
  42. var compile = function (code, fileName) {
  43. var compiledPath = getCompiledPath(code, fileName, compiledDir);
  44. if (process.send) {
  45. try {
  46. process.send({
  47. compile: fileName,
  48. compiledPath: compiledPath,
  49. });
  50. }
  51. catch (e) {
  52. console.warn('Error while sending compile request via process.send');
  53. sendFsCompileRequest(fileName, compiledPath);
  54. }
  55. }
  56. else {
  57. sendFsCompileRequest(fileName, compiledPath);
  58. }
  59. waitForFile(compiledPath + '.done');
  60. var compiled = fs.readFileSync(compiledPath, 'utf-8');
  61. return compiled;
  62. };
  63. function registerExtensions(extensions) {
  64. extensions.forEach(function (ext) {
  65. var old = require.extensions[ext] || require.extensions['.js'];
  66. require.extensions[ext] = function (m, fileName) {
  67. var _compile = m._compile;
  68. m._compile = function (code, fileName) {
  69. return _compile.call(this, compile(code, fileName), fileName);
  70. };
  71. return old(m, fileName);
  72. };
  73. });
  74. if (preferTs) {
  75. var reorderRequireExtension_1 = function (ext) {
  76. var old = require.extensions[ext];
  77. delete require.extensions[ext];
  78. require.extensions[ext] = old;
  79. };
  80. var order = ['.ts', '.tsx'].concat(Object.keys(require.extensions).filter(function (_) { return _ !== '.ts' && _ !== '.tsx'; }));
  81. order.forEach(function (ext) {
  82. reorderRequireExtension_1(ext);
  83. });
  84. }
  85. }
  86. function isFileInNodeModules(fileName) {
  87. return fileName.indexOf(sep + 'node_modules' + sep) >= 0;
  88. }
  89. function registerJsExtension() {
  90. var old = require.extensions['.js'];
  91. // handling preferTs probably redundant after reordering
  92. if (allowJs) {
  93. require.extensions['.jsx'] = require.extensions['.js'] = function (m, fileName) {
  94. if (fileName.indexOf(libPath) === 0) {
  95. return old(m, fileName);
  96. }
  97. var tsCode = undefined;
  98. var tsFileName = '';
  99. var _compile = m._compile;
  100. var isIgnored = ignore &&
  101. ignore.reduce(function (res, ignore) {
  102. return res || ignore.test(fileName);
  103. }, false);
  104. var ext = extname(fileName);
  105. if (tsCode !== undefined || (allowJs && !isIgnored && ext == '.js')) {
  106. m._compile = function (code, fileName) {
  107. if (tsCode !== undefined) {
  108. code = tsCode;
  109. fileName = tsFileName;
  110. }
  111. return _compile.call(this, compile(code, fileName), fileName);
  112. };
  113. }
  114. return old(m, fileName);
  115. };
  116. }
  117. }
  118. var sourceMapRequire = Module.createRequire
  119. ? Module.createRequire(sourceMapSupportPath)
  120. : require;
  121. sourceMapRequire(sourceMapSupportPath).install({
  122. hookRequire: true,
  123. });
  124. registerJsExtension();
  125. registerExtensions(['.ts', '.tsx']);
  126. if (readyFile) {
  127. var time = new Date().getTime();
  128. while (!fs.existsSync(readyFile)) {
  129. if (new Date().getTime() - time > 5000) {
  130. throw new Error('Waiting ts-node-dev ready file failed');
  131. }
  132. }
  133. }
  134. if (exitChild) {
  135. process.on('SIGTERM', function () {
  136. console.log('Child got SIGTERM, exiting.');
  137. process.exit();
  138. });
  139. }
  140. module.exports.registerExtensions = registerExtensions;