用 bun run 无法直接运行 HTML 文件,因其非可执行脚本;正确方式是用 Bun 编写极简 HTTP 服务(如 serve({ fetch }))或使用 esbuild --servedir=. 启动静态服务器。
用 bun run 直接打开 HTML 文件行不通
html 文件本身不是可执行脚本,bun run index.html 会报错 error: cannot find module 'index.html' —— bun 默认只识别 js/ts 模块,不内置静态文件服务能力。
真正能跑起来的,是用 Bun 写一个极简 HTTP 服务,把当前目录当静态资源根来 serve。核心就两步:写个 server.ts,再 bun run server.ts。
-
bun create http-server不是官方命令,别搜这个,Bun 没预置模板 - 不要试图用
bun run --watch index.html,watch 对纯 HTML 无效 - 浏览器直接双击打开
file://协议的 HTML,会因跨域限制让fetch、import等失效,必须走http://
用 Bun 写个 3 行静态服务(支持热更新)
新建 server.ts,内容如下:
import { serve } from "bun";
serve({
port: 3000,
fetch: (req) => new Response(Bun.file("./index.html")),
});
这只能返回固定 index.html,不处理 CSS/JS 路径。要真正支持整个项目(比如 /style.css、/script.js),得加路由逻辑:
- 用
new URL(req.url)解析路径,避免硬编码 - 对根路径
/返回index.html,其他路径尝试读取对应文件(如/main.js→./main.js) - 加
if (!file.exists)判断,否则 404 会崩掉进程 - 注意:Bun 默认不自动设置
Content-Type,CSS/JS 会被当成text/plain,需手动塞headers: { "Content-Type": "..."}
更稳的选择:bun run 启动 esbuild 或 vite
Bun 自带 esbuild,能一键起 dev server,比手写 serve 更靠谱:
立即学习“前端免费学习笔记(深入)”;
bun add -d esbuild
然后运行:
bun run esbuild --servedir=. --port=3000
这等价于 Python 的 python -m http.server,但支持现代 MIME 类型和缓存头。优势很明显:
- 不用写任何代码,
--servedir=.就指定当前为根目录 - 自动处理
.html、.js、.css、.png的 Content-Type - 支持
Accept-Ranges,视频/大文件拖动没问题 - 不支持 HMR(热模块替换),但纯 HTML + 静态资源开发完全够用
为什么不用 bun install 或 bun dev?
这些命令只在有 package.json 且定义了 "scripts": { "dev": "..." } 时才有效。Bun 不像 Node.js 生态默认绑定某个 bundler —— 它只是个更快的运行时 + 工具链,没有“开箱即用的 HTML 开发服务器”概念。
容易被忽略的一点:Bun 的 fetch 在服务端(serve 回调里)默认不支持 file:// 协议读取,所以 await fetch("file://./data.json") 会失败;必须用 Bun.file() 或 await Bun.file().text()。



















