> ## Documentation Index
> Fetch the complete documentation index at: https://bun.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HTML 和静态站点

> 使用 Bun 的打包工具构建静态站点、落地页和 web 应用

Bun 的打包工具对 HTML 拥有一级支持。可以零配置构建静态站点、落地页和 web 应用。只需将 Bun 指向你的 HTML 文件，其他一切交给它处理。

```html title="index.html" icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
<!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`。

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
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 入口点和通配符入口点
* **现代 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 会用这个文件作为所有路径的回退路由。这使得它非常适合使用客户端路由的单页应用：

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
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 文件，由客户端路由处理导航。

```html title="index.html" icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
<!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`：

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun ./index.html ./about.html
```

```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
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` 结尾的通配符模式：

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
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
```

### 路径规范化

基路径取所有文件最长的公共前缀。

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
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。你可以在 Bun 中了解更多关于加载器的内容。

<Note>Bun 的转译器也在运行时使用。</Note>

### ES 模块与 CommonJS

你可以在 JavaScript、TypeScript 和 JSX 文件中使用 ESM 和 CJS。Bun 会自动处理转译和打包。

无需预先构建或单独优化步骤，全程同步完成。

了解更多 Bun 中的模块解析。

## CSS

Bun 的 CSS 解析器同样原生实现（大约 58,000 行 Zig 代码）。

它也是一个 CSS 打包器。你可以在 CSS 文件中使用 `@import` 导入其他 CSS 文件。

例如：

<CodeGroup>
  ```css styles.css icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
  @import "./abc.css";

  .container {
    background-color: blue;
  }
  ```

  ```css abc.css icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
  body {
    background-color: red;
  }
  ```
</CodeGroup>

最终输出为：

```css styles.css icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
body {
  background-color: red;
}

.container {
  background-color: blue;
}
```

### CSS 中引用本地资源

你可以在 CSS 文件中引用本地资源。

```css styles.css icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
body {
  background-image: url("./logo.png");
}
```

这会将 `./logo.png` 复制到输出目录，并在 CSS 文件中重写路径以包含内容哈希。

```css styles.css icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
body {
  background-image: url("./logo-[ABC123].png");
}
```

### 在 JavaScript 中导入 CSS

要将 CSS 文件与 JavaScript 文件关联，可以在 JavaScript 中导入它。

```ts app.ts icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
import "./styles.css";
import "./more-styles.css";
```

这将在输出目录中生成 `./app.css` 和 `./app.js`。所有从 JavaScript 导入的 CSS 文件都会被打包成每个入口点的单个 CSS 文件。如果从多个 JavaScript 文件导入了同一个 CSS 文件，它在输出中仅会包含一次。

## 插件

开发服务器支持插件。

### Tailwind CSS

要使用 TailwindCSS，安装 `bun-plugin-tailwind` 插件：

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
# 或任意 npm 客户端
bun install --dev bun-plugin-tailwind
```

然后，将插件添加到你的 `bunfig.toml`：

```toml title="bunfig.toml" icon="settings" theme={"theme":{"light":"github-light","dark":"dracula"}}
[serve.static]
plugins = ["bun-plugin-tailwind"]
```

接着，在 HTML 中通过 `<link>` 标签、CSS 中的 `@import` 或 JavaScript 中导入引用 TailwindCSS。

<Tabs>
  <Tab title="index.html">
    ```html title="index.html" icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
    <!-- 在 HTML 中引用 TailwindCSS -->
    <link rel="stylesheet" href="tailwindcss" />
    ```
  </Tab>

  <Tab title="styles.css">
    ```css title="styles.css" icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
    @import "tailwindcss";
    ```
  </Tab>

  <Tab title="app.ts">
    ```ts title="app.ts" icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
    import "tailwindcss";
    ```
  </Tab>
</Tabs>

<Info>三者只需其中一个即可，无需全部添加。</Info>

## 内联环境变量

Bun 可以在构建时将 JavaScript 和 TypeScript 文件中的 `process.env.*` 替换为实际的值。这对将配置（如 API URL 或功能开关）注入前端代码非常有用。

### 开发服务器（运行时）

使用 `bun ./index.html` 时，可在 `bunfig.toml` 中配置 `env` 选项以内联环境变量：

```toml title="bunfig.toml" icon="settings" theme={"theme":{"light":"github-light","dark":"dracula"}}
[serve.static]
env = "PUBLIC_*"  # 仅内联以 PUBLIC_ 开头的环境变量（推荐）
# env = "inline"  # 内联所有环境变量
# env = "disable" # 禁用环境变量替换（默认）
```

<Note>
  仅支持直接字面量的 `process.env.FOO`，不支持 `import.meta.env` 或间接访问如 `const env = process.env; env.FOO`。

  若环境变量未设置，浏览器可能会出现运行时错误，如 `ReferenceError: process is not defined`。
</Note>

然后运行开发服务器：

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
PUBLIC_API_URL=https://api.example.com bun ./index.html
```

### 生产构建

构建静态 HTML 生产版本时，使用 `env` 选项内联环境变量：

