UNPKG

2.15 kBJavaScriptView Raw
1// @flow strict-local
2
3import type {Config} from '@parcel/types';
4import presetEnv from '@babel/preset-env';
5import type {BabelConfig} from './types';
6import type {Targets as BabelTargets, PresetEnvPlugin} from '@babel/preset-env';
7
8import getBabelTargets from './getBabelTargets';
9import {enginesToBabelTargets} from './utils';
10
11/**
12 * Generates a @babel/preset-env config for an asset.
13 * This is done by finding the source module's target engines, and the app's
14 * target engines, and doing a diff to include only the necessary plugins.
15 */
16export default async function getEnvOptions(
17 config: Config,
18): Promise<?{|
19 config: BabelConfig,
20 targets: BabelTargets,
21|}> {
22 // Only compile if there are engines defined in the environment.
23 if (Object.keys(config.env.engines).length === 0) {
24 return null;
25 }
26
27 // Load the target engines for the app and generate a @babel/preset-env config
28 let appBabelTargets = enginesToBabelTargets(config.env);
29
30 // If this is the app module, the source and target will be the same, so just compile everything.
31 // Otherwise, load the source engines and generate a babel-present-env config.
32 if (!config.isSource) {
33 let sourceBabelTargets = await getBabelTargets(config);
34
35 if (
36 !sourceBabelTargets ||
37 !shouldCompileFurther(sourceBabelTargets, appBabelTargets)
38 ) {
39 return null;
40 }
41 }
42
43 return {
44 targets: appBabelTargets,
45 config: {presets: ['@parcel/babel-preset-env']},
46 };
47}
48
49function getNeededPlugins(targets: BabelTargets): Array<PresetEnvPlugin> {
50 return presetEnv(
51 {assertVersion: () => true},
52 {targets: targets},
53 ).plugins.filter(p => p[0]);
54}
55
56function shouldCompileFurther(
57 sourceBabelTargets: BabelTargets,
58 appBabelTargets: BabelTargets,
59): boolean {
60 let sourcePlugins = new Set(getNeededPlugins(sourceBabelTargets));
61 let appPlugins = getNeededPlugins(appBabelTargets);
62
63 // If there is any app plugin present that was not used to compile the source,
64 // then the asset was built to a higher target and will need to be compiled
65 // further
66 return appPlugins.some(plugin => {
67 return !sourcePlugins.has(plugin);
68 });
69}