UNPKG

2.71 kBJavaScriptView Raw
1// @flow
2
3import type {Environment} from '@parcel/types';
4import type {Targets as BabelTargets} from '@babel/preset-env';
5
6import invariant from 'assert';
7import semver from 'semver';
8import {TargetNames} from '@babel/helper-compilation-targets/lib/options';
9
10// List of browsers to exclude when the esmodule target is specified.
11// Based on https://caniuse.com/#feat=es6-module
12const ESMODULE_BROWSERS = [
13 'not ie <= 11',
14 'not edge < 16',
15 'not firefox < 60',
16 'not chrome < 61',
17 'not safari < 11',
18 'not opera < 48',
19 'not ios_saf < 11',
20 'not op_mini all',
21 'not android < 76',
22 'not blackberry > 0',
23 'not op_mob > 0',
24 'not and_chr < 76',
25 'not and_ff < 68',
26 'not ie_mob > 0',
27 'not and_uc > 0',
28 'not samsung < 8.2',
29 'not and_qq > 0',
30 'not baidu > 0',
31 'not kaios > 0',
32];
33
34export function enginesToBabelTargets(env: Environment): BabelTargets {
35 // "Targets" is the name @babel/preset-env uses for what Parcel calls engines.
36 // This should not be confused with Parcel's own targets.
37 // Unlike Parcel's engines, @babel/preset-env expects to work with minimum
38 // versions, not semver ranges, of its targets.
39 let targets = {};
40 for (let engineName of Object.keys(env.engines)) {
41 let engineValue = env.engines[engineName];
42
43 // if the engineValue is a string, it might be a semver range. Use the minimum
44 // possible version instead.
45 if (engineName === 'browsers') {
46 targets[engineName] = engineValue;
47 } else {
48 invariant(typeof engineValue === 'string');
49 if (!TargetNames.hasOwnProperty(engineName)) continue;
50 let minVersion = getMinSemver(engineValue);
51 targets[engineName] = minVersion ?? engineValue;
52 }
53 }
54
55 if (env.outputFormat === 'esmodule' && env.isBrowser()) {
56 // If there is already a browsers target, add a blacklist to exclude
57 // instead of using babel's esmodules target. This allows specifying
58 // a newer set of browsers than the baseline esmodule support list.
59 // See https://github.com/babel/babel/issues/8809.
60 if (targets.browsers) {
61 let browsers = Array.isArray(targets.browsers)
62 ? targets.browsers
63 : [targets.browsers];
64 targets.browsers = [...browsers, ...ESMODULE_BROWSERS];
65 } else {
66 targets.esmodules = true;
67 }
68 }
69
70 return targets;
71}
72
73// TODO: Replace with `minVersion` (https://github.com/npm/node-semver#ranges-1)
74// once semver has been upgraded across Parcel.
75export function getMinSemver(version: string): ?string {
76 try {
77 let range = new semver.Range(version);
78 let sorted = range.set.sort((a, b) => a[0].semver.compare(b[0].semver));
79 return sorted[0][0].semver.version;
80 } catch (err) {
81 return null;
82 }
83}