index.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import browserslist from 'browserslist'
  2. // convert the browserslist field in package.json to
  3. // esbuild compatible array of browsers
  4. export default function browserslistToEsbuild(browserslistConfig, options = {}) {
  5. if (!browserslistConfig) {
  6. // the path from where the script is run
  7. const path = process.cwd()
  8. // read config if none is passed
  9. browserslistConfig = browserslist.loadConfig({ path, ...options })
  10. }
  11. const SUPPORTED_ESBUILD_TARGETS = [
  12. 'es',
  13. 'chrome',
  14. 'edge',
  15. 'firefox',
  16. 'ios',
  17. 'node',
  18. 'safari',
  19. 'opera',
  20. 'ie',
  21. ]
  22. // https://github.com/eBay/browserslist-config/issues/16#issuecomment-863870093
  23. const UNSUPPORTED = ['android 4']
  24. const replaces = {
  25. ios_saf: 'ios',
  26. android: 'chrome',
  27. }
  28. const separator = ' '
  29. return (
  30. browserslist(browserslistConfig, options)
  31. // filter out the unsupported ones
  32. .filter((b) => !UNSUPPORTED.some((u) => b.startsWith(u)))
  33. // replaces safari TP with latest safari version
  34. .map((b) => {
  35. if (b === 'safari TP') {
  36. return browserslist('last 1 safari version')[0]
  37. }
  38. return b
  39. })
  40. // transform into ['chrome', '88']
  41. .map((b) => b.split(separator))
  42. // replace the similar browser
  43. .map((b) => {
  44. if (replaces[b[0]]) {
  45. b[0] = replaces[b[0]]
  46. }
  47. return b
  48. })
  49. // 11.0-12.0 --> 11.0
  50. .map((b) => {
  51. if (b[1].includes('-')) {
  52. b[1] = b[1].slice(0, b[1].indexOf('-'))
  53. }
  54. return b
  55. })
  56. // 11.0 --> 11
  57. .map((b) => {
  58. if (b[1].endsWith('.0')) {
  59. b[1] = b[1].slice(0, -2)
  60. }
  61. return b
  62. })
  63. // removes invalid versions that will break esbuild
  64. // https://github.com/evanw/esbuild/blob/35c0d65b9d4f29a26176404d2890d1b499634e9f/compat-table/src/caniuse.ts#L119-L122
  65. .filter((b) => /^\d+(\.\d+)*$/.test(b[1]))
  66. // only get the targets supported by esbuild
  67. .filter((b) => SUPPORTED_ESBUILD_TARGETS.includes(b[0]))
  68. // only get the oldest version, assuming that the older version
  69. // is last in the array
  70. .reduce((acc, b) => {
  71. const existingIndex = acc.findIndex((br) => br[0] === b[0])
  72. if (existingIndex !== -1) {
  73. acc[existingIndex][1] = b[1]
  74. } else {
  75. acc.push(b)
  76. }
  77. return acc
  78. }, [])
  79. // remove separator
  80. .map((b) => b.join(''))
  81. )
  82. }