JSX 的使用
前言
JSX 一种 JavaScript 的语法扩展,它类似于模板语言,但具有 JavaScript 的全部功能。JSX 可以生成 React 元素,也可以生成其他任何类型的值。Writing Markup with JSX – React
New JSX Transform
React v17.0 – React Blog, 中引入了 New JSX Transform
, Introducing the New JSX Transform – React Blog.
在 React 17 之前, JSX 都是编译成 React.createElement
方法,所以代码中,必需引入 react
.但在 React 17 之后,JSX 会被编译成 _jsx
方法, 引入的组件不需要自行添加,是编译器添加的, 这样就可以灵活决定用什么 jsx
,可以是 react/jsx-runtime
也可以是 @emotion/react
:
// 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' });
}
新的 JSX Transform 的好处:
- With the new transform, you can use JSX without importing React.
- Depending on your setup, its compiled output may slightly improve the bundle size.
- It will enable future improvements that reduce the number of concepts you need to learn React.
JSX Pragma
对于有些框架, 比如 CRA 是无法修改编译器的配置,所以需要通过 JSX Pragma
来指定编译器。
编译工具
JSX 的最大好处就是开发的时候,我们可以写类似组件的形式代码,在编译后, 转换为对应的函数,生成 DOM.
编译 JSX 通常是 babel, swc, esbuild 这类工具处理。我们需要关注的是设置 rumtime
和 importSource
两个参数。
runtime
:classic | automatic
: 默认classic
, 建议修改成automatic
来使用New JSX Transform
importSource
:string
: 指定 jsx 从什么模块导入, 默认是react
.
babel
@babel/plugin-transform-react-jsx · Babel, 默认 runtime 为 classic
SWC
比如我们使用 vite 的 vitejs/vite-plugin-react-swc: Speed up your Vite dev server with SWC,就会有对应的配置, runtime
默认为 automatic
, jsxImportSource
默认为 react
.
esbuild
比如 vite 的生成环境构建使用的就是 esbuild.
读取的 tsconfig.json
的配置: esbuild - Content Types,
Only certain tsconfig.json fields are respected
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxFactory": "React.createElement"
}
}
TS 设置
为了编译器能够正确的处理 JSX,我们需要设置 jsx
和 jsxImportSource
两个参数。特别是一些项目,如果直接用 tsc
编译的话。
jsx 配置
TypeScript: TSConfig Reference - Docs on every TSConfig option TypeScript: Documentation - JSX
TypeScript 提供了三种 JSX 模式:
- preserve: 组件代码不做编译,后置可能有其他工具处理,输出文件为
.jsx
- react: 将 JSX 转换为 React.createElement,输出文件为
.js
- react-jsx: 使用
New JSX Transform
,输出文件为.js
- react-jsxdev: 调用
jsxDev
, 输出.js
jsxImportSource 配置
TypeScript: TSConfig Reference - Docs on every TSConfig option
配置这个,可以指定 JSX 的函数,从什么包导入。
如何 JSX 支持其他框架
比如使用 preact 的 h
方法, 那么我们需要关注的是:
jsxFactory
jsxFragmentFactory
比如 tsconfig 配置:
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment"
}
}
使用的效果:
import { h, Fragment } from "preact";
const HelloWorld = () => (
<>
<div>Hello</div>
</>
);
将会编译成:
const preact_1 = require("preact");
const HelloWorld = () => ((0, preact_1.h)(preact_1.Fragment, null,
(0, preact_1.h)("div", null, "Hello")));
技术总结
- 使用 React 17+ 版本。
- JSX 设置
runtime
为automatic
,importSource
按需设置。 - TS 中也要配置
jsx
和jsxImportSource
两个参数。