> ## Documentation Index
> Fetch the complete documentation index at: https://bun.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JSX

> Bun 内置的 JSX 和 TSX 支持，具有可配置的转译选项

Bun 开箱即支持 `.jsx` 和 `.tsx` 文件。Bun 的内部转译器会在执行前将 JSX 语法转换为原生 JavaScript。

```ts react.tsx icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
function Component(props: {message: string}) {
  return (
    <body>
      <h1 style={{color: 'red'}}>{props.message}</h1>
    </body>
  );
}

console.log(<Component message="Hello world!" />);
```

## 配置

Bun 会读取你的 `tsconfig.json` 或 `jsconfig.json` 配置文件，以确定如何在内部执行 JSX 转换。为了避免使用这两者，也可以在 [`bunfig.toml`](/runtime/bunfig) 中定义以下选项。

下面的编译器选项将被遵循。

### [`jsx`](https://www.typescriptlang.org/tsconfig#jsx)

JSX 构造如何被内部转换成原生 JavaScript。下表列出了 `jsx` 的可能取值，以及对以下简单 JSX 组件的转译结果：

```tsx theme={"theme":{"light":"github-light","dark":"dracula"}}
<Box width={5}>Hello</Box>
```

| 编译器选项                                               | 转译输出                                                                                                                                                                                                                                                                                      |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `json<br/>{<br/>  "jsx": "react"<br/>}<br/>`        | `tsx<br/>import { createElement } from "react";<br/>createElement("Box", { width: 5 }, "Hello");<br/>`                                                                                                                                                                                    |
| `json<br/>{<br/>  "jsx": "react-jsx"<br/>}<br/>`    | `tsx<br/>import { jsx } from "react/jsx-runtime";<br/>jsx("Box", { width: 5 }, "Hello");<br/>`                                                                                                                                                                                            |
| `json<br/>{<br/>  "jsx": "react-jsxdev"<br/>}<br/>` | `tsx<br/>import { jsxDEV } from "react/jsx-dev-runtime";<br/>jsxDEV(<br/>  "Box",<br/>  { width: 5, children: "Hello" },<br/>  undefined,<br/>  false,<br/>  undefined,<br/>  this,<br/>);<br/>`<br /><br />`jsxDEV` 变量名是 React 约定用法。`DEV` 后缀直观地表明该代码用于开发环境。React 开发版本较慢，包含额外的有效性校验和调试工具。 |
| `json<br/>{<br/>  "jsx": "preserve"<br/>}<br/>`     | `tsx<br/>// JSX 不被转译<br/>// Bun 当前不支持 "preserve"<br/><Box width={5}>Hello</Box><br/>`                                                                                                                                                                                                     |

### [`jsxFactory`](https://www.typescriptlang.org/tsconfig#jsxFactory)

<Note>**注意** — 仅当 `jsx` 为 `react` 时生效。</Note>

用于表示 JSX 构造的函数名。默认值为 `"createElement"`。此选项对像 [Preact](https://preactjs.com/) 之类使用不同函数名称（`"h"`）的库很有用。

| 编译器选项                                                                 | 转译输出                                                                           |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `json<br/>{<br/>  "jsx": "react",<br/>  "jsxFactory": "h"<br/>}<br/>` | `tsx<br/>import { h } from "react";<br/>h("Box", { width: 5 }, "Hello");<br/>` |

### [`jsxFragmentFactory`](https://www.typescriptlang.org/tsconfig#jsxFragmentFactory)

<Note>**注意** — 仅当 `jsx` 为 `react` 时生效。</Note>

用于表示 [JSX 片段](https://react.dev/reference/react/Fragment)（如 `<>Hello</>`）的函数名；仅当 `jsx` 为 `react` 时生效。默认值为 `"Fragment"`。

| 编译器选项                                                                                                               | 转译输出                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `json<br/>{<br/>  "jsx": "react",<br/>  "jsxFactory": "myjsx",<br/>  "jsxFragmentFactory": "MyFragment"<br/>}<br/>` | `tsx<br/>// 输入<br/><>Hello</>;<br/><br/>// 输出<br/>import { myjsx, MyFragment } from "react";<br/>myjsx(MyFragment, null, "Hello");<br/>` |

### [`jsxImportSource`](https://www.typescriptlang.org/tsconfig#jsxImportSource)

<Note>**注意** — 仅当 `jsx` 为 `react-jsx` 或 `react-jsxdev` 时生效。</Note>

指定从哪个模块导入组件工厂函数（`createElement`，`jsx`，`jsxDEV` 等）。默认值为 `"react"`。通常在使用如 Preact 这样的组件库时需要设置。

| 编译器选项                                                                                            | 转译输出                                                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `jsonc<br/>{<br/>  "jsx": "react",<br/>  // jsxImportSource 未定义<br/>  // 默认为 "react"<br/>}<br/>` | `tsx<br/>import { jsx } from "react/jsx-runtime";<br/>jsx("Box", { width: 5, children: "Hello" });<br/>`                                                                                                                       |
| `jsonc<br/>{<br/>  "jsx": "react-jsx",<br/>  "jsxImportSource": "preact",<br/>}<br/>`            | `tsx<br/>import { jsx } from "preact/jsx-runtime";<br/>jsx("Box", { width: 5, children: "Hello" });<br/>`                                                                                                                      |
| `jsonc<br/>{<br/>  "jsx": "react-jsxdev",<br/>  "jsxImportSource": "preact",<br/>}<br/>`         | `tsx<br/>// 会自动添加 /jsx-runtime 后缀<br/>import { jsxDEV } from "preact/jsx-dev-runtime";<br/>jsxDEV(<br/>  "Box",<br/>  { width: 5, children: "Hello" },<br/>  undefined,<br/>  false,<br/>  undefined,<br/>  this,<br/>);<br/>` |

### JSX pragma

所有这些值都可以通过 *pragma* 按文件单独设置。pragma 是一种特殊注释，用于在特定文件中设置编译器选项。

| Pragma                                   | 等效配置                                                               |
| ---------------------------------------- | ------------------------------------------------------------------ |
| `ts<br/>// @jsx h<br/>`                  | `jsonc<br/>{<br/>  "jsxFactory": "h",<br/>}<br/>`                  |
| `ts<br/>// @jsxFrag MyFragment<br/>`     | `jsonc<br/>{<br/>  "jsxFragmentFactory": "MyFragment",<br/>}<br/>` |
| `ts<br/>// @jsxImportSource preact<br/>` | `jsonc<br/>{<br/>  "jsxImportSource": "preact",<br/>}<br/>`        |

## 日志记录

Bun 实现了 JSX 的特殊日志功能以便调试。以下文件为例：

```tsx index.tsx icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
import { Stack, UserCard } from "./components";

console.log(
  <Stack>
    <UserCard name="Dom" bio="Street racer and Corona lover" />
    <UserCard name="Jakob" bio="Super spy and Dom's secret brother" />
  </Stack>,
);
```

Bun 会漂亮地打印组件树：

<Frame>![JSX logging output](https://github.com/oven-sh/bun/assets/3084745/d29db51d-6837-44e2-b8be-84fc1b9e9d97)</Frame>

## 属性快速赋值（Prop punning）

Bun 运行时还支持 JSX 的“属性快速赋值”。这是一种对同名变量赋值给属性的简写语法。

```tsx react.tsx icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
function Div(props: {className: string;}) {
  const {className} = props;

  // 不使用快速赋值
  return <div className={className} />;
  // 使用快速赋值
  return <div {className} />;
}
```
