index.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. const tests = {
  2. // ECMAScript 2018
  3. "object-rest-spread": ["({ ...{} })", "({ ...x } = {})"], // Babel 7.2.0
  4. "async-generators": ["async function* f() {}"], // Babel 7.2.0
  5. // ECMAScript 2019
  6. "optional-catch-binding": ["try {} catch {}"], // Babel 7.2.0
  7. "json-strings": ["'\\u2028'"], // Babel 7.2.0
  8. // ECMAScript 2020
  9. bigint: ["1n"], // Babel 7.8.0
  10. "optional-chaining": ["a?.b"], // Babel 7.9.0
  11. "nullish-coalescing-operator": ["a ?? b"], // Babel 7.9.0
  12. // import.meta is handled manually
  13. // ECMAScript 2021
  14. "numeric-separator": ["1_2"],
  15. "logical-assignment-operators": ["a ||= b", "a &&= b", "a ??= c"],
  16. // ECMAScript 2022
  17. "class-properties": [
  18. "(class { x = 1 })",
  19. "(class { #x = 1 })",
  20. "(class { #x() {} })",
  21. ],
  22. "private-property-in-object": ["(class { #x; m() { #x in y } })"],
  23. "class-static-block": ["(class { static {} })"],
  24. // top-level await is handled manually
  25. // Stage 3
  26. // import attributes is handled manually
  27. };
  28. const plugins = [];
  29. const works = (test) => {
  30. try {
  31. // Wrap the test in a function to only test the syntax, without executing it
  32. (0, eval)(`(() => { ${test} })`);
  33. return true;
  34. } catch (_error) {
  35. return false;
  36. }
  37. };
  38. for (const [name, cases] of Object.entries(tests)) {
  39. if (cases.some(works)) {
  40. plugins.push(require.resolve(`@babel/plugin-syntax-${name}`));
  41. }
  42. }
  43. // import.meta is only allowed in modules, and modules can only be evaluated
  44. // synchronously. For this reason, we cannot detect import.meta support at
  45. // runtime. It is supported starting from 10.4, so we can check the version.
  46. const major = parseInt(process.versions.node, 10);
  47. const minor = parseInt(process.versions.node.match(/^\d+\.(\d+)/)[1], 10);
  48. if (major > 10 || (major === 10 && minor >= 4)) {
  49. plugins.push(require.resolve("@babel/plugin-syntax-import-meta"));
  50. }
  51. // Same for top level await - it is only supported in modules. It is supported
  52. // from 14.3.0
  53. if (major > 14 || (major === 14 && minor >= 3)) {
  54. plugins.push(require.resolve("@babel/plugin-syntax-top-level-await"));
  55. }
  56. // Similar for import attributes
  57. if (
  58. major > 20 ||
  59. (major === 20 && minor >= 10) ||
  60. (major === 18 && minor >= 20)
  61. ) {
  62. plugins.push(require.resolve("@babel/plugin-syntax-import-attributes"));
  63. }
  64. module.exports = () => ({ plugins });