<Tabs>
  <Tab title="CLI">
    ```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
    # 内联所有环境变量
    bun build ./index.html --outdir=dist --env=inline

    # 仅内联带指定前缀的环境变量（推荐）
    bun build ./index.html --outdir=dist --env=PUBLIC_*
    ```
  </Tab>

  <Tab title="API">
    ```ts title="build.ts" icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
    // 内联所有环境变量
    await Bun.build({
      entrypoints: ["./index.html"],
      outdir: "./dist",
      env: "inline", // [!code highlight]
    });

    // 仅内联带指定前缀的环境变量（推荐）
    await Bun.build({
      entrypoints: ["./index.html"],
      outdir: "./dist",
      env: "PUBLIC_*", // [!code highlight]
    });
    ```
  </Tab>
</Tabs>

### 示例

给定以下源文件：

```ts title="app.ts" icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
const apiUrl = process.env.PUBLIC_API_URL;
console.log(`API URL: ${apiUrl}`);
```

使用 `PUBLIC_API_URL=https://api.example.com` 运行：

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
PUBLIC_API_URL=https://api.example.com bun build ./index.html --outdir=dist --env=PUBLIC_*
```

打包输出将为：

```js title="dist/app.js" icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/javascript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=14ec2cbdf78f597f421d87adcffda9ac" theme={"theme":{"light":"github-light","dark":"dracula"}}
const apiUrl = "https://api.example.com";
console.log(`API URL: ${apiUrl}`);
```

## 将浏览器控制台日志回显至终端

Bun 的开发服务器支持将浏览器中的控制台日志流式传输到终端。

要启用，传入 CLI 参数 `--console`。

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun ./index.html --console
```

```
Bun v1.3.3
ready in 6.62ms
→ http://localhost:3000/
Press h + Enter to show shortcuts
```

每次调用 `console.log` 或 `console.error` 都会广播到启动服务器的终端。这对于在服务器运行同一终端查看浏览器错误非常有用，也适合监控终端输出的 AI 代理。

内部复用了热模块重载的现有 WebSocket 连接来发送日志。

## 在浏览器中编辑文件

Bun 的前端开发服务器支持 Chrome DevTools 的自动工作区文件夹功能，可让你在浏览器中保存文件修改。

## 键盘快捷键

服务器运行时：

* `o + Enter` - 在浏览器中打开
* `c + Enter` - 清除控制台
* `q + Enter` 或 `Ctrl+C` - 退出服务器

## 生产构建

准备部署时，使用 `bun build` 创建优化的生产包：

<Tabs>
  <Tab title="CLI">
    ```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
    bun build ./index.html --minify --outdir=dist
    ```
  </Tab>

  <Tab title="API">
    ```ts title="build.ts" icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
    await Bun.build({
      entrypoints: ["./index.html"],
      outdir: "./dist",
      minify: true,
    });
    ```
  </Tab>
</Tabs>

<Warning>
  当前，插件仅支持通过 `Bun.build` 的 API 或通过前端开发服务器的 `bunfig.toml` 使用，还不支持 `bun build` CLI。
</Warning>

### 监听模式

你可以运行 `bun build --watch` 自动监听文件变更并重建，非常适合库开发。

<Info>你从未见过如此快速的监听模式。</Info>

## 插件 API

需要更灵活的控制？可以通过 JavaScript API 配置打包器，并使用 Bun 内置的 `HTMLRewriter` 预处理 HTML。

```ts title="build.ts" icon="https://mintcdn.com/bun-zhcndoc/cnUTwgMuf4cCrwC-/icons/typescript.svg?fit=max&auto=format&n=cnUTwgMuf4cCrwC-&q=85&s=e7767043c9e885c34f2d6c8fe2a95217" theme={"theme":{"light":"github-light","dark":"dracula"}}
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>` 标签会被重写路径并哈希

所有路径都以你的 HTML 文件为相对基准进行解析，因此你可以按自己的方式组织项目。

<Warning>
  **This is a work in progress**

  * Need more plugins
  * Need more configuration options for things like asset handling
  * Need a way to configure CORS, headers, etc.

  {/* If you want to submit a PR, most of the code is [here](https://github.com/oven-sh/bun/blob/main/src/runtime/api/bun/html-rewriter.ts). You could even copy paste that file into your project and use it as a starting point. */}

  {/* 如果你想提交 PR，大部分代码在 [这里](https://github.com/oven-sh/bun/blob/main/src/bun.js/api/bun/html-rewriter.ts)。你甚至可以将该文件复制到项目中作为起点。 */}
</Warning>

## 工作原理

这是 Bun 对 JavaScript 中 HTML 导入支持的一个简单封装。

## 单文件独立 HTML

你可以使用 `--compile --target=browser` 将整个前端打包成一个**单个自包含的 `.html` 文件**，无需外部依赖。所有 JavaScript、CSS 和图片都被直接内联到 HTML 中。

```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun build --compile --target=browser ./index.html --outdir=dist
```

了解更多内容请参见[单文件独立 HTML 文档](/bundler/standalone-html)。

## 给前端添加后端

想给前端添加后端支持，可以使用 `Bun.serve` 的“routes”选项。

详见全栈文档。
