浏览器无法识别 JSX 语法,在过去,React 会将我们编写的 JSX 代码转换成 React.createElement(...)但这样会存在以下的问题:
- 我们在编写代码时,不得不引入 React,即使我们的代码里没有引入任何的 React API。因为当构建工具完成代码编译后,我们的代码都会调用 React 的 createElement 方法,所以必须写
import React from "react"; - 而本身 React 并不止暴露了 createElemnt 这一个 API,这回导致将React 的所有导出的部分都打包进这个模块,加大了 bundle 的体积。 所以,React 17 版本开始,引入了全新的 JSX 转换机制,被称为 JSX runtime。
通过 JSX runime,我们的 JSX 代码会被编译成以下代码:
import {jsx as _jsx} from 'react/jsx-runtime';
function App() {
return _jsx('h1', { children: 'Hello world' });
}
我们不再需要一些模块中引入不必要的 React 模块了。同时,因为使用了具名导出,我们可以利用构建工具的 tree shaking 功能来优化 bundle 的体积。 除了 jsx,react/jsx-runtime 还导出了 jsxs。jsx 用于创建没有子元素或者只有一个子元素的元素,jsxs则用于创建含有多个子元素的元素。
import { jsxs } from 'react/jsx-runtime';
const element = jsxs("div", {
className: "my-class",
children: [
jsx("span", { children: "First Child" }),
jsx("span", { children: "Second Child" })
]
});
新版的 JSX runtime 在减少 bundle 体积方面,只能说是略微改善。因为打包工具在处理模块时,普遍存在缓存机制,也就是说你在 A 组件全量引用了 React,在 B 组件再引用一次是不会在打包文件中再加上一个 React,并不是 1 + 1 的关系。