UNPKG

1.79 kBJavaScriptView Raw
1// @flow strict-local
2
3import type {Config, PluginOptions} from '@parcel/types';
4import type {BabelConfig} from './types';
5
6import path from 'path';
7
8const JSX_EXTENSIONS = {
9 '.jsx': true,
10 '.tsx': true,
11};
12
13const JSX_PRAGMA = {
14 react: {
15 pragma: 'React.createElement',
16 pragmaFrag: 'React.Fragment',
17 },
18 preact: {
19 pragma: 'h',
20 pragmaFrag: 'Fragment',
21 },
22 nervjs: {
23 pragma: 'Nerv.createElement',
24 pragmaFrag: undefined,
25 },
26 hyperapp: {
27 pragma: 'h',
28 pragmaFrag: undefined,
29 },
30};
31
32/**
33 * Generates a babel config for JSX. Attempts to detect react or react-like libraries
34 * and changes the pragma accordingly.
35 */
36export default async function getJSXOptions(
37 options: PluginOptions,
38 config: Config,
39): Promise<?{|config: BabelConfig, pragma: ?string, pragmaFrag: ?string|}> {
40 if (!config.isSource) {
41 return null;
42 }
43
44 let pkg = await config.getPackage();
45 let reactLib;
46 if (pkg?.alias && pkg.alias['react']) {
47 // e.g.: `{ alias: { "react": "preact/compat" } }`
48 reactLib = 'react';
49 } else {
50 // Find a dependency that we can map to a JSX pragma
51 reactLib = Object.keys(JSX_PRAGMA).find(
52 libName =>
53 pkg &&
54 ((pkg.dependencies && pkg.dependencies[libName]) ||
55 (pkg.devDependencies && pkg.devDependencies[libName])),
56 );
57 }
58
59 let pragma = reactLib ? JSX_PRAGMA[reactLib].pragma : undefined;
60 let pragmaFrag = reactLib ? JSX_PRAGMA[reactLib].pragmaFrag : undefined;
61
62 if (pragma || JSX_EXTENSIONS[path.extname(config.searchPath)]) {
63 return {
64 config: {
65 presets: [
66 [
67 '@babel/preset-react',
68 {pragma, pragmaFrag, development: options.mode === 'development'},
69 ],
70 ],
71 },
72 pragma,
73 pragmaFrag,
74 };
75 }
76}