.html 文件,无需任何外部依赖。JavaScript、TypeScript、JSX、CSS、图片、字体、视频、WASM —— 所有内容均内联到一个文件中。
terminal
.html 文件,可以在任何浏览器中打开。
单文件。随处上传。
输出是一个单独的.html 文件,你可以放到任何地方:
- 上传到 S3 或任何静态文件托管服务 — 无需维护目录结构,只有一个文件
- 从桌面双击打开 — 在浏览器中打开并且可离线工作,不需要 localhost 服务器
- 嵌入到你的 webview 中 — 不用处理相对文件
- 插入到
<iframe>中 — 使用单个文件 URL 在另一个页面中嵌入交互内容 - 从任何地方提供服务 — 任何 HTTP 服务器、CDN 或文件共享。一个文件,零配置。
node_modules,不用管理构建产物,也无需考虑相对路径。整个应用 —— 框架代码、样式表、图片等等 —— 都在这唯一的文件中。
真正的单文件
通常,发布网页意味着管理一个资产文件夹 —— HTML、JavaScript 包、CSS 文件、图片。只移动 HTML 文件,没了其他内容就会坏掉。浏览器以前试图解决这个问题:Safari 的.webarchive 和 .mhtml 旨在将页面保存为单文件,但实际上它们会在电脑上解包成一堆松散文件 —— 违背了初衷。
独立 HTML 不同。输出是一个普通的 .html 文件。不是归档文件,也不是文件夹。一个文件,内装所有内容。每张图片、每个字体、每行 CSS 和 JavaScript 都通过标准的 <style> 标签、<script> 标签和 data: URI 直接嵌入 HTML。任何浏览器都能打开。任何服务器都能托管。任何文件托管都能存储。
这使得发布网页就像发布 PDF 一样方便 —— 单个文件,你可以随意移动、复制、上传或分享,无需担心路径断裂或资产丢失。
快速开始
terminal
dist/index.html —— React 应用无需服务器即可运行。
所有内容均内联
Bun 会内联你 HTML 中找到的所有本地资源。如果是相对路径,则嵌入到输出文件中。这不仅限于图片和样式表 —— 适用于任何文件类型。什么内容会被内联
| 你的源码 | 输出内容 |
|---|---|
<script src="./app.tsx"> | <script type="module">...打包后的代码...</script> |
<link rel="stylesheet" href="./styles.css"> | <style>...打包后的 CSS...</style> |
<img src="./logo.png"> | <img src="data:image/png;base64,..."> |
<img src="./icon.svg"> | <img src="data:image/svg+xml;base64,..."> |
<video src="./demo.mp4"> | <video src="data:video/mp4;base64,..."> |
<audio src="./click.wav"> | <audio src="data:audio/wav;base64,..."> |
<source src="./clip.webm"> | <source src="data:video/webm;base64,..."> |
<video poster="./thumb.jpg"> | <video poster="data:image/jpeg;base64,..."> |
<link rel="icon" href="./favicon.ico"> | <link rel="icon" href="data:image/x-icon;base64,..."> |
<link rel="manifest" href="./app.webmanifest"> | <link rel="manifest" href="data:application/manifest+json;base64,..."> |
CSS 中的 url("./bg.png") | CSS 中的 url(data:image/png;base64,...) |
CSS 中的 @import "./reset.css" | 合并到 <style> 标签中 |
CSS 中的 url("./font.woff2") | CSS 中的 url(data:font/woff2;base64,...) |
JS 中的 import "./styles.css" | 合并到 <style> 标签中 |
data: URI,直接嵌入 HTML。MIME 类型会根据文件扩展名自动检测。
外部 URL(如 CDN 链接或绝对链接)保持不变,不会被内联。
与 React 一起使用
React 应用开箱即用。Bun 会自动处理 JSX 转译和 npm 包解析。terminal
terminal
dist/index.html。把这唯一文件上传到任何地方即可运行。
与 Tailwind CSS 一起使用
安装插件并在 HTML 或 CSS 中引用 Tailwind:terminal
terminal
<style> 标签的形式注入 HTML 文件。
工作原理
当你传入--compile --target=browser 且入口是 HTML 文件时,Bun 会:
- 解析 HTML,发现所有
<script>、<link>、<img>、<video>、<audio>、<source>及其他资源引用 - 将所有 JavaScript/TypeScript/JSX 打包为单个模块
- 将所有 CSS(包括
@import链和 JS 中导入的 CSS)打包成一个样式表 - 将所有相对资源引用转换为 base64 的
data:URI - 将打包后的 JS 以内联
<script type="module">形式放在</body>前 - 将打包后的 CSS 以内联
<style>形式放在<head>内 - 输出一个不依赖任何外部文件的单个
.html文件
压缩
添加--minify 来压缩 JavaScript 和 CSS:
terminal
JavaScript API
你可以使用Bun.build() 以编程方式生成独立 HTML:
outdir,输出可以作为 BuildArtifact 从 result.outputs 获取:
多个 HTML 文件
你可以传入多个 HTML 文件作为入口,分别生成独立 HTML 文件:terminal
环境变量
使用--env 将环境变量内联到打包的 JavaScript 中:
terminal
process.env.API_URL 的引用会在构建时被替换为对应的字面量值。
限制
- 不支持代码拆分 ——
--splitting不能与--compile --target=browser一起使用 - 大文件资产 由于 base64 编码,体积会变大(比原二进制大33%)
- 外部 URL(CDN 链接、绝对 URL)保持不变,只有相对路径资源会被内联