一个基于 Islands 架构 的现代多页面应用(MPA),使用 Bun 运行时、Hono Web 框架和 Preact 前端库。项目结合了服务端渲染(SSR)的高性能和客户端部分 hydration 的交互性,提供类似 Next.js App Router 的开发体验。
- 🏝️ Islands 架构 - 仅交互式组件在客户端 hydrate,静态内容保持为 HTML
- 🚀 服务端渲染 - 页面在服务端渲染为完整 HTML,SEO 友好
- 📁 文件系统路由 - 类似 Next.js App Router 的自动路由生成
- 🔌 API 路由支持 - 基于文件系统的 API 端点自动生成
- 🎨 Tailwind CSS v4 - 现代化的原子化 CSS 框架,支持 PostCSS 处理
- ⚡ 快速开发 - Bun 运行时 + 热重载 + TypeScript 类型安全
- 🔧 自动生成 - 脚本自动扫描和注册岛组件、路由、API 端点
- 🌐 端口灵活配置 - 支持环境变量 PORT 配置,默认端口 5000
- 运行时: Bun v1.3.1
- 语言: TypeScript (ESNext)
- 前端: Preact v10.28.2 (轻量级 React)
- 后端: Hono v4.11.4 (Web 框架)
- SSR: preact-render-to-string v6.6.5
- CSS 框架: Tailwind CSS v4.1.18 + PostCSS
- 架构: Islands 架构 (部分 hydration) + 文件系统路由
bun installbun run dev开发服务器默认在 http://localhost:5000 启动。可以通过环境变量 PORT 指定端口:
PORT=3000 bun run dev # 使用端口 3000# 构建客户端代码(包括 CSS、岛组件、路由生成)
bun run build:client
# 启动生产服务器
bun run start生产服务器默认使用端口 5000,同样支持 PORT 环境变量:
PORT=8080 bun run start # 使用端口 8080bun-php/
├── src/
│ ├── app/ # App Router 风格应用目录
│ │ ├── page.tsx # 首页 (路径: /)
│ │ ├── about/ # 关于页面目录
│ │ │ └── page.tsx # 关于页面 (路径: /about)
│ │ ├── users/[id]/ # 动态路由目录
│ │ │ └── page.tsx # 用户详情页 (路径: /users/:id)
│ │ ├── api-test/ # API 测试页面
│ │ │ └── page.tsx # API 测试页面
│ │ ├── api/ # API 路由目录
│ │ │ ├── hello/ # Hello API
│ │ │ │ └── route.ts # GET /api/hello
│ │ │ └── users/ # 用户 API
│ │ │ ├── route.ts # GET /api/users
│ │ │ └── [id]/ # 动态 API 路由
│ │ │ └── route.ts # GET /api/users/:id
│ │ ├── components/ # 共享组件
│ │ │ ├── Layout.tsx # 布局组件
│ │ │ └── Island.tsx # 岛组件包装器
│ │ └── islands/ # 岛组件 (交互式组件)
│ │ ├── Counter.tsx # 示例计数器组件
│ │ ├── forms/ # 表单组件目录
│ │ │ └── Button.tsx # 表单按钮组件
│ │ └── ui/ # UI 组件目录
│ │ └── Button.tsx # UI 按钮组件
│ ├── styles.css # Tailwind CSS 入口文件 (@tailwind 指令)
│ ├── islands.generated.ts # 自动生成的岛组件注册表
│ ├── api.generated.ts # 自动生成的 API 路由注册表
│ ├── routes.generated.ts # 自动生成的文件路由配置
│ ├── router.config.ts # 路由系统配置文件
│ ├── entry-client.tsx # 客户端 hydration 入口
│ └── server.tsx # 服务端入口 (Hono 服务器)
├── scripts/ # 构建和生成脚本
│ ├── generate-islands.ts # 岛组件自动生成脚本
│ ├── generate-routes.ts # 文件路由自动生成脚本
│ ├── generate-api-routes.ts # API 路由自动生成脚本
│ ├── build-css.js # Tailwind CSS 构建脚本
│ ├── build-dev-reload.js # 开发环境自动刷新脚本
│ ├── clean-port.js # 端口清理脚本
│ ├── smart-restart.js # 智能重启脚本
│ └── shared-config.js # 共享配置模块 (端口配置)
├── dist/ # 构建输出目录
│ ├── entry-client.js # 客户端构建产物
│ └── styles.css # 构建后的 Tailwind CSS 文件
├── docs/ # 项目文档
│ ├── islands-architecture-explanation.md # Islands 架构说明
│ ├── tailwind-css-integration.md # Tailwind CSS 集成
│ ├── hot-reload-implementation.md # 热重载实现
│ ├── port-and-git-fix-commands-260124.md # 端口配置与 Git 清理命令
│ └── third-party-integration-guide.md # 第三方工具集成指南
├── package.json # 项目配置和依赖
├── tsconfig.json # TypeScript 配置 (支持 Preact JSX)
├── tailwind.config.js # Tailwind CSS 配置
├── postcss.config.js # PostCSS 配置 (包含 @tailwindcss/postcss 插件)
├── production.md # 项目完整文档 (技术规格、架构说明)
└── README.md # 项目说明 (本文件)
在 src/app/ 目录下创建目录和 page.tsx 文件:
// src/app/products/page.tsx
export default function ProductsPage() {
return <h1>产品列表</h1>;
}
// 支持动态路由: src/app/products/[id]/page.tsx
export default function ProductDetailPage({ params }) {
return <h1>产品详情: {params.id}</h1>;
}在 src/app/islands/ 目录下创建 .tsx 文件,使用 PascalCase 命名:
// src/app/islands/ProductCard.tsx
import { useState } from 'preact/hooks';
export default function ProductCard({ productId }) {
const [liked, setLiked] = useState(false);
return (
<div>
<h3>产品 {productId}</h3>
<button onClick={() => setLiked(!liked)}>
{liked ? '已喜欢' : '喜欢'}
</button>
</div>
);
}// 在页面组件中
import Island from '../components/Island';
export default function ProductsPage() {
return (
<div>
<h1>产品列表</h1>
{/* 使用 Island 包装器 */}
<Island
name="product-card" // kebab-case 版本
component="ProductCard"
props={{ productId: 123 }}
/>
</div>
);
}在 src/app/api/ 目录下创建 route.ts 文件:
// src/app/api/products/route.ts
import type { Context } from 'hono';
// 获取产品列表
export const GET = async (c: Context) => {
return c.json({
products: [
{ id: 1, name: '产品A', price: 100 },
{ id: 2, name: '产品B', price: 200 },
],
count: 2,
});
};
// 创建新产品
export const POST = async (c: Context) => {
try {
const body = await c.req.json();
// 简单的验证
if (!body.name || !body.price) {
return c.json({ error: '产品名称和价格是必填项' }, 400);
}
const newProduct = {
id: Date.now(), // 使用时间戳作为简单ID
name: body.name,
price: body.price,
createdAt: new Date().toISOString(),
};
return c.json(
{
message: '产品创建成功',
product: newProduct,
},
201
);
} catch {
return c.json({ error: '无效的JSON数据' }, 400);
}
};在组件中使用 Tailwind 类名:
export default function HomePage() {
return (
<div className="container mx-auto p-4">
<h1 className="text-3xl font-bold text-blue-600">欢迎</h1>
<p className="text-gray-600 mt-2">这是一个使用 Tailwind CSS 的页面</p>
</div>
);
}| 命令 | 描述 |
|---|---|
bun run dev |
启动开发服务器 (热重载 + 自动生成) |
bun run generate:islands |
生成岛组件注册表 |
bun run generate:routes |
生成文件路由配置 |
bun run generate:api-routes |
生成 API 路由配置 |
bun run build:css |
构建 Tailwind CSS 文件 |
bun run build:client |
构建客户端代码 (包括所有生成步骤) |
bun run build |
构建整个项目 (build:client 的别名) |
bun run start |
启动生产服务器 |
bun run lint |
运行 ESLint 代码检查 |
bun run lint:fix |
运行 ESLint 自动修复 |
bun run format |
运行 Prettier 代码格式化 |
bun run format:check |
检查代码格式化 |
bun run check |
运行完整代码检查 (lint + format:check) |
- 服务端渲染 - 页面在服务端使用 Preact 渲染为完整 HTML
- 组件标记 - 交互式组件被标记为
data-island属性 - 部分 hydration - 客户端仅加载和 hydrate 这些岛组件
- 静态内容 - 非交互部分保持为纯 HTML,无需 JavaScript 开销
项目实现了类似 Next.js App Router 的路由系统:
- 自动路由生成 - 扫描
src/app/目录,自动生成路由配置 - 动态路由支持 - 使用
[param]目录命名约定,自动转换为:param路由参数 - 布局系统 - 支持
layout.tsx文件,自动嵌套布局组件 - API 路由 -
src/app/api/目录下的route.ts文件自动注册为 API 端点
- 岛组件注册 - 自动扫描
src/app/islands/目录,生成组件注册表 - 路由配置 - 自动扫描
src/app/目录,生成路由配置和类型定义 - API 路由注册 - 自动扫描
src/app/api/目录,生成 API 路由配置
项目使用现代 TypeScript 配置,支持:
- Preact JSX (
jsxImportSource: "preact") - ESNext 模块
- 严格类型检查
- 自动类型导入
- 内置打包器和压缩
- 热重载支持
- 快速的 TypeScript 编译
- Tailwind CSS v4.1.18 支持
- PostCSS 处理,包含
@tailwindcss/postcss插件 - 自定义配置文件:
tailwind.config.js - CSS 入口文件:
src/styles.css
项目使用统一的端口配置系统:
# 开发环境
PORT=3000 bun run dev
# 生产环境
PORT=8080 bun run start
# 默认端口: 5000 (未设置 PORT 环境变量时)配置通过 scripts/shared-config.js 统一管理,所有相关脚本自动使用相同端口。
- Fork 项目
- 创建功能分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'Add amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 打开 Pull Request
本项目基于 MIT 许可证 - 查看 LICENSE 文件了解详情。
- Bun - 快速的 JavaScript 运行时,引擎
- Hono - 轻量级 Web 框架,骨架
- Preact - 快速的 React 替代品
- Tailwind CSS - 现代化的 CSS 框架
- Islands Architecture - 架构灵感
提示: 查看 production.md 获取项目完整技术文档和架构说明。