index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. var path = require('path');
  2. // We only register on the final extension (like `.js`) due to https://github.com/joyent/node/blob/v0.12.0/lib/module.js#L353
  3. // However, we use these matchers to apply the transform only if the full extension matches
  4. function endsInJsx(filename) {
  5. return filename.endsWith('.jsx');
  6. }
  7. function endsInTs(filename) {
  8. return filename.endsWith('.ts');
  9. }
  10. function endsInTsx(filename) {
  11. return filename.endsWith('.tsx');
  12. }
  13. function endsInBabelJs(filename) {
  14. return filename.endsWith('.babel.js');
  15. }
  16. function endsInBabelJsx(filename) {
  17. return filename.endsWith('.babel.jsx');
  18. }
  19. function endsInBabelTs(filename) {
  20. return filename.endsWith('.babel.ts');
  21. }
  22. function endsInBabelTsx(filename) {
  23. return filename.endsWith('.babel.tsx');
  24. }
  25. function endsInEsbuildJs(filename) {
  26. return filename.endsWith('.esbuild.js');
  27. }
  28. function endsInEsbuildJsx(filename) {
  29. return filename.endsWith('.esbuild.jsx');
  30. }
  31. function endsInEsbuildTs(filename) {
  32. return filename.endsWith('.esbuild.ts');
  33. }
  34. function endsInEsbuildTsx(filename) {
  35. return filename.endsWith('.esbuild.tsx');
  36. }
  37. function endsInSucraseJs(filename) {
  38. return filename.endsWith('.sucrase.js');
  39. }
  40. function endsInSucraseJsx(filename) {
  41. return filename.endsWith('.sucrase.jsx');
  42. }
  43. function endsInSucraseTs(filename) {
  44. return filename.endsWith('.sucrase.ts');
  45. }
  46. function endsInSucraseTsx(filename) {
  47. return filename.endsWith('.sucrase.tsx');
  48. }
  49. function endsInSwcJs(filename) {
  50. return filename.endsWith('.swc.js');
  51. }
  52. function endsInSwcJsx(filename) {
  53. return filename.endsWith('.swc.jsx');
  54. }
  55. function endsInSwcTs(filename) {
  56. return filename.endsWith('.swc.ts');
  57. }
  58. function endsInSwcTsx(filename) {
  59. return filename.endsWith('.swc.tsx');
  60. }
  61. var cjsStub = path.join(__dirname, 'cjs-stub');
  62. var mjsStub = path.join(__dirname, 'mjs-stub');
  63. function isNodeModules(file) {
  64. return path.relative(process.cwd(), file).includes('node_modules');
  65. }
  66. var extensions = {
  67. '.babel.js': {
  68. module: '@babel/register',
  69. register: function (hook, config) {
  70. config = config || {
  71. rootMode: 'upward-optional',
  72. overrides: [{ only: [endsInBabelJs], presets: ['@babel/preset-env'] }],
  73. };
  74. hook(Object.assign({}, config, { extensions: '.js' }));
  75. },
  76. },
  77. '.babel.jsx': {
  78. module: '@babel/register',
  79. register: function (hook, config) {
  80. config = config || {
  81. rootMode: 'upward-optional',
  82. overrides: [
  83. {
  84. only: [endsInBabelJsx],
  85. presets: ['@babel/preset-env', '@babel/preset-react'],
  86. },
  87. ],
  88. };
  89. hook(Object.assign({}, config, { extensions: '.jsx' }));
  90. },
  91. },
  92. '.babel.ts': [
  93. {
  94. module: '@babel/register',
  95. register: function (hook, config) {
  96. config = config || {
  97. rootMode: 'upward-optional',
  98. overrides: [
  99. {
  100. only: [endsInBabelTs],
  101. presets: ['@babel/preset-env', '@babel/preset-typescript'],
  102. },
  103. ],
  104. };
  105. hook(Object.assign({}, config, { extensions: '.ts' }));
  106. },
  107. },
  108. ],
  109. '.babel.tsx': {
  110. module: '@babel/register',
  111. register: function (hook, config) {
  112. config = config || {
  113. rootMode: 'upward-optional',
  114. overrides: [
  115. {
  116. only: [endsInBabelTsx],
  117. presets: [
  118. '@babel/preset-env',
  119. '@babel/preset-react',
  120. [
  121. '@babel/preset-typescript',
  122. {
  123. isTSX: true,
  124. allExtensions: true,
  125. },
  126. ],
  127. ],
  128. },
  129. ],
  130. };
  131. hook(Object.assign({}, config, { extensions: '.tsx' }));
  132. },
  133. },
  134. '.cjs': cjsStub,
  135. '.coffee': 'coffeescript/register',
  136. '.coffee.md': 'coffeescript/register',
  137. '.esbuild.js': {
  138. module: 'esbuild-register/dist/node',
  139. register: function (mod, config) {
  140. config = config || {
  141. target: 'node' + process.version.slice(1),
  142. hookMatcher: endsInEsbuildJs,
  143. };
  144. mod.register(Object.assign({}, config, { extensions: ['.js'] }));
  145. },
  146. },
  147. '.esbuild.jsx': {
  148. module: 'esbuild-register/dist/node',
  149. register: function (mod, config) {
  150. config = config || {
  151. target: 'node' + process.version.slice(1),
  152. hookMatcher: endsInEsbuildJsx,
  153. };
  154. mod.register(Object.assign({}, config, { extensions: ['.jsx'] }));
  155. },
  156. },
  157. '.esbuild.ts': {
  158. module: 'esbuild-register/dist/node',
  159. register: function (mod, config) {
  160. config = config || {
  161. target: 'node' + process.version.slice(1),
  162. hookMatcher: endsInEsbuildTs,
  163. };
  164. mod.register(Object.assign({}, config, { extensions: ['.ts'] }));
  165. },
  166. },
  167. '.esbuild.tsx': {
  168. module: 'esbuild-register/dist/node',
  169. register: function (mod, config) {
  170. config = config || {
  171. target: 'node' + process.version.slice(1),
  172. hookMatcher: endsInEsbuildTsx,
  173. };
  174. mod.register(Object.assign({}, config, { extensions: ['.tsx'] }));
  175. },
  176. },
  177. '.esm.js': {
  178. module: 'esm',
  179. register: function (hook) {
  180. // register on .js extension due to https://github.com/joyent/node/blob/v0.12.0/lib/module.js#L353
  181. // which only captures the final extension (.esm.js -> .js)
  182. var esmLoader = hook(module);
  183. require.extensions['.js'] = esmLoader('module')._extensions['.js'];
  184. },
  185. },
  186. '.js': null,
  187. '.json': null,
  188. '.json5': 'json5/lib/register',
  189. '.jsx': [
  190. {
  191. module: '@babel/register',
  192. register: function (hook, config) {
  193. config = config || {
  194. rootMode: 'upward-optional',
  195. overrides: [
  196. {
  197. only: [endsInJsx],
  198. presets: ['@babel/preset-env', '@babel/preset-react'],
  199. },
  200. ],
  201. };
  202. hook(Object.assign({}, config, { extensions: '.jsx' }));
  203. },
  204. },
  205. 'sucrase/register/jsx',
  206. ],
  207. '.litcoffee': 'coffeescript/register',
  208. // The mdx loader hooks both `.md` and `.mdx` when it is imported
  209. // but we only install the hook if `.mdx` is the first file
  210. '.mdx': '@mdx-js/register',
  211. '.mjs': mjsStub,
  212. '.node': null,
  213. '.sucrase.js': {
  214. module: 'sucrase/dist/register',
  215. register: function (hook, config) {
  216. config = config || {
  217. matcher: endsInSucraseJs,
  218. };
  219. hook.registerJS(config);
  220. },
  221. },
  222. '.sucrase.jsx': {
  223. module: 'sucrase/dist/register',
  224. register: function (hook, config) {
  225. config = config || {
  226. matcher: endsInSucraseJsx,
  227. };
  228. hook.registerJSX(config);
  229. },
  230. },
  231. '.sucrase.ts': {
  232. module: 'sucrase/dist/register',
  233. register: function (hook, config) {
  234. config = config || {
  235. matcher: endsInSucraseTs,
  236. };
  237. hook.registerTS(config);
  238. },
  239. },
  240. '.sucrase.tsx': {
  241. module: 'sucrase/dist/register',
  242. register: function (hook, config) {
  243. config = config || {
  244. matcher: endsInSucraseTsx,
  245. };
  246. hook.registerTSX(config);
  247. },
  248. },
  249. '.swc.js': {
  250. module: '@swc/register',
  251. register: function (hook, config) {
  252. config = config || {
  253. only: [endsInSwcJs],
  254. ignore: [isNodeModules],
  255. jsc: {
  256. parser: {
  257. syntax: 'ecmascript',
  258. },
  259. },
  260. module: {
  261. type: 'commonjs',
  262. },
  263. };
  264. hook(
  265. Object.assign({}, config, {
  266. extensions: '.js',
  267. })
  268. );
  269. },
  270. },
  271. '.swc.jsx': {
  272. module: '@swc/register',
  273. register: function (hook, config) {
  274. config = config || {
  275. only: [endsInSwcJsx],
  276. ignore: [isNodeModules],
  277. jsc: {
  278. parser: {
  279. syntax: 'ecmascript',
  280. jsx: true,
  281. },
  282. },
  283. module: {
  284. type: 'commonjs',
  285. },
  286. };
  287. hook(
  288. Object.assign({}, config, {
  289. extensions: '.jsx',
  290. })
  291. );
  292. },
  293. },
  294. '.swc.ts': {
  295. module: '@swc/register',
  296. register: function (hook, config) {
  297. config = config || {
  298. only: [endsInSwcTs],
  299. ignore: [isNodeModules],
  300. jsc: {
  301. parser: {
  302. syntax: 'typescript',
  303. },
  304. },
  305. module: {
  306. type: 'commonjs',
  307. },
  308. };
  309. hook(
  310. Object.assign({}, config, {
  311. extensions: '.ts',
  312. })
  313. );
  314. },
  315. },
  316. '.swc.tsx': {
  317. module: '@swc/register',
  318. register: function (hook, config) {
  319. config = config || {
  320. only: [endsInSwcTsx],
  321. ignore: [isNodeModules],
  322. jsc: {
  323. parser: {
  324. syntax: 'typescript',
  325. tsx: true,
  326. },
  327. },
  328. module: {
  329. type: 'commonjs',
  330. },
  331. };
  332. hook(
  333. Object.assign({}, config, {
  334. extensions: '.tsx',
  335. })
  336. );
  337. },
  338. },
  339. '.toml': {
  340. module: 'toml-require',
  341. register: function (hook, config) {
  342. hook.install(config);
  343. },
  344. },
  345. '.ts': [
  346. 'ts-node/register',
  347. 'sucrase/register/ts',
  348. {
  349. module: '@babel/register',
  350. register: function (hook, config) {
  351. config = config || {
  352. rootMode: 'upward-optional',
  353. overrides: [
  354. {
  355. only: [endsInTs],
  356. presets: ['@babel/preset-env', '@babel/preset-typescript'],
  357. },
  358. ],
  359. };
  360. hook(
  361. Object.assign({}, config, {
  362. extensions: '.ts',
  363. })
  364. );
  365. },
  366. },
  367. {
  368. module: 'esbuild-register/dist/node',
  369. register: function (mod, config) {
  370. config = config || {
  371. target: 'node' + process.version.slice(1),
  372. hookMatcher: endsInTs,
  373. };
  374. mod.register(
  375. Object.assign({}, config, {
  376. extensions: ['.ts'],
  377. })
  378. );
  379. },
  380. },
  381. {
  382. module: '@swc/register',
  383. register: function (hook, config) {
  384. config = config || {
  385. only: [endsInTs],
  386. ignore: [isNodeModules],
  387. jsc: {
  388. parser: {
  389. syntax: 'typescript',
  390. },
  391. },
  392. module: {
  393. type: 'commonjs',
  394. },
  395. };
  396. hook(
  397. Object.assign({}, config, {
  398. extensions: '.ts',
  399. })
  400. );
  401. },
  402. },
  403. ],
  404. '.cts': ['ts-node/register'],
  405. '.tsx': [
  406. 'ts-node/register',
  407. 'sucrase/register/tsx',
  408. {
  409. module: '@babel/register',
  410. register: function (hook, config) {
  411. config = config || {
  412. rootMode: 'upward-optional',
  413. overrides: [
  414. {
  415. only: [endsInTsx],
  416. presets: [
  417. '@babel/preset-env',
  418. '@babel/preset-react',
  419. [
  420. '@babel/preset-typescript',
  421. {
  422. isTSX: true,
  423. allExtensions: true,
  424. },
  425. ],
  426. ],
  427. },
  428. ],
  429. };
  430. hook(
  431. Object.assign({}, config, {
  432. extensions: '.tsx',
  433. })
  434. );
  435. },
  436. },
  437. {
  438. module: 'esbuild-register/dist/node',
  439. register: function (mod, config) {
  440. config = config || {
  441. target: 'node' + process.version.slice(1),
  442. hookMatcher: endsInTsx,
  443. };
  444. mod.register(
  445. Object.assign({}, config, {
  446. extensions: ['.tsx'],
  447. })
  448. );
  449. },
  450. },
  451. {
  452. module: '@swc/register',
  453. register: function (hook, config) {
  454. config = config || {
  455. only: [endsInTsx],
  456. ignore: [isNodeModules],
  457. jsc: {
  458. parser: {
  459. syntax: 'typescript',
  460. tsx: true,
  461. },
  462. },
  463. module: {
  464. type: 'commonjs',
  465. },
  466. };
  467. hook(
  468. Object.assign({}, config, {
  469. extensions: '.tsx',
  470. })
  471. );
  472. },
  473. },
  474. ],
  475. '.yaml': 'yaml-hook/register',
  476. '.yml': 'yaml-hook/register',
  477. };
  478. var jsVariantExtensions = [
  479. '.js',
  480. '.babel.js',
  481. '.babel.jsx',
  482. '.babel.ts',
  483. '.babel.tsx',
  484. '.esbuild.js',
  485. '.esbuild.jsx',
  486. '.esbuild.ts',
  487. '.esbuild.tsx',
  488. '.cjs',
  489. '.coffee',
  490. '.coffee.md',
  491. '.esm.js',
  492. '.jsx',
  493. '.litcoffee',
  494. '.mdx',
  495. '.mjs',
  496. '.sucrase.js',
  497. '.sucrase.jsx',
  498. '.sucrase.ts',
  499. '.sucrase.tsx',
  500. '.swc.js',
  501. '.swc.jsx',
  502. '.swc.ts',
  503. '.swc.tsx',
  504. '.ts',
  505. '.tsx',
  506. ];
  507. module.exports = {
  508. extensions: extensions,
  509. jsVariants: jsVariantExtensions.reduce(function (result, ext) {
  510. result[ext] = extensions[ext];
  511. return result;
  512. }, {}),
  513. };