Bun:下一代 JavaScript/TypeScript 运行时,从入门到实践
一、什么是 Bun?
Bun 是一个开箱即用、零配置的 JavaScript/TypeScript 运行时 + 包管理器,可以理解为 Node.js 的优化升级版。它的核心卖点就是快------内置了打包器、转译器、包管理器,不需要像 Node 生态那样拼装 Webpack + Babel + npm 才能跑起来。
有意思的是,Claude Code(就是你现在用来写代码的 AI 工具)底层就使用了 Bun 运行时。
安装
Windows 下通过 PowerShell 一键安装:
powershell
powershell -c "irm bun.sh/install/windows | iex"
安装后可以用 bun init 初始化项目,生成的结构非常简洁:
json
{
"name": "axios-demo",
"module": "index.ts",
"type": "module",
"dependencies": {
"axios": "^1.17.0",
"dotenv": "^17.4.2"
}
}
注意,Bun 项目原生支持 .ts 文件作为入口("module": "index.ts"),不需要额外配置 ts-node 或构建步骤。
二、TypeScript:为 JavaScript 加上类型约束
为什么需要 TypeScript?
JavaScript 是弱类型语言,看似灵活,实际暗藏风险。看这个例子:
html
<input type="text" id="ipt">
<script>
const ipt = document.getElementById("ipt");
ipt.addEventListener("change", function(){
console.log(event.target.value,
typeof event.target.value
);
})
</script>
用户在输入框里输入数字,我们下意识以为拿到的是 number,但实际上 typeof 的结果永远是 "string"。这种"不会报错的错误"可能悄悄藏在系统里很久而不被发现。
TypeScript 由微软开发,是 JavaScript 的超集------所有合法的 JS 代码都是合法的 TS 代码。它在 JS 之上添加了类型系统,让你可以这样写:
typescript
const nickname: string = "9527";
const age: number = 18;
console.log(`我是${nickname},我今年${age}岁`);
如果你尝试 const age: number = "18",编译器会直接报错,在编码阶段就把类型问题揪出来。
类型安全的函数
来看一个加法函数的例子:
typescript
function add(a: number, b: number) {
return a + b;
}
let a = 1;
let b = "2"; // 字符串!
// 三种转换方式:
add(a, parseInt(b)); // parseInt API
add(a, Number(b)); // Number 构造函数(推荐)
add(a, +b); // 隐式类型转换(不推荐,可读性差)
如果没有 TypeScript 的类型检查,add(1, "2") 会返回 "12"(字符串拼接)而不是 3(数学加法)。这就是典型的 JS 弱类型陷阱------不会报错,但结果完全错误。
TypeScript 已经是 AI Agent 开发的标配------在大型项目中,类型系统带来的可维护性和智能提示远超过起初多写几个类型标注的成本。
三、异步编程:从回调到 async/await
Bun 运行时同样支持标准的 Promise 和 async/await。
封装一个 sleep 函数
javascript
function sleep(t) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, t);
});
}
async function main() {
console.log('---start---');
await sleep(2000); // 等待 2 秒
console.log('---end---');
}
main();
解读:
Promise是 ES6 提供的异步解决方案------它代表一个"未来会完成"的操作sleep函数返回一个 Promise,在setTimeout完成后调用resolve表示兑现await后面必须跟 Promise(或 thenable 对象),它会暂停当前 async 函数的执行,等 Promise 完成后继续- 这就是"异步任务同步化"------用同步的写法写异步代码,彻底告别回调地狱
四、实战:用 Axios 调用 LLM API
最后来看一个完整的实战案例------用 Bun + Axios 调用 DeepSeek 大模型:
typescript
import axios from 'axios';
import dotenv from 'dotenv';
dotenv.config();
async function chat() {
try {
const res = await axios.post(
`${process.env.DEEPSEEK_BASE_URL}`,
{
model: 'deepseek-v4-flash',
messages: [{
role: 'user',
content: '你好,介绍一下Bun'
}]
},
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.DEEPSEEK_API_KEY}`
}
}
);
console.log(res.data.choices[0].message.content);
} catch (err: any) {
console.log(err.message);
}
}
chat();
关键知识点
GET vs POST:
- GET 请求有长度限制,且参数明文拼接在 URL 中,API Key 容易泄露
- POST 请求将数据放在请求体中,更安全,支持大体积数据(如图片上传)
HTTP 请求的结构(以这个例子拆解):
- 请求行 :
POST /v1/chat/completions HTTP/1.1 - 请求头 :
Content-Type: application/json、Authorization: Bearer sk-xxx - 请求体 :JSON 格式的
{ model, messages }
fetch vs axios:
fetch是浏览器和 Bun 内置的底层 HTTP APIaxios是封装了 fetch 的第三方框架,提供了拦截器、自动 JSON 解析、超时控制等企业级特性
错误处理 : 调用 LLM 接口可能遇到网络超时、服务繁忙、API Key 过期等问题,所以 try/catch 是必须的。
五、总结
| 技术点 | 一句话总结 |
|---|---|
| Bun | 比 Node 更快的 JS/TS 运行时,开箱即用 |
| TypeScript | JS 的超集,用类型系统在编译期消灭低级错误 |
| Promise + async/await | 异步任务同步化,是现代 JS 的核心能力 |
| Axios | 企业级 HTTP 请求库,封装了 fetch |
| POST vs GET | POST 把数据放请求体,更安全、无长度限制 |
整个学习路径是:语言基础(JS/TS)→ 运行时(Bun)→ 异步编程(Promise)→ 网络请求(Axios)→ 对接 AI 服务(LLM API),这就是一个现代 AI Agent 开发者的技能栈。