01
ShipNowKit 项目架构与核心功能详解
概述
ShipNowKit 是一个基于 Next.js 16 和 React 19 构建的现代化 SaaS 应用程序脚手架。本指南解析项目的整体架构、核心功能模块以及技术实现细节。
1. 项目技术栈
1.1 前端技术栈
- Next.js 16: App Router 架构
- React 19
- TypeScript: 提供类型安全和更好的开发体验
- TailwindCSS v4: 实用程序优先的 CSS 框架
- shadcn/ui: 基于 Radix UI 的现代组件库
- Framer Motion: 流畅的动画库
1.2 后端技术栈
- Better Auth: 下一代身份验证解决方案
- Prisma ORM: 现代数据库工具包,支持多种数据库
- Server Actions: Next.js 服务端动作,简化数据处理
- Winston: 企业级日志系统
1.3 数据库支持
- SQLite (开发默认)
- PostgreSQL
- MySQL
- MongoDB
1.4 支付系统
- Stripe: 完整的支付处理平台
- Paddle: 替代支付提供商
- 统一的支付接口设计
1.5 其他服务
- React Email: 邮件模板系统
- Resend: 邮件递送服务
- next-intl: 国际化支持
- Vercel Analytics: 网站分析
2. 项目目录结构
shipnow-boilerplate/
├── app/ # Next.js App Router 应用目录
│ ├── [locale]/ # 国际化路由
│ │ ├── docs/ # 文档页面
│ │ ├── page.tsx # 首页
│ │ ├── signin/ # 登录页面
│ │ ├── register/ # 注册页面
│ │ ├── payment/ # 支付相关页面
│ │ └── policies/ # 政策页面
│ ├── api/ # API 路由
│ │ ├── auth/ # 认证 API
│ │ ├── payment/ # 支付 API
│ │ └── search/ # 搜索 API
│ ├── _templates/ # 模板系统
│ │ ├── T1/ # 模板 T1
│ │ └── T2/ # 模板 T2
│ └── layout.tsx # 根布局
├── components/ # React 组件
│ ├── auth/ # 认证组件
│ ├── payment/ # 支付组件
│ ├── ui/ # shadcn/ui 基础组件
│ ├── feature/ # 功能组件
│ ├── header/ # 头部组件
│ ├── footer/ # 底部组件
│ └── hero/ # 英雄区组件
├── config/ # 配置文件
│ ├── site.ts # 站点配置
│ ├── index.ts # 主配置
│ ├── languages.ts # 语言配置
│ └── types.ts # 类型定义
├── lib/ # 工具库
│ ├── actions/ # Server Actions
│ ├── payment/ # 支付工具
│ ├── auth-client.ts # 认证客户端
│ ├── logger.ts # 日志工具
│ └── utils.ts # 通用工具
├── db/ # 数据库
│ ├── prisma/ # Prisma 配置
│ ├── services/ # 数据库服务
│ ├── client.ts # 数据库客户端
│ └── types.ts # 数据库类型
├── content/ # 内容管理
│ └── docs/ # 文档内容
├── messages/ # 国际化消息
│ ├── en.json # 英文消息
│ └── zh.json # 中文消息
├── public/ # 静态资源
├── styles/ # 样式文件
└── providers/ # React 提供者3. 核心功能模块
3.1 认证系统
ShipNowKit 采用 Better Auth 作为认证解决方案,提供以下功能:
3.1.1 多种认证方式
- OAuth 提供商: Google, GitHub, Apple, Discord, Facebook, LinkedIn, Slack, Twitter
- 邮箱密码认证: 传统的用户名密码登录
- 魔法链接: 无密码邮箱登录
3.1.2 客户端使用
import { useSession, signIn, signOut } from "@/lib/auth-client";
export function Protected({ children }: { children: React.ReactNode }) {
const { data, status } = useSession();
if (status === "loading") return null;
if (!data) return <button onClick={() => signIn("google")}>登录</button>;
return <>{children}</>;
}3.1.3 会话管理
- JWT 令牌策略
- 安全的 Cookie 配置
- 自动会话刷新
- 跨域 SSO 支持
3.2 支付系统
3.2.1 结账流程
使用 useCheckout 钩子进行 Stripe/Paddle 结账。Stripe 通过 lib/payment/stripe/server.ts 的服务端动作发起,Paddle 使用 app/[locale]/payment/paddle/checkout/[priceId]/page.tsx 页面。
3.2.2 Stripe 集成
- 订阅管理
- 一次性支付
- 客户门户
- Webhook 处理
3.2.3 Paddle 集成
- 替代支付方案
- 全球税务处理
- 多币种支持
3.3 数据库架构
3.3.1 Prisma 模型设计
model User {
id String @id @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// 关联关系
sessions Session[]
subscriptions Subscription[]
payments OneTimePayment[]
}
model Subscription {
id String @id @default(cuid())
userId String
stripeCustomerId String?
paddleCustomerId String?
status SubscriptionStatus
currentPeriodEnd DateTime?
user User @relation(fields: [userId], references: [id])
}3.3.2 数据库服务层
// 用户服务示例
export async function createUser(data: CreateUserData) {
return await prisma.user.create({
data: {
email: data.email,
name: data.name,
// 其他字段
},
});
}3.4 国际化系统
3.4.1 多语言支持
- 基于 next-intl 实现
- 支持中文和英文
- 动态语言切换
- 本地化路由
3.4.2 消息管理
// messages/zh.json
{
"auth": {
"signin": "登录",
"signup": "注册",
"signout": "退出"
},
"payment": {
"subscribe": "订阅",
"cancel": "取消订阅"
}
}3.5 模板系统
3.5.1 多模板架构
ShipNowKit 提供两套完整的模板:
- ShipNowLike: 现代简洁风格
- NotionLike: Notion 风格设计
3.5.2 模板切换
npm run template:t1
npm run template:t24. 核心组件详解
4.1 认证组件
4.1.1 SignInButton 组件
export function SignInButton({ provider }: { provider: string }) {
const handleSignIn = async () => {
await signIn(provider);
};
return (
<button onClick={handleSignIn}>
使用 {provider} 登录
</button>
);
}4.1.2 保护路由组件
export function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { data: session, status } = useSession();
if (status === "loading") return <div>加载中...</div>;
if (!session) redirect("/signin");
return <>{children}</>;
}4.2 支付组件
4.2.1 价格卡片组件
export function PriceCard({ plan }: { plan: PricingPlan }) {
const handleSubscribe = async () => {
const session = await createCheckoutSession({
priceId: plan.priceId,
mode: 'subscription',
});
window.location.href = session.url;
};
return (
<div className="price-card">
<h3>{plan.name}</h3>
<p>{plan.price}</p>
<button onClick={handleSubscribe}>订阅</button>
</div>
);
}4.3 UI 组件
4.3.1 主题切换组件
export function ThemeToggle() {
const { theme, setTheme } = useTheme();
return (
<button
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
>
{theme === "dark" ? <Sun /> : <Moon />}
</button>
);
}5. API 路由设计
5.1 认证 API
5.1.1 登录 API
// app/api/auth/signin/route.ts
export async function POST(request: Request) {
const { email, password } = await request.json();
try {
const user = await authenticateUser(email, password);
const session = await createSession(user.id);
return NextResponse.json({ success: true, session });
} catch (error) {
return NextResponse.json({ error: "认证失败" }, { status: 401 });
}
}5.2 支付 API
5.2.1 创建结账会话
// app/api/payment/create-checkout/route.ts
export async function POST(request: Request) {
const { priceId, mode } = await request.json();
const session = await stripe.checkout.sessions.create({
mode,
line_items: [{ price: priceId, quantity: 1 }],
success_url: `${process.env.NEXT_PUBLIC_URL}/payment/success`,
cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
});
return NextResponse.json({ url: session.url });
}5.3 Webhook 处理
5.3.1 Stripe Webhook
// app/api/payment/stripe/webhook/route.ts
export async function POST(request: Request) {
const body = await request.text();
const signature = request.headers.get('stripe-signature')!;
try {
const event = stripe.webhooks.constructEvent(
body,
signature,
process.env.STRIPE_WEBHOOK_SECRET!
);
await handleStripeEvent(event);
return NextResponse.json({ received: true });
} catch (error) {
return NextResponse.json({ error: "Webhook 处理失败" }, { status: 400 });
}
}6. 配置管理
6.1 环境变量配置
# 数据库
DATABASE_URL="sqlite:./dev.db"
# 身份验证
BETTER_AUTH_SECRET="your-secret-key"
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"
# 支付
STRIPE_PUBLISHABLE_KEY="pk_test_..."
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
# 邮件
RESEND_API_KEY="re_..."6.2 站点配置
// config/site.ts
export const siteConfig = {
name: "ShipNowKit",
description: "现代化 SaaS 应用程序脚手架",
url: "https://shipnowkit.com",
ogImage: "https://shipnowkit.com/og.jpg",
links: {
twitter: "https://twitter.com/shipnowkit",
github: "https://github.com/shipnowkit",
},
};7. 开发工具与脚本
7.1 数据库管理脚本
{
"scripts": {
"db:generate": "prisma generate",
"db:studio": "prisma studio",
"db:migrate": "prisma migrate dev",
"db:use:mysql": "node scripts/switch-database.js mysql",
"db:use:postgresql": "node scripts/switch-database.js postgresql"
}
}7.2 开发服务器
# 启动开发服务器
npm run dev
# 构建生产版本
npm run build
# 启动生产服务器
npm start8. 最佳实践
8.1 代码组织
- 组件分层: 按功能模块组织组件
- 类型安全: 充分利用 TypeScript 类型系统
- 错误处理: 统一的错误处理机制
- 日志记录: 使用 Winston 进行结构化日志
8.2 性能优化
- 服务器组件: 优先使用 React 服务器组件
- 代码分割: 按路由自动分割代码
- 图片优化: 使用 Next.js Image 组件
- 缓存策略: 合理使用缓存机制
8.3 安全考虑
- 环境变量: 敏感信息使用环境变量
- CSRF 保护: 内置 CSRF 保护机制
- 输入验证: 使用 Zod 进行数据验证
- 会话安全: 安全的会话管理
总结
ShipNowKit 提供了一个完整、现代化的 SaaS 应用程序开发框架。通过模块化的架构设计、统一的接口规范和丰富的功能组件,开发者可以快速构建高质量的 SaaS 应用程序。
下一篇指南将详细介绍认证系统的深度配置与最佳实践。