diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 68dcfa6e..44d76509 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -115,9 +115,9 @@ importers: tests/fixtures/build/automatic-jsx: specifiers: - react: ^17.0.0 + react: ^16.14.0 dependencies: - react: 17.0.2 + react: 16.14.0 tests/fixtures/build/classic-jsx: specifiers: @@ -2859,8 +2859,8 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - JSONStream: 1.3.5 is-text-path: 1.0.1 + JSONStream: 1.3.5 lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 @@ -6461,7 +6461,6 @@ packages: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - dev: true /ps-tree/1.2.0: resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} @@ -6558,7 +6557,6 @@ packages: /react-is/16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - dev: true /react-is/17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -6576,15 +6574,6 @@ packages: loose-envify: 1.4.0 object-assign: 4.1.1 prop-types: 15.8.1 - dev: true - - /react/17.0.2: - resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} - engines: {node: '>=0.10.0'} - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - dev: false /react/18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} diff --git a/src/builder/bundle/index.ts b/src/builder/bundle/index.ts index cc611f41..e607373d 100644 --- a/src/builder/bundle/index.ts +++ b/src/builder/bundle/index.ts @@ -69,7 +69,10 @@ export default async (opts: { presetEnv: { targets: getBundleTargets(config), }, - presetReact: getBabelPresetReactOpts(opts.configProvider.pkg), + presetReact: getBabelPresetReactOpts( + opts.configProvider.pkg, + opts.cwd, + ), presetTypeScript: {}, pluginTransformRuntime: {}, pluginLockCoreJS: {}, diff --git a/src/builder/bundless/loaders/javascript/babel.ts b/src/builder/bundless/loaders/javascript/babel.ts index 88c1532b..abba4fa1 100644 --- a/src/builder/bundless/loaders/javascript/babel.ts +++ b/src/builder/bundless/loaders/javascript/babel.ts @@ -39,7 +39,10 @@ const babelTransformer: IJSTransformer = function (content) { targets: getBundlessTargets(this.config), modules: this.config.format === IFatherBundlessTypes.ESM ? false : 'auto', }, - presetReact: getBabelPresetReactOpts(this.pkg), + presetReact: getBabelPresetReactOpts( + this.pkg, + path.dirname(this.paths.fileAbsPath), + ), presetTypeScript: {}, }; @@ -68,7 +71,6 @@ const babelTransformer: IJSTransformer = function (content) { version: this.pkg.dependencies?.['@babel/runtime'], }; } - // TODO: recommend install @babel/runtime in doctor const { code, map } = transform(content, { filename: this.paths.fileAbsPath, cwd: this.paths.cwd, diff --git a/src/builder/bundless/loaders/javascript/swc.ts b/src/builder/bundless/loaders/javascript/swc.ts index 79d31622..c2acb6a1 100644 --- a/src/builder/bundless/loaders/javascript/swc.ts +++ b/src/builder/bundless/loaders/javascript/swc.ts @@ -143,7 +143,10 @@ const swcTransformer: IJSTransformer = async function (content) { ...(!isTSFile && isJSXFile ? { jsx: true } : {}), }, transform: { - react: getSWCTransformReactOpts(this.pkg), + react: getSWCTransformReactOpts( + this.pkg, + path.dirname(this.paths.fileAbsPath), + ), }, }, module: { diff --git a/src/builder/utils.ts b/src/builder/utils.ts index 797292f0..036b25ce 100644 --- a/src/builder/utils.ts +++ b/src/builder/utils.ts @@ -6,6 +6,7 @@ import { IFatherJSTransformerTypes, IFatherPlatformTypes, } from '../types'; +import { getTsconfig } from './bundless/dts'; import type { IBundlessConfig } from './config'; export function addSourceMappingUrl(code: string, loc: string) { @@ -16,16 +17,7 @@ export function addSourceMappingUrl(code: string, loc: string) { ); } -export function getIsLTRReact17(pkg: IApi['pkg']) { - const reactVer = Object.assign( - {}, - pkg.dependencies, - pkg.peerDependencies, - ).react; - return semver.subset(reactVer, '>=17.0.0-0'); -} - -export function getBaseTransformReactOpts(pkg: IApi['pkg']) { +export function getBaseTransformReactOpts(pkg: IApi['pkg'], cwd: string) { const reactVer = Object.assign( {}, pkg.dependencies, @@ -34,30 +26,44 @@ export function getBaseTransformReactOpts(pkg: IApi['pkg']) { let opts: Record = {}; if (reactVer) { - const isLTRReact17 = getIsLTRReact17(pkg); + let isNewJSX: boolean; + const tsconfig = getTsconfig(cwd); + + /* istanbul ignore else -- @preserve */ + if (tsconfig) { + // respect tsconfig first, `4` means `react-jsx` + isNewJSX = tsconfig.options?.jsx === 4; + } else { + // fallback to match react versions which support new JSX transform + // ref: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#how-to-upgrade-to-the-new-jsx-transform + isNewJSX = semver.subset( + reactVer, + '>=17.0.0-0||^16.14.0||^15.7.0||^0.14.10', + ); + } opts = { // force use production mode, to make sure dist of dev/build are consistent // ref: https://github.com/umijs/umi/blob/6f63435d42f8ef7110f73dcf33809e6cda750332/packages/babel-preset-umi/src/index.ts#L45 development: false, - // use legacy jsx runtime for react@<17 - runtime: isLTRReact17 ? 'automatic' : 'classic', - ...(isLTRReact17 ? {} : { importSource: undefined }), + // set jsx runtime automatically + runtime: isNewJSX ? 'automatic' : 'classic', + ...(isNewJSX ? {} : { importSource: undefined }), }; } return opts; } -export function getBabelPresetReactOpts(pkg: IApi['pkg']) { +export function getBabelPresetReactOpts(pkg: IApi['pkg'], cwd: string) { return { - ...getBaseTransformReactOpts(pkg), + ...getBaseTransformReactOpts(pkg, cwd), }; } -export function getSWCTransformReactOpts(pkg: IApi['pkg']) { +export function getSWCTransformReactOpts(pkg: IApi['pkg'], cwd: string) { return { - ...getBaseTransformReactOpts(pkg), + ...getBaseTransformReactOpts(pkg, cwd), }; } diff --git a/tests/fixtures/build/automatic-jsx/package.json b/tests/fixtures/build/automatic-jsx/package.json index 82a49442..6cfa74c3 100644 --- a/tests/fixtures/build/automatic-jsx/package.json +++ b/tests/fixtures/build/automatic-jsx/package.json @@ -1,5 +1,5 @@ { "dependencies": { - "react": "^17.0.0" + "react": "^16.14.0" } } diff --git a/tests/fixtures/build/automatic-jsx/tsconfig.json b/tests/fixtures/build/automatic-jsx/tsconfig.json new file mode 100644 index 00000000..a224293f --- /dev/null +++ b/tests/fixtures/build/automatic-jsx/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "jsx": "react-jsx" + } +}