bun直接tsx,优雅!

没错,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-nodewebpack 开发服务器快得多。

对于 React 项目,Bun 还提供了官方模板:

bash 复制代码
bun init --react

这会自动生成包含 tsconfig.jsonindex.tsxindex.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.jsonscripts 中配置:

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,三者各司其职,配合天衣无缝。

相关推荐
Cosolar2 小时前
藏在 Claude Code 里的极致浪漫:完整 187 条 Spinner Verbs 全收录
后端·程序员·代码规范
Csvn3 小时前
Linux 防火墙管理 — firewalld 实战
后端
Csvn3 小时前
`functools.lru_cache` —— 一行代码搞定缓存加速
后端·python
leeyi3 小时前
Multi-Agent:让多个 AI 分工协作完成复杂任务
后端·aigc·agent
长栎3 小时前
你的策略模式是 Map<String, Strategy>?那不过是最廉价的 if-else 替代品
后端
长栎3 小时前
你写的 abstract class 里全是钩子方法——模板模式不是让你填空,是让你别越界
后端
ping某3 小时前
语法树,到底是一棵什么形状的树?
后端
_柳青杨3 小时前
一文吃透 Node.js 事件循环:从原理到 Node 20+ 重大变更
javascript·后端
Alson_Code4 小时前
人机协作项目文档--HITL-AgentScope
后端·aigc·ai编程