Bun

JSX

Bun 开箱即用支持 .jsx.tsx 文件。Bun 的内部转换器在执行前将 JSX 语法转换为纯 JavaScript。

react.tsx
function Component(props: {message: string}) {
  return (
    <body>
      <h1 style={{color: 'red'}}>{props.message}</h1>
    </body>
  );
}

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

配置

Bun 读取您的 tsconfig.jsonjsconfig.json 配置文件,以确定如何在内部执行 JSX 转换。为了避免使用其中任何一个,还可以在 bunfig.toml 中定义以下选项。

尊重以下编译器选项。

jsx

JSX 构造如何内部转换为纯 JavaScript。下表列出了 jsx 的可能值,以及对以下简单 JSX 组件的转换

<Box width={5}>Hello</Box>
编译器选项转换输出
{
  "jsx": "react"
}
import { createElement } from "react";
createElement("Box", { width: 5 }, "Hello");
{
  "jsx": "react-jsx"
}
import { jsx } from "react/jsx-runtime";
jsx("Box", { width: 5 }, "Hello");
{
  "jsx": "react-jsxdev"
}
import { jsxDEV } from "react/jsx-dev-runtime";
jsxDEV(
  "Box",
  { width: 5, children: "Hello" },
  undefined,
  false,
  undefined,
  this,
);

jsxDEV 变量名是 React 使用的约定。DEV 后缀是指示代码旨在用于开发的可见方式。React 的开发版本较慢,并且包括其他有效性检查和调试工具。

{
  "jsx": "preserve"
}
// JSX is not transpiled
// "preserve" is not supported by Bun currently
<Box width={5}>Hello</Box>

jsxFactory

注意 — 仅当 jsxreact 时才适用。

用于表示 JSX 构造的函数名称。默认值为 "createElement"。这对于使用不同函数名称("h")的库(如 Preact)很有用。

编译器选项转换输出
{
  "jsx": "react",
  "jsxFactory": "h"
}
import { h } from "react";
h("Box", { width: 5 }, "Hello");

jsxFragmentFactory

注意 — 仅当 jsxreact 时才适用。

用于表示 JSX 片段(如 <>Hello</>)的函数名称;仅当 jsxreact 时适用。默认值为 "Fragment"

编译器选项转换输出
{
  "jsx": "react",
  "jsxFactory": "myjsx",
  "jsxFragmentFactory": "MyFragment"
}
// input
<>Hello</>;

// output
import { myjsx, MyFragment } from "react";
myjsx(MyFragment, null, "Hello");

jsxImportSource

注意 — 仅当 jsxreact-jsxreact-jsxdev 时适用。

将从中导入组件工厂函数(createElementjsxjsxDEV 等)的模块。默认值为 "react"。在使用 Preact 等组件库时,通常需要这样做。

编译器选项转换输出
{
  "jsx": "react"
  // jsxImportSource is not defined
  // default to "react"
}
import { jsx } from "react/jsx-runtime";
jsx("Box", { width: 5, children: "Hello" });
{
  "jsx": "react-jsx",
  "jsxImportSource": "preact"
}
import { jsx } from "preact/jsx-runtime";
jsx("Box", { width: 5, children: "Hello" });
{
  "jsx": "react-jsxdev",
  "jsxImportSource": "preact"
}
// /jsx-runtime is automatically appended
import { jsxDEV } from "preact/jsx-dev-runtime";
jsxDEV(
  "Box",
  { width: 5, children: "Hello" },
  undefined,
  false,
  undefined,
  this,
);

JSX 语法

所有这些值都可以使用语法逐个文件设置。语法是一种特殊注释,用于在特定文件中设置编译器选项。

语法等效配置
// @jsx h
{
  "jsxFactory": "h"
}
// @jsxFrag MyFragment
{
  "jsxFragmentFactory": "MyFragment"
}
// @jsxImportSource preact
{
  "jsxImportSource": "preact"
}

日志记录

Bun 为 JSX 实施了特殊日志记录,以简化调试。给定以下文件

index.tsx
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 将在记录时美化打印组件树

Prop 双关

Bun 运行时还支持 JSX 的“prop 双关”。这是一种简写语法,可用于将变量分配给具有相同名称的 prop。

function Div(props: {className: string;}) {
  const {className} = props;

  // without punning
  return <div className={className} />;
  // with punning
  return <div {className} />;
}