本篇是 Bun 1.0 推出后的初尝试。Bun 是一个集合所有 js 基础工具的运行时,以迄今为止最快的 js 运行时而著称
像 Node 一样,Bun
是一个运行时(runtime
), 而非什么新的语言。感觉 deno 的地位有点尴尬了。大家被他的宣传的速度所折服。
安装
官网推荐的是运行
1 | curl -fsSL https://bun.sh/install | bash |
但鉴于国内有墙的原因,bun 现在有 npm 包了,所以我更推荐另一种安装方法,更快更直接:
1 | npm i -g bun |
用以下命令检查是否安装成功:
1 | (base) ➜ ~ bun -v |
启用
项目初始化:
1 | mkdir bun-learn |
可以看到
package.json
文件被bun.lockb
文件替代,比起原来的 json 文件,这个文件写起来有点类似yml
的语法,用了缩进和换行,不用花括号- 直接生成了
tsconfig.json
文件, bun 原生支持了ts
跑单个文件,和 node 用法类似,当然run
可以省略:
1 | bun run index.ts |
简单的服务
我们在 index.ts
里写上:
1 | const server = Bun.serve({ |
终端跑 index.ts
, 浏览器可以看到 hello Bun!
的字样。当然,直接跑的话我们改 index.ts
要重启项目,可以加上 --watch
参数:
1 | bun --watch index.ts |
进一步优化,创建一个 env 文件touch .env
,将配置写在该文件里,
1 | PORT = 8889 |
index.ts
文件里 port
参数改:
1 | --- port: 5678, |
可以见到,以前用node
时,我们须安装 process
包,并且引入,才能用 process.env.PORT
的,现在直接用Bun
,课件Bun
把很多第三方库,如 process
也集成了, 无需二次下载。
处理路由
把 fecth
函数改写如下:
1 | fetch (req) { |
bunx
类似 npx
的使用,直接运行二进制码,无须下载安装包,他自带了个 cowsay
命令,可以体验 bunx
的用法,命令行运行 bunx cowsay Hell Bun
1 | (base) ➜ bun-learn bunx cowsay Hello Bun |
前端脚手架
react
官方脚手架,在 Bun 中使用如下:
1 | bun create react-app <yourAppName> |
vite
的脚手架:
1 | bun create vite <yourAppName> --template vue |
模块化引入
bun 直接支持 es module
和 commonjs
两种模块引入,也不用在 package.json
里做出其他配置,解决了困扰了 node
多年的模块引入问题。
下面是一个简单的 demo,新建一个文件 module.ts
1 | touch module.ts |
以下我们用 path
模块举例:
1 | import path from "path"; |
跑了后控制台可看到:
1 | (base) ➜ bun-learn bun module.ts |
一些常用模块在 Bun 中的使用
file
模块
Bun.write()
写入文件:
1 | touch file-demo.ts |
写下:
1 | const data = "I love Bun!"; |
从以上代码可以看出,
Bun
和deno
一样,支持顶层的await
语法,无须像 node 一样包装在async
函数里使用await
Bun.write()
接口可写入文件
跑 bun file-demo.ts
可以看到当前目录下生成了 file-demo.txt
文件,并在文件里写下了 data 的内容。
await Bun.file().text()
读取文件
在上面的代码加上:
1 | const file = Bun.file("file-demo.txt"); |
控制台输出
1 | (base) ➜ bun-learn bun file-demo.ts |
- 这里值得注意,
Bun.file().text()
是异步接口,返回的是Promise
对象,所以必须用上await
关键字才能显示出内容
其他几个 file 的接口:
1 | console.log(await file.stream()); |
测试模块
bun 集成了 jest 的测试模块,我们在项目里直接创建测试文件:
1 | touch index.test.ts |
1 | import { describe, expect, test, beforeAll } from "bun:test"; |
可以看出,所有的 jest 模块都集成在 "bun:test"
原生包里,控制台跑的结果:
1 | (base) ➜ bun-learn bun test |
bundle 打包
我们来试试用 Bun 进行普通的 bundle 打包
在项目根目录创建以下文件夹和文件:
1 | ---src |
githubApi.ts
文件
前端 js 代码打包,所以暂时不用顶层 await
语法:
1 | import axios from "axios"; |
index.ts
文件
1 | import fetchUser from "./githubApi"; |
在命令行里运行:
1 | bun build ./src/index.ts --outfile=./dist/bundle.js |
可以看到dist
文件夹下生成了 bundle.js
将该文件放入 HTML 的 script 标签里则可使用
如果开发时,可以在 bun build 的命令加上 --watch
, 则可以热加载模式
1 | bun build ./src/index.ts --outfile=./dist/bundle.js --watch |
react 在项目中的应用
在我们原来的项目里添加 react
和 react-dom
1 | bun i react react-dom |
src 下创建 index.tsx
, 写一个简单的计数器:
1 | import React from "react"; |
在 dist 目录下,创建一个根目录 index.html
, 加上一下两行:
1 | <div id="root"></div> |
bash 下运行:
1 | bun build ./src/index.tsx --outfile=./dist/budle.js --watch |
打开 index.html
就可以看到该计数器