创建项目
要点
- create-turbo 负责的是仓库级能力:workspace、turbo.json、根级脚本,以及 Turborepo 的任务编排方式
- 最初的项目设计中,至少包含 web、admin、api 三个真正要继续开发的子应用,其中 web 和 admin 已经准备好了
- 最容易遇到的第一个小问题是端口冲突
- 第一次验证,建议分开开三个终端,这样最清楚
内容
1. 概述
我们先把三个应用的骨架搭起来,后面再慢慢添加功能,最基础的全栈应用通常包括:
- web:用户端站点
- admin:管理后台
- api:独立 API 服务
做法也很直接:先用 create-turbo 把 monorepo 框架搭建出来,再把三个子应用都放进 apps/ 中去。
这样一开始就把「多应用」「共享代码」「统一任务入口」放进同一个仓库里,后面继续扩展功能时就会非常自然。
2. create-turbo
create-turbo 负责的是仓库级能力:workspace、turbo.json、根级脚本,以及 Turborepo 的任务编排方式。它解决的是「这个多应用仓库怎么协同」,不是「你的业务应用默认长什么样」。
pnpm create turbo@latest ai-agent --package-manager pnpm
cd ai-agent当前默认脚手架通常会先给你一套可运行的示例内容,但具体有哪些目录,可能会随版本变化。第一次创建以后,先执行完脚手架,再打开 apps/ 和 packages/ 看一眼当前生成结果。
执行如下指令,把 react next 升级到最新,并更新 pnpm-lock.yaml:
pnpm up -r next react react-dom @types/react @types/react-dom --latest然后把 docs 文件夹修改为 admin,并修改 docs 文件夹中的 package.json 文件,将 name 修改为 admin:
// docs/package.json (renamed to admin)
{
"name": "admin",
"version": "0.1.0",
"private": true
}接下来,我们可以通过 catalog 来统一所有子站的依赖版本。检查 pnpm 版本是否是最新的,需要 pnpm@10 以上:
# 启用 Node 自带的包管理器代理
corepack enable
# 下载最新 pnpm,并把当前项目的 packageManager 改成最新版本
corepack use pnpm@latest
# 查看 pnpm 版本
pnpm -v然后对多个子站中使用的 React 等依赖包进行统一管理。可以手动修改 pnpm-workspace.yaml:
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
+ catalog:
+ next: 16.2.4
+ react: ^19.2.5
+ react-dom: ^19.2.5
+ "@types/node": ^22.15.3
+ "@types/react": 19.2.14
+ "@types/react-dom": 19.2.3
+ eslint: ^9.39.1
+ typescript: 5.9.2然后在子站和共享包的 package.json 中,通过如下的方式引用依赖:
// apps/web/package.json
{
"dependencies": {
"react": "catalog:"
}
}这样,基础的前端项目就准备好了。
3. 创建 api 这个 Hono 子应用
最初的项目设计中,至少包含 web、admin、api 三个真正要继续开发的子应用,其中 web 和 admin 已经准备好了,api 这里直接用 create-hono 创建:
pnpm create hono apps/api --template cloudflare-workers --pm pnpm创建完以后,先把 apps/api/src/index.ts 改成一个最小健康检查接口:
// apps/api/src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/health', (c) => {
return c.json({ ok: true, service: 'api' })
})
export default app这时候 api 的目标很单纯:先证明「独立服务已经能在 monorepo 里运行」,业务接口后面再继续加。
4. 让三套应用更容易同时运行
最容易遇到的第一个小问题是端口冲突。web 和 admin 都是 Next.js,默认都会占 3000。所以先把 admin 的开发端口改掉:
// apps/admin/package.json
{
"scripts": {
"dev": "next dev --turbopack --port 3006"
}
}改完以后:
- web 默认跑在 3005
- admin 跑在 3006
- api 的 wrangler dev 默认跑在 8787
如果想更方便地单独启动某个应用,可以再补几个过滤脚本:
// package.json
{
"scripts": {
"dev": "turbo run dev",
"dev:web": "turbo run dev --filter=web",
"dev:admin": "turbo run dev --filter=admin",
"dev:api": "turbo run dev --filter=api",
"build": "turbo run build"
}
}--filter 可以把它理解成「只跑某一个 workspace」。比如只想盯着后台开发,就跑 pnpm dev:admin;只想看接口服务,就跑 pnpm dev:api。
5. 跑起来验证一下
第一次验证,建议分开开三个终端,这样最清楚:
# 终端 1
pnpm dev:web
# 终端 2
pnpm dev:admin
# 终端 3
pnpm dev:api预期结果是:
http://localhost:3000打开后看到「web 前台站」http://localhost:3001打开后看到「admin 管理台」http://localhost:8787/health返回 API 的 JSON
可以顺手再测一下接口:
curl http://localhost:8787/health正常返回:
{
"ok": true,
"service": "api"
}到这一步,项目底盘就已经立住了:一个 monorepo 根,三个独立子应用,一套统一的任务入口。
然后执行如下指令,把三个子应用都跑起来:
pnpm dev8. 总结
刚开始就做三件事:
- 用
create-turbo起 monorepo - 用
create-next-app建 web 和 admin - 用
create-hono建 api
项目目录结构(预期)
ai-agent/
├── apps/
│ ├── web/ # Next.js 用户端 (port 3005)
│ ├── admin/ # Next.js 管理后台 (port 3006)
│ └── api/ # Hono + Cloudflare Workers (port 8787)
├── packages/ # 共享包
├── pnpm-workspace.yaml
├── turbo.json
└── package.json