1. 了解 JSX Transform

JSX:

1
2
3
4
5
import React from 'react';

function App() {
return <h1>Hello World</h1>;
}

原来的转换方式:

1
2
3
4
5
6
// 转换后需要调用 React.createElement,所以必须先手动引入 React
import React from 'react';

function App() {
return React.createElement('h1', null, 'Hello world');
}

新的转换方式:

1
2
3
4
5
6
// Inserted by a compiler (don't import it yourself!)
import { jsx as _jsx } from 'react/jsx-runtime';

function App() {
return _jsx('h1', { children: 'Hello world' });
}

2. 如何升级

默认支持新的转换方式

  • Create React App 4.0.0+
  • React 17
  • Next.js v9.5.3+
  • Gatsby v2.24.5+
  • TypeScript v4.1+

手动修改 Babel

  1. 升级 Babel 到 v7.9.0+
    1
    2
    3
    npm update @babel/core @babel/plugin-transform-react-jsx
    # or
    yarn upgrade @babel/core @babel/plugin-transform-react-jsx
  2. 升级 @babel/preset-react
    1
    2
    3
    npm update @babel/core @babel/preset-react
    # or
    yarn upgrade @babel/core @babel/preset-react
  3. .babelrc.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // If you're using @babel/plugin-transform-react-jsx
    {
    "plugins": [
    ["@babel/plugin-transform-react-jsx", {
    "runtime": "automatic"
    }]
    ]
    }

    // If you are using @babel/preset-react
    {
    "presets": [
    ["@babel/preset-react", {
    "runtime": "automatic"
    }]
    ]
    }

    Starting from Babel 8, “automatic” will be the default runtime for both plugins.

ESLint 中关掉 react-in-jsx-scope

1
2
3
4
5
6
7
8
{
// ...
"rules": {
// ...
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off"
}
}

最后,官方提供了一键更新项目中文件引入React的工具

1
2
cd your_project
npx react-codemod update-react-imports

还是比较靠谱的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';

function App() {
const [text, setText] = React.useState('Hello World');
return <h1>{text}</h1>;
}

// 将转换成如下:

import { useState } from 'react';

function App() {
const [text, setText] = useState('Hello World');
return <h1>{text}</h1>;
}