From f72ff7747afb1a71d53ba9258bd9a8838c0b062f Mon Sep 17 00:00:00 2001 From: Georges Haidar Date: Thu, 25 Feb 2021 14:37:34 +0000 Subject: [PATCH] feat(babel-preset-gatsby): allow setting importSource on preset-react (#29260) * feat(babel-preset-gatsby): allow passing importSource to preset-react With React 17's new JSX transform feature, it is possible to pass a custom JSX factory besides React's default one. This is useful when working with libraries like Emotion 11: https://emotion.sh/docs/css-prop#babel-preset. In order to support this feature in `babel-preset-gatsby`, this PR adds an option called `reactImportSource` that is passed down to the underlying `@babel/preset-react` preset option `importSource`. Users of `babel-preset-gatsby` can then use this like so: ```json { "presets": [ [ "babel-preset-gatsby", { "reactRuntime": "automatic", "reactImportSource": "@emotion/react" } ] ] } ``` * conditionally pass through the preset option rather than undefined * throwing if runtime is wrong, move the logic out of the object * clean up tests, change syntax Co-authored-by: Laurie --- .../src/__tests__/index.js | 20 +++++++++++++++++++ packages/babel-preset-gatsby/src/index.js | 9 ++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/babel-preset-gatsby/src/__tests__/index.js b/packages/babel-preset-gatsby/src/__tests__/index.js index 69e9715c2a43b..dcf3dd837b351 100644 --- a/packages/babel-preset-gatsby/src/__tests__/index.js +++ b/packages/babel-preset-gatsby/src/__tests__/index.js @@ -50,4 +50,24 @@ describe(`babel-preset-gatsby`, () => { }), ]) }) + + it(`Allows to configure react importSource`, () => { + const { presets } = preset(null, { + reactImportSource: `@emotion/react`, + reactRuntime: `automatic`, + }) + + expect(presets[1]).toEqual([ + expect.stringContaining(path.join(`@babel`, `preset-react`)), + expect.objectContaining({ + importSource: `@emotion/react`, + }), + ]) + }) + + it(`Fails to configure react importSource if source is classic`, () => { + expect(() => preset(null, { reactImportSource: `@emotion/react` })).toThrow( + `@babel/preset-react\` requires reactRuntime \`automatic\` in order to use \`importSource\`.` + ) + }) }) diff --git a/packages/babel-preset-gatsby/src/index.js b/packages/babel-preset-gatsby/src/index.js index e87620ff21a04..f8336d09bfe53 100644 --- a/packages/babel-preset-gatsby/src/index.js +++ b/packages/babel-preset-gatsby/src/index.js @@ -30,7 +30,7 @@ export function loadCachedConfig() { } export default function preset(_, options = {}) { - let { targets = null } = options + let { targets = null, reactImportSource = null } = options const stage = options.stage || `test` const pluginBabelConfig = loadCachedConfig() @@ -54,6 +54,12 @@ export default function preset(_, options = {}) { } } + if (reactImportSource && options.reactRuntime !== `automatic`) { + throw Error( + `\`@babel/preset-react\` requires reactRuntime \`automatic\` in order to use \`importSource\`.` + ) + } + return { presets: [ [ @@ -87,6 +93,7 @@ export default function preset(_, options = {}) { : `React.createElement`, development: stage === `develop`, runtime: options.reactRuntime || `classic`, + ...(reactImportSource && { importSource: reactImportSource }), }, ], ],