1 |
|
2 |
|
3 | import type {Config} from '@parcel/types';
|
4 | import type {Targets as BabelTargets} from '@babel/preset-env';
|
5 |
|
6 | import browserslist from 'browserslist';
|
7 | import semver from 'semver';
|
8 |
|
9 | const BROWSER_CONTEXT = new Set(['browser', 'web-worker', 'service-worker']);
|
10 |
|
11 |
|
12 | type BrowserslistConfig = {|[string]: string | Array<string>|};
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | export default async function getBabelTargets(
|
26 | config: Config,
|
27 | ): Promise<?BabelTargets> {
|
28 | let targets = {};
|
29 | let compileTarget = BROWSER_CONTEXT.has(config.env.context)
|
30 | ? 'browsers'
|
31 | : config.env.context;
|
32 | let pkg = await config.getPackage();
|
33 | let packageEngines = pkg?.engines;
|
34 |
|
35 | if (compileTarget === 'node') {
|
36 | let nodeVersion = packageEngines?.node;
|
37 |
|
38 | if (typeof nodeVersion === 'string') {
|
39 | try {
|
40 |
|
41 | targets.node = semver.minVersion(nodeVersion).version;
|
42 | } catch (e) {
|
43 | throw new Error("Expected 'node' engine to be a valid Semver Range");
|
44 | }
|
45 | }
|
46 | } else {
|
47 | let browsers;
|
48 | if (
|
49 | packageEngines &&
|
50 | (typeof packageEngines.browsers === 'string' ||
|
51 | Array.isArray(packageEngines.browsers))
|
52 | ) {
|
53 | browsers = packageEngines.browsers;
|
54 | } else if (pkg && pkg.browserslist) {
|
55 | browsers = pkg.browserslist;
|
56 | } else {
|
57 | let browserslist = await loadBrowserslist(config);
|
58 | if (browserslist) {
|
59 | browsers = browserslist;
|
60 | }
|
61 | }
|
62 |
|
63 |
|
64 | if (
|
65 | typeof browsers === 'object' &&
|
66 | browsers != null &&
|
67 | !Array.isArray(browsers)
|
68 | ) {
|
69 | let env = process.env.NODE_ENV ?? 'development';
|
70 | browsers = browsers[env] || browsers.defaults;
|
71 | }
|
72 |
|
73 | if (browsers != null) {
|
74 | targets.browsers = browserslist(browsers).sort();
|
75 | }
|
76 | }
|
77 |
|
78 |
|
79 | if (Object.keys(targets).length === 0) {
|
80 | return null;
|
81 | }
|
82 |
|
83 | return targets;
|
84 | }
|
85 |
|
86 | async function loadBrowserslist(config): Promise<?BrowserslistConfig> {
|
87 | let browserslistConfig = await config.getConfig(
|
88 | ['browserslist', '.browserslistrc'],
|
89 | {
|
90 | parse: false,
|
91 | },
|
92 | );
|
93 |
|
94 | if (browserslistConfig) {
|
95 | return browserslist.parseConfig(browserslistConfig.contents);
|
96 | }
|
97 | }
|