使用 Bun.serve()
的 routes
选项,您可以在同一个应用中运行前端和后端,无需额外步骤。
要开始使用,导入 HTML 文件并将它们传递给 Bun.serve()
中的 routes
选项。
import { sql, serve } from "bun";
import dashboard from "./dashboard.html";
import homepage from "./index.html";
const server = serve({
routes: {
// ** HTML imports **
// Bundle & route index.html to "/". This uses HTMLRewriter to scan the HTML for `<script>` and `<link>` tags, run's Bun's JavaScript & CSS bundler on them, transpiles any TypeScript, JSX, and TSX, downlevels CSS with Bun's CSS parser and serves the result.
"/": homepage,
// Bundle & route dashboard.html to "/dashboard"
"/dashboard": dashboard,
// ** API endpoints ** (Bun v1.2.3+ required)
"/api/users": {
async GET(req) {
const users = await sql`SELECT * FROM users`;
return Response.json(users);
},
async POST(req) {
const { name, email } = await req.json();
const [user] =
await sql`INSERT INTO users (name, email) VALUES (${name}, ${email})`;
return Response.json(user);
},
},
"/api/users/:id": async req => {
const { id } = req.params;
const [user] = await sql`SELECT * FROM users WHERE id = ${id}`;
return Response.json(user);
},
},
// Enable development mode for:
// - Detailed error messages
// - Hot reloading (Bun v1.2.3+ required)
development: true,
// Prior to v1.2.3, the `fetch` option was used to handle all API requests. It is now optional.
// async fetch(req) {
// // Return 404 for unmatched routes
// return new Response("Not Found", { status: 404 });
// },
});
console.log(`Listening on ${server.url}`);
bun run app.ts
HTML 导入即路由
Web 应用始于 HTML,Bun 的全栈开发服务器也是如此。
要指定前端的入口点,请将 HTML 文件导入到您的 JavaScript/TypeScript/TSX/JSX 文件中。
import dashboard from "./dashboard.html";
import homepage from "./index.html";
这些 HTML 文件在 Bun 的开发服务器中用作路由,您可以将它们传递给 Bun.serve()
。
Bun.serve({
routes: {
"/": homepage,
"/dashboard": dashboard,
}
fetch(req) {
// ... api requests
},
});
当您向 /dashboard
或 /
发出请求时,Bun 会自动捆绑 HTML 文件中的 <script>
和 <link>
标签,将它们公开为静态路由,并提供结果。
像这样的 index.html 文件
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
<link rel="stylesheet" href="./reset.css" />
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<div id="root"></div>
<script type="module" src="./sentry-and-preloads.ts"></script>
<script type="module" src="./my-app.tsx"></script>
</body>
</html>
变成这样
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
<link rel="stylesheet" href="/index-[hash].css" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/index-[hash].js"></script>
</body>
</html>
如何与 React 一起使用
要在客户端代码中使用 React,请导入 react-dom/client
并渲染您的应用。
import dashboard from "../public/dashboard.html";
import { serve } from "bun";
serve({
routes: {
"/": dashboard,
},
async fetch(req) {
// ...api requests
return new Response("hello world");
},
});
import "./styles.css";
import { createRoot } from "react-dom/client";
import { App } from "./app.tsx";
document.addEventListener("DOMContentLoaded", () => {
const root = createRoot(document.getElementById("root"));
root.render(<App />);
});
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="../src/frontend.tsx"></script>
</body>
</html>
body {
background-color: red;
}
export function App() {
return <div>Hello World</div>;
}
开发模式
在本地构建时,通过在 Bun.serve()
中设置 development: true
来启用开发模式。
import homepage from "./index.html";
import dashboard from "./dashboard.html";
Bun.serve({
routes: {
"/": homepage,
"/dashboard": dashboard,
}
development: true,
fetch(req) {
// ... api requests
},
});
当 development
为 true
时,Bun 将会
- 在响应中包含
SourceMap
标头,以便开发工具可以显示原始源代码 - 禁用代码压缩
- 在每次请求 .html 文件时重新打包资源
生产模式
在生产环境中部署您的应用程序时,在 Bun.serve()
中设置 development: false
。
- 启用捆绑资源的内存缓存。Bun 将在首次请求
.html
文件时延迟捆绑资源,并将结果缓存在内存中,直到服务器重启。 - 启用
Cache-Control
标头和ETag
标头 - 压缩 JavaScript/TypeScript/TSX/JSX 文件
插件
Bun 的 打包器插件 在捆绑静态路由时也受支持。
要为 Bun.serve
配置插件,请在您的 bunfig.toml
的 [serve.static]
部分添加一个 plugins
数组。
在 HTML 路由中使用 TailwindCSS
例如,通过安装并添加 bun-plugin-tailwind
插件,在您的路由上启用 TailwindCSS
bun add bun-plugin-tailwind
[serve.static]
plugins = ["bun-plugin-tailwind"]
这将允许您在 HTML 和 CSS 文件中使用 TailwindCSS 实用程序类。您只需在某处导入 tailwindcss
即可
<!doctype html>
<html>
<head>
<title>Home</title>
<link rel="stylesheet" href="tailwindcss" />
</head>
<body>
<!-- the rest of your HTML... -->
</body>
</html>