这是一个基于 Next.js 16 + shadcn/ui 的全栈应用项目,由扣子编程 CLI 创建。
coze dev
启动后,在浏览器中打开 http://localhost:5000 查看应用。
开发服务器支持热更新,修改代码后页面会自动刷新。
coze build
coze start
src/
├── app/ # Next.js App Router 目录
│ ├── layout.tsx # 根布局组件
│ ├── page.tsx # 首页
│ ├── globals.css # 全局样式(包含 shadcn 主题变量)
│ └── [route]/ # 其他路由页面
├── components/ # React 组件目录
│ └── ui/ # shadcn/ui 基础组件(优先使用)
│ ├── button.tsx
│ ├── card.tsx
│ └── ...
├── lib/ # 工具函数库
│ └── utils.ts # cn() 等工具函数
└── hooks/ # 自定义 React Hooks(可选)
server/
├── index.ts # 自定义服务器入口
├── tsconfig.json # Server TypeScript 配置
└── dist/ # 编译输出目录(自动生成)
优先使用 shadcn/ui 基础组件
本项目已预装完整的 shadcn/ui 组件库,位于 src/components/ui/ 目录。开发时应优先使用这些组件作为基础:
// ✅ 推荐:使用 shadcn 基础组件 import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; export default function MyComponent() { return ( <Card> <CardHeader>标题</CardHeader> <CardContent> <Input placeholder="输入内容" /> <Button>提交</Button> </CardContent> </Card> ); }
可用的 shadcn 组件清单
- 表单:
button,input,textarea,select,checkbox,radio-group,switch,slider - 布局:
card,separator,tabs,accordion,collapsible,scroll-area - 反馈:
alert,alert-dialog,dialog,toast,sonner,progress - 导航:
dropdown-menu,menubar,navigation-menu,context-menu - 数据展示:
table,avatar,badge,hover-card,tooltip,popover - 其他:
calendar,command,carousel,resizable,sidebar
详见 src/components/ui/ 目录下的具体组件实现。
Next.js 使用文件系统路由,在 src/app/ 目录下创建文件夹即可添加路由:
# 创建新路由 /about src/app/about/page.tsx # 创建动态路由 /posts/[id] src/app/posts/[id]/page.tsx # 创建路由组(不影响 URL) src/app/(marketing)/about/page.tsx # 创建 API 路由 src/app/api/users/route.ts
页面组件示例
// src/app/about/page.tsx import { Button } from '@/components/ui/button'; export const metadata = { title: '关于我们', description: '关于页面描述', }; export default function AboutPage() { return ( <div> <h1>关于我们</h1> <Button>了解更多</Button> </div> ); }
动态路由示例
// src/app/posts/[id]/page.tsx export default async function PostPage({ params, }: { params: Promise<{ id: string }>; }) { const { id } = await params; return <div>文章 ID: {id}</div>; }
API 路由示例
// src/app/api/users/route.ts import { NextResponse } from 'next/server'; export async function GET() { return NextResponse.json({ users: [] }); } export async function POST(request: Request) { const body = await request.json(); return NextResponse.json({ success: true }); }
必须使用 pnpm 管理依赖
# ✅ 安装依赖 pnpm install # ✅ 添加新依赖 pnpm add package-name # ✅ 添加开发依赖 pnpm add -D package-name # ❌ 禁止使用 npm 或 yarn # npm install # 错误! # yarn add # 错误!
项目已配置 preinstall 脚本,使用其他包管理器会报错。
使用 Tailwind CSS v4
本项目使用 Tailwind CSS v4 进行样式开发,并已配置 shadcn 主题变量。
// 使用 Tailwind 类名 <div className="flex items-center gap-4 p-4 rounded-lg bg-background"> <Button className="bg-primary text-primary-foreground"> 主要按钮 </Button> </div> // 使用 cn() 工具函数合并类名 import { cn } from '@/lib/utils'; <div className={cn( "base-class", condition && "conditional-class", className )}> 内容 </div>
主题变量
主题变量定义在 src/app/globals.css 中,支持亮色/暗色模式:
--background,--foreground--primary,--primary-foreground--secondary,--secondary-foreground--muted,--muted-foreground--accent,--accent-foreground--destructive,--destructive-foreground--border,--input,--ring
推荐使用 react-hook-form + zod 进行表单开发:
import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; const formSchema = z.object({ username: z.string().min(2, '用户名至少 2 个字符'), email: z.string().email('请输入有效的邮箱'), }); export default function MyForm() { const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { username: '', email: '' }, }); const onSubmit = (data: z.infer<typeof formSchema>) => { console.log(data); }; return ( <form onSubmit={form.handleSubmit(onSubmit)}> <Input {...form.register('username')} /> <Input {...form.register('email')} /> <Button type="submit">提交</Button> </form> ); }
服务端组件(推荐)
// src/app/posts/page.tsx async function getPosts() { const res = await fetch('https://api.example.com/posts', { cache: 'no-store', // 或 'force-cache' }); return res.json(); } export default async function PostsPage() { const posts = await getPosts(); return ( <div> {posts.map(post => ( <div key={post.id}>{post.title}</div> ))} </div> ); }
客户端组件
'use client'; import { useEffect, useState } from 'react'; export default function ClientComponent() { const [data, setData] = useState(null); useEffect(() => { fetch('/api/data') .then(res => res.json()) .then(setData); }, []); return <div>{JSON.stringify(data)}</div>; }
- 在
src/app/下创建文件夹和page.tsx - 使用 shadcn 组件构建 UI
- 根据需要添加
layout.tsx和loading.tsx
- 在
src/components/下创建组件文件(非 UI 组件) - 优先组合使用
src/components/ui/中的基础组件 - 使用 TypeScript 定义 Props 类型
推荐使用 React Context 或 Zustand:
// src/lib/store.ts import { create } from 'zustand'; interface Store { count: number; increment: () => void; } export const useStore = create<Store>((set) => ({ count: 0, increment: () => set((state) => ({ count: state.count + 1 })), }));
推荐使用 Prisma 或 Drizzle ORM,在 src/lib/db.ts 中配置。
- 框架: Next.js 16.1.1 (App Router)
- UI 组件: shadcn/ui (基于 Radix UI)
- 样式: Tailwind CSS v4
- 表单: React Hook Form + Zod
- 图标: Lucide React
- 字体: Geist Sans & Geist Mono
- 包管理器: pnpm 9+
- TypeScript: 5.x
- 必须使用 pnpm 作为包管理器
- 优先使用 shadcn/ui 组件 而不是从零开发基础组件
- 遵循 Next.js App Router 规范,正确区分服务端/客户端组件
- 使用 TypeScript 进行类型安全开发
- 使用
@/路径别名 导入模块(已配置)