HTML 和静态站点
使用 Bun 的打包工具构建静态站点、落地页和 web 应用
Bun 的打包工具原生支持 HTML。无需任何配置即可构建静态站点、落地页和 Web 应用:将 HTML 文件交给 Bun,它就会打包该文件所引用的脚本、样式表和资源。
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="./styles.css" />
<script src="./app.ts" type="module"></script>
</head>
<body>
<img src="./logo.png" />
</body>
</html>
要开始使用,只需将 HTML 文件传入 bun。
bun ./index.html
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Press h + Enter to show shortcuts
无需配置时,Bun 的开发服务器提供:
- 自动打包 - 打包并提供你的 HTML、JavaScript 和 CSS
- 多入口支持 - 处理多个 HTML 入口点和 glob 入口点
- 现代 JavaScript - 默认支持 TypeScript 和 JSX
- 智能配置 - 读取
tsconfig.json中的路径、JSX 选项和实验性装饰器配置 - 插件 - 支持插件,包括 TailwindCSS
- ESM 和 CommonJS - 在 JavaScript、TypeScript 和 JSX 文件中使用 ESM 和 CommonJS
- CSS 打包与压缩 - 打包来自
<link>标签和@import语句的 CSS - 资源管理 - 复制并生成哈希化的图像和资源,同时重写 JavaScript、CSS 和 HTML 中的资源路径
单页应用 (SPA)
当你将一个 .html 文件传递给 Bun 时,Bun 会将其用作所有路径的回退路由。这适用于使用客户端路由的单页应用:
bun index.html
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Press h + Enter to show shortcuts
你的 React 或其他 SPA 无需任何配置即可运行。像 /about 和 /users/123 这样的路由会提供同一个 HTML 文件,因此由你的客户端路由器处理导航。
<!doctype html>
<html>
<head>
<title>我的 SPA</title>
<script src="./app.tsx" type="module"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
多页应用 (MPA)
有些项目有几个独立的路由或多个 HTML 文件作为入口点。要支持多个入口点,可以全部传给 bun:
bun ./index.html ./about.html
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Routes:
/ ./index.html
/about ./about.html
Press h + Enter to show shortcuts
这会提供:
/路由对应index.html/about路由对应about.html
通配符模式
要指定多个文件,请使用以 .html 结尾的 glob 模式:
bun ./**/*.html
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Routes:
/ ./index.html
/about ./about.html
Press h + Enter to show shortcuts
路径规范化
Bun 根据所有文件中最长的公共前缀选择基础路径。
bun ./index.html ./about/index.html ./about/foo/index.html
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Routes:
/ ./index.html
/about ./about/index.html
/about/foo ./about/foo/index.html
Press h + Enter to show shortcuts
JavaScript、TypeScript 和 JSX
Bun 的转译器原生支持 JavaScript、TypeScript 和 JSX。请参阅加载器。
ES 模块与 CommonJS
您可以在 JavaScript、TypeScript 和 JSX 文件中使用 ESM 和 CommonJS。Bun 会自动转译并打包它们。
无需预构建或单独的优化步骤。Bun 会同时完成所有这些工作。
请参阅模块解析。
CSS
Bun 的 CSS 解析器也是原生实现的(约 70,000 行 Rust 代码)。
它也是一个 CSS 打包器。你可以在 CSS 文件中使用 @import 导入其他 CSS 文件。
例如:
@import "./abc.css";
.container {
background-color: blue;
}
body {
background-color: red;
}
最终输出为:
body {
background-color: red;
}
.container {
background-color: blue;
}
CSS 中引用本地资源
body {
background-image: url("./logo.png");
}
Bun 会将 ./logo.png 复制到输出目录,并重写 CSS 文件中的路径以包含内容哈希。
body {
background-image: url("./logo-[ABC123].png");
}
在 JavaScript 中导入 CSS
要将 CSS 文件与 JavaScript 文件关联,请在 JavaScript 文件中导入它。
import "./styles.css";
import "./more-styles.css";
这会在输出目录中生成 ./app.css 和 ./app.js。Bun 会将从 JavaScript 导入的所有 CSS 文件打包到每个入口点对应的单个 CSS 文件中。如果你从多个 JavaScript 文件导入同一个 CSS 文件,Bun 只会在输出的 CSS 文件中包含它一次。
插件
开发服务器支持插件。
Tailwind CSS
要使用 TailwindCSS,安装 bun-plugin-tailwind 插件:
# 或任意 npm 客户端
bun install --dev bun-plugin-tailwind
然后,将插件添加到你的 bunfig.toml:
[serve.static]
plugins = ["bun-plugin-tailwind"]
然后,在 HTML 中通过 <link> 标签、CSS 中的 @import,或 JavaScript 中的导入来引用 TailwindCSS。
<!-- 在 HTML 中引用 TailwindCSS -->
<link rel="stylesheet" href="tailwindcss" />
@import "tailwindcss";
import "tailwindcss";
内联环境变量
Bun 可以在构建时将 JavaScript 和 TypeScript 中的 process.env.* 引用替换为其实际值。你可以使用此功能将 API URL 或功能标志等配置注入前端代码。
开发服务器(运行时)
使用 bun ./index.html 时,可在 bunfig.toml 中配置 env 选项以内联环境变量:
[serve.static]
env = "PUBLIC_*" # 仅内联以 PUBLIC_ 开头的环境变量(推荐)
# env = "inline" # 内联所有环境变量
# env = "disable" # 禁用环境变量替换(默认)
然后运行开发服务器:
PUBLIC_API_URL=https://api.example.com bun ./index.html
生产构建
构建静态 HTML 生产版本时,使用 env 选项内联环境变量:
# 内联所有环境变量
bun build ./index.html --outdir=dist --env=inline
# 仅内联带指定前缀的环境变量(推荐)
bun build ./index.html --outdir=dist --env=PUBLIC_*
// 内联所有环境变量
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
env: "inline", // [!code highlight]
});
// 仅内联带指定前缀的环境变量(推荐)
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
env: "PUBLIC_*", // [!code highlight]
});
示例
给定以下源文件:
const apiUrl = process.env.PUBLIC_API_URL;
console.log(`API URL: ${apiUrl}`);
使用 PUBLIC_API_URL=https://api.example.com 运行:
PUBLIC_API_URL=https://api.example.com bun build ./index.html --outdir=dist --env=PUBLIC_*
捆绑后的输出包含:
const apiUrl = "https://api.example.com";
console.log(`API URL: ${apiUrl}`);
将浏览器控制台日志回显至终端
Bun 的开发服务器可以将浏览器中的控制台日志流式传输到终端。要启用此功能,请传入 --console CLI 标志。
bun ./index.html --console
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Press h + Enter to show shortcuts
Bun 会将每次 console.log 或 console.error 调用广播到启动服务器的终端,因此浏览器错误会显示在运行服务器的同一位置。这也有助于监视终端输出的 AI 代理。
在内部,Bun 会复用热模块替换(HMR)现有的 WebSocket 连接来发送日志。
在浏览器中编辑文件
Bun 的前端开发服务器支持 Chrome DevTools 中的自动工作区文件夹,因此你可以从浏览器保存对文件的编辑。
键盘快捷键
服务器运行时:
o + Enter- 在浏览器中打开c + Enter- 清除控制台q + Enter或Ctrl+C- 退出服务器。
生产构建
准备部署时,使用 bun build 创建优化的生产包:
bun build ./index.html --minify --outdir=dist
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
minify: true,
});
监听模式
运行 bun build --watch 以监听更改并自动重新构建。这非常适合库开发。
插件 API
如需进行更多控制,可以通过 JavaScript API 配置打包器,并使用 Bun 内置的 HTMLRewriter 预处理 HTML。
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
minify: true,
plugins: [
{
// 一个将所有 HTML 标签名改为小写的插件
name: "lowercase-html-plugin",
setup({ onLoad }) {
const rewriter = new HTMLRewriter().on("*", {
element(element) {
element.tagName = element.tagName.toLowerCase();
},
text(element) {
element.replace(element.text.toLowerCase());
},
});
onLoad({ filter: /\.html$/ }, async args => {
const html = await Bun.file(args.path).text();
return {
// Bun 的打包器会自动扫描 HTML 中的 <script> 标签、<link rel="stylesheet"> 标签及其他资源并打包
contents: rewriter.transform(html),
loader: "html",
};
});
},
},
],
});
处理了哪些内容?
Bun 自动处理所有常见的 Web 资源:
- 脚本 (
<script src>) 会进入 Bun 的 JavaScript/TypeScript/JSX 打包器 - 样式表 (
<link rel="stylesheet">) 会进入 Bun 的 CSS 解析器和打包器 - 图片 (
<img>,<picture>) 会复制并哈希处理 - 媒体 (
<video>,<audio>,<source>) 会复制并哈希 - 任何带有指向本地文件
href的<link>标签会被重写路径并哈希
Bun 会根据 HTML 文件解析所有路径,因此你可以按照任意方式组织项目。
工作原理
开发服务器是一个小型封装层,用于支持 Bun 在 JavaScript 中的 HTML 导入。
单文件独立 HTML
你可以使用 --compile --target=browser 将整个前端打包成一个自包含的单个 .html 文件,且无需外部依赖。Bun 会将所有 JavaScript、CSS 和图像直接内联到 HTML 中。
bun build --compile --target=browser ./index.html --outdir=dist
了解更多内容请参见单文件独立 HTML 文档。
给前端添加后端
要为前端添加后端,请使用 Bun.serve 中的 routes 选项。请参阅全栈文档。