没错,bun可以直接编译tsx。
我之前做谷歌插件(Any Bookmarks),就是用bun+tsx做的,没有webpack也没有vite。

Bun 对 TSX(TypeScript + JSX)提供了原生、零配置的一流支持。
一、直接运行:bun run app.tsx
Bun 最吸引人的特性是无需任何构建工具就能直接执行 TSX 文件。你只需要一个命令:
bash
bun run app.tsx
# 或简写为
bun app.tsx
来看一个完整的示例 app.tsx:
bash
// 无需 import React(配合 react-jsx 运行时)
interface User {
id: number;
name: string;
}
const UserCard = ({ user }: { user: User }) => {
return (
<div className="card">
<h2>{user.name}</h2>
<p>ID: {user.id}</p>
</div>
);
};
const data: User = { id: 1, name: "Alice" };
console.log(<UserCard user={data} />);
执行后,Bun 的内部转译器会在内存中即时将 TSX 转换为纯 JavaScript ,然后立即执行。整个过程通常在 50ms 以内 ,比 ts-node 或 webpack 开发服务器快得多。
对于 React 项目,Bun 还提供了官方模板:
bash
bun init --react
这会自动生成包含 tsconfig.json、index.tsx 和 index.html 的完整项目结构。
二、编译为 JavaScript 的三种方式
当需要部署到生产环境时,我们通常需要将 TSX 编译为纯 JS 文件。Bun 提供了三种灵活的方式。
2.1 使用 Bun.build API(打包整个项目)
Bun.build 是官方推荐的打包方式,它会解析入口文件的所有依赖,并输出优化后的 JS 文件。
创建一个 build.js 脚本:
bash
// build.js
const result = await Bun.build({
entrypoints: ['./src/index.tsx'], // 入口
outdir: './dist', // 输出目录
target: 'browser', // 目标环境:'browser' | 'bun' | 'node'
minify: true, // 是否压缩
splitting: true, // 是否代码分割(自动分块)
sourcemap: 'external', // 生成外部 sourcemap
// 可指定外部依赖,不打包进 bundle
external: ['react', 'react-dom'],
});
if (!result.success) {
console.error('构建失败:', result.logs);
process.exit(1);
}
console.log('✅ 构建成功! 输出文件:');
result.outputs.forEach(file => console.log(` - ${file.path}`));
运行:
bash
bun run build.js
输出到 ./dist 目录下的就是纯 JavaScript 文件,所有 TSX 语法已转换,可直接在浏览器或 Node.js 中运行。
2.2 使用 CLI 命令 bun build
如果你更习惯命令行,Bun 也提供了 bun build 命令,功能与 API 一致:
bash
bun build ./src/index.tsx --outdir ./dist --target browser --minify
该命令会输出打包后的 JS 文件,非常适合在 package.json 的 scripts 中配置:
bash
{
"scripts": {
"build": "bun build ./src/index.tsx --outdir ./dist --target browser --minify"
}
}
2.3 使用 Bun.Transpiler 进行代码级转译
如果你只想将 TSX 字符串转换为 JS 字符串,而不处理模块依赖,可以使用 Bun.Transpiler 类。这适用于构建工具链、在线编辑器或动态代码执行场景。
bash
import { Transpiler } from 'bun';
const transpiler = new Transpiler({
loader: 'tsx', // 指定为 tsx 加载器
tsconfig: './tsconfig.json', // 可选:指定 tsconfig 路径
});
const tsxSource = `
import React from 'react';
const App = () => <div>Hello, {props.name}</div>;
export default App;
`;
// 同步转译
const jsOutput = transpiler.transformSync(tsxSource);
console.log(jsOutput);
// 输出:转换后的标准 JavaScript 代码(字符串)
// 也支持异步转译
const asyncResult = await transpiler.transform(tsxSource);
console.log(asyncResult);
这个方法只做语法转换,不会打包或处理 import 语句,适合轻量级场景。
三、配置细节:tsconfig.json 与 bunfig.toml
Bun 会读取项目根目录的 tsconfig.json 来控制 TSX 编译行为。推荐配置如下:
bash
{
"compilerOptions": {
"jsx": "react-jsx", // 使用新 JSX 转换(无需 import React)
"jsxImportSource": "react", // 默认 react
"target": "ESNext",
"module": "ESNext",
"strict": true,
"esModuleInterop": true
}
}
重要限制 :Bun 不支持 "jsx": "preserve",因为 Bun 必须实际转换 JSX 才能执行,若设置 preserve 会报错。
你也可以在 bunfig.toml 中配置 JSX(优先级低于 tsconfig.json):
bash
[jsx]
runtime = "automatic" # "automatic" 或 "classic"
importSource = "react"
四、性能与注意事项
Bun 的转译器只负责语法转换,不执行类型检查 。这意味着即使存在类型错误,bun run 也能正常执行。例如:
bash
// type-error.tsx
const count: number = "这是一个字符串"; // 类型错误
console.log(count); // Bun 能正常运行!
生产最佳实践 :在 CI/CD 流程中单独运行 tsc --noEmit 进行类型检查,确保代码类型安全。
bash
{
"scripts": {
"type-check": "tsc --noEmit",
"build": "bun run type-check && bun build ./src/index.tsx --outdir ./dist"
}
}
五、总结
| 使用场景 | 推荐方式 | 命令/代码 | | :-- | :-- | :-- | | 开发调试 | 直接运行 | bun run app.tsx | | 生产打包 | Bun.build API 或 CLI | bun build ./src/index.tsx --outdir ./dist | | 动态转译 | Bun.Transpiler | new Transpiler({ loader: 'tsx' }).transformSync(code) |
Bun 对 TSX 的支持覆盖了从开发到部署的全链路,且性能优异。你只需记住:开发用 bun run,部署用 bun build,类型检查交给 tsc,三者各司其职,配合天衣无缝。