node-internal-modules-esm-get_format.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copied from https://raw.githubusercontent.com/nodejs/node/v15.3.0/lib/internal/modules/esm/get_format.js
  2. 'use strict';
  3. const {
  4. RegExpPrototypeExec,
  5. StringPrototypeStartsWith,
  6. } = require('./node-primordials');
  7. const { extname } = require('path');
  8. const { getOptionValue } = require('./node-options');
  9. const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(s => parseInt(s, 10));
  10. const experimentalJsonModules =
  11. nodeMajor > 17
  12. || (nodeMajor === 17 && nodeMinor >= 5)
  13. || (nodeMajor === 16 && nodeMinor >= 15)
  14. || getOptionValue('--experimental-json-modules');
  15. const experimentalWasmModules = getOptionValue('--experimental-wasm-modules');
  16. const { URL, fileURLToPath } = require('url');
  17. const { ERR_UNKNOWN_FILE_EXTENSION } = require('./node-internal-errors').codes;
  18. const extensionFormatMap = {
  19. '__proto__': null,
  20. '.cjs': 'commonjs',
  21. '.js': 'module',
  22. '.mjs': 'module'
  23. };
  24. const legacyExtensionFormatMap = {
  25. '__proto__': null,
  26. '.cjs': 'commonjs',
  27. '.js': 'commonjs',
  28. '.json': 'commonjs',
  29. '.mjs': 'module',
  30. '.node': 'commonjs'
  31. };
  32. if (experimentalWasmModules)
  33. extensionFormatMap['.wasm'] = legacyExtensionFormatMap['.wasm'] = 'wasm';
  34. if (experimentalJsonModules)
  35. extensionFormatMap['.json'] = legacyExtensionFormatMap['.json'] = 'json';
  36. /**
  37. *
  38. * @param {'node' | 'explicit'} [tsNodeExperimentalSpecifierResolution]
  39. * @param {ReturnType<
  40. * typeof import('../dist-raw/node-internal-modules-esm-resolve').createResolve
  41. * >} nodeEsmResolver
  42. */
  43. function createGetFormat(tsNodeExperimentalSpecifierResolution, nodeEsmResolver) {
  44. // const experimentalSpeciferResolution = tsNodeExperimentalSpecifierResolution ?? getOptionValue('--experimental-specifier-resolution');
  45. let experimentalSpeciferResolution = tsNodeExperimentalSpecifierResolution != null ? tsNodeExperimentalSpecifierResolution : getOptionValue('--experimental-specifier-resolution');
  46. const { getPackageType } = nodeEsmResolver;
  47. /**
  48. * @param {string} url
  49. * @param {{}} context
  50. * @param {any} defaultGetFormatUnused
  51. * @returns {ReturnType<import('../src/esm').NodeLoaderHooksAPI1.GetFormatHook>}
  52. */
  53. function defaultGetFormat(url, context, defaultGetFormatUnused) {
  54. if (StringPrototypeStartsWith(url, 'node:')) {
  55. return { format: 'builtin' };
  56. }
  57. const parsed = new URL(url);
  58. if (parsed.protocol === 'data:') {
  59. const [ , mime ] = RegExpPrototypeExec(
  60. /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/,
  61. parsed.pathname,
  62. ) || [ null, null, null ];
  63. const format = ({
  64. '__proto__': null,
  65. 'text/javascript': 'module',
  66. 'application/json': experimentalJsonModules ? 'json' : null,
  67. 'application/wasm': experimentalWasmModules ? 'wasm' : null
  68. })[mime] || null;
  69. return { format };
  70. } else if (parsed.protocol === 'file:') {
  71. const ext = extname(parsed.pathname);
  72. let format;
  73. if (ext === '.js') {
  74. format = getPackageType(parsed.href) === 'module' ? 'module' : 'commonjs';
  75. } else {
  76. format = extensionFormatMap[ext];
  77. }
  78. if (!format) {
  79. if (experimentalSpeciferResolution === 'node') {
  80. process.emitWarning(
  81. 'The Node.js specifier resolution in ESM is experimental.',
  82. 'ExperimentalWarning');
  83. format = legacyExtensionFormatMap[ext];
  84. } else {
  85. throw new ERR_UNKNOWN_FILE_EXTENSION(ext, fileURLToPath(url));
  86. }
  87. }
  88. return { format: format || null };
  89. }
  90. return { format: null };
  91. }
  92. return {defaultGetFormat};
  93. }
  94. module.exports = {
  95. createGetFormat
  96. };