Appearance
JSX 在 Bun 中的使用
JSX 简介
JSX(JavaScript XML)是一种 JavaScript 的语法扩展,允许在 JavaScript 代码中编写类似 HTML 的标记。Bun 内置支持 .jsx
和 .tsx
文件,无需额外配置即可运行。
INFO
Bun 的内部转译器会在执行前将 JSX 语法转换为普通的 JavaScript,这个过程对开发者是透明的。
JSX 基本示例
下面是一个简单的 React 组件示例:
tsx
// 一个简单的 React 组件示例
function Component(props: {message: string}) {
return (
<body>
<h1 style={{color: 'red'}}>{props.message}</h1>
</body>
);
}
console.log(<Component message="Hello world!" />);
在上面的代码中,我们定义了一个接收 `message` 属性的组件,并在 `h1` 标签中显示这个消息。高亮部分是 JSX 语法。
JSX 配置选项
Bun 会自动读取项目中的 tsconfig.json
或 jsconfig.json
配置文件来确定如何处理 JSX 转换。如果不想使用这些配置文件,也可以在 bunfig.toml
中定义以下选项。
JSX 转换过程
JSX代码 配置选项 转换结果
┌────┐ ┌────┐ ┌────┐
│<Div>│ ──────► │jsx │ ──────► │普通JS│
└────┘ └────┘ └────┘
jsx
选项
jsx
选项决定了 JSX 构造如何转换为普通 JavaScript。下表展示了不同 jsx
值对于同一个简单组件的转换结果:
tsx
<Box width={5}>Hello</Box>
配置选项 | 转换输出 | 说明 |
---|---|---|
"react" | import { createElement } from "react"; createElement("Box", { width: 5 }, "Hello"); | 使用 React 的 createElement 函数 |
"react-jsx" | import { jsx } from "react/jsx-runtime"; jsx("Box", { width: 5, children: "Hello" }); | 使用 React 17+ 的新 JSX 转换 |
"react-jsxdev" | import { jsxDEV } from "react/jsx-dev-runtime"; jsxDEV("Box", { width: 5, children: "Hello" }, undefined, false, undefined, this); | 开发环境专用,包含额外的调试信息 |
"preserve" | <Box width={5}>Hello</Box> | 保留 JSX 语法不转换(Bun 目前不支持) |
> `jsxDEV` 是 React 开发版本使用的特殊函数,它包含额外的有效性检查和调试工具,但运行速度较慢。
jsxFactory
选项
WARNING
仅当 jsx
设置为 react
时适用。
此选项指定用于表示 JSX 构造的函数名称。默认值是 "createElement"
。这对于使用不同函数名的库(如 Preact 使用 "h"
)非常有用。
配置选项 | 转换输出 |
---|---|
{ "jsx": "react", "jsxFactory": "h" } | import { h } from "react"; h("Box", { width: 5 }, "Hello"); |
jsxFragmentFactory
选项
WARNING
仅当 jsx
设置为 react
时适用。
此选项指定用于表示 JSX 片段(如 <>Hello</>
)的函数名称。默认值是 "Fragment"
。
示例:
配置:
json
{
"jsx": "react",
"jsxFactory": "myjsx",
"jsxFragmentFactory": "MyFragment"
}
输入代码:
tsx
<>Hello</>
转换后:
tsx
import { myjsx, MyFragment } from "react";
myjsx(MyFragment, null, "Hello");
jsxImportSource
选项
WARNING
仅当 jsx
设置为 react-jsx
或 react-jsxdev
时适用。
此选项指定将从中导入组件工厂函数(createElement
、jsx
、jsxDEV
等)的模块。默认值是 "react"
。在使用 Preact 等组件库时通常需要设置此选项。
常见配置示例:
json
{
"jsx": "react-jsx"
// jsxImportSource 未定义,默认为 "react"
}
json
{
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
转换效果对比:
配置 | 转换输出 |
---|---|
React 默认 | import { jsx } from "react/jsx-runtime"; jsx("Box", { width: 5, children: "Hello" }); |
Preact 配置 | import { jsx } from "preact/jsx-runtime"; jsx("Box", { width: 5, children: "Hello" }); |
JSX 文件级设置:pragma 指令
所有上述配置选项都可以通过特殊注释(pragma)在单个文件中设置。这使得您可以针对特定文件覆盖全局配置。
Pragma 注释 | 等效配置 |
---|---|
// @jsx h | { "jsxFactory": "h" } |
// @jsxFrag MyFragment | { "jsxFragmentFactory": "MyFragment" } |
// @jsxImportSource preact | { "jsxImportSource": "preact" } |
JSX 在 Bun 中的增强功能
更好的日志输出
Bun 为 JSX 实现了特殊的日志功能,使调试变得更容易。例如:
tsx
import { Stack, UserCard } from "./components";
console.log(
<Stack>
<UserCard name="Dom" bio="街头赛车手,科罗娜爱好者" />
<UserCard name="Jakob" bio="超级间谍,Dom的秘密兄弟" />
</Stack>,
);
当您使用 console.log
打印上述组件时,Bun 会以易读的树形式显示组件结构:
<Stack>
<UserCard name="Dom" bio="街头赛车手,科罗娜爱好者" />
<UserCard name="Jakob" bio="超级间谍,Dom的秘密兄弟" />
</Stack>
这种可视化的日志输出大大提高了开发过程中的调试效率!
属性简写(Prop Punning)
Bun 运行时支持 JSX 的"属性简写"语法。当变量名与属性名相同时,这种简写语法非常有用。
问题陈述: 在 React 组件中,我们经常需要将同名变量传递给属性,导致代码重复。
解决方案:
tsx
function Div(props: {className: string;}) {
const {className} = props;
// 传统方式
return <div className={className} />;
// 使用属性简写
return <div {className} />; // 更简洁!
}
分析:
- 传统方式需要写两次
className
:一次是属性名,一次是变量名 - 使用属性简写语法,只需写一次变量名,代码更简洁
- 这种语法特别适合需要传递多个属性的场景
高级用例:多属性简写
tsx
function UserProfile(props) {
const {name, age, email, avatar} = props;
// 使用属性简写传递多个属性
return (
<Profile
{name}
{age}
{email}
{avatar}
/>
);
}
JSX 转换原理总结
┌────────────────────────────────────────────┐
│ │
│ JSX文件(.jsx/.tsx) ──┐ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ Bun内部转译器 │ │
│ │ ├─ 读取配置: │ │
│ │ │ ├─ tsconfig.json │ │
│ │ │ ├─ jsconfig.json │ │
│ │ │ └─ bunfig.toml │ │
│ │ │ │ │
│ │ └─ 应用转换规则 │ │
│ └───────────────┬──────────────────┘ │
│ │ │
│ ▼ │
│ 普通JavaScript ──► 执行 │
│ │
└────────────────────────────────────────────┘
实践建议
选择合适的 JSX 转换模式:
- 对于 React 17 及以上版本,推荐使用
"react-jsx"
- 开发环境可考虑使用
"react-jsxdev"
获得更好的调试体验
- 对于 React 17 及以上版本,推荐使用
库兼容性:
- 使用 Preact 时,设置
"jsxImportSource": "preact"
- 使用其他库时,查阅相关文档了解所需配置
- 使用 Preact 时,设置
性能考量:
- 生产环境避免使用
"react-jsxdev"
,因为它包含额外的调试信息,会影响性能 - 开发环境可以利用 Bun 的 JSX 日志增强功能进行更高效的调试
- 生产环境避免使用
理解 JSX 转换的工作原理对于排查问题和优化应用程序至关重要。确保在项目中正确配置 JSX 相关选项,以获得最佳的开发体验和运行效率。