Skip to content

winnerwbx/json-formatter

Repository files navigation

projects

这是一个基于 Next.js 16 + shadcn/ui 的全栈应用项目,由扣子编程 CLI 创建。

快速开始

启动开发服务器

pnpm dev

默认在端口 5000 启动。可通过环境变量覆盖端口:

PORT=5173 pnpm dev

启动后,在浏览器中打开对应地址(如 http://localhost:5000http://localhost:5173)查看应用。

开发服务器支持热更新,修改代码后页面会自动刷新。

构建生产版本

pnpm build

启动生产服务器

pnpm start

默认端口为 5000,可通过环境变量覆盖:

DEPLOY_RUN_PORT=8080 pnpm start

运行与部署指南

依赖与环境

  • Node.js 20+(工作流使用 Node 24,建议本地 18+)
  • pnpm 9+
  • 浏览器现代版本

安装依赖

pnpm install

本地开发

  • 启动:pnpm dev
  • 端口:默认 5000,可用 PORT=<port> 覆盖(脚本见 scripts/dev.sh)
  • 常用示例:PORT=5173 pnpm dev

构建静态产物(Next.js 静态导出)

  • 执行:pnpm build
  • 产物目录:./out
  • 预览静态产物:
    npx serve ./out -p 8080
    # 打开 http://localhost:8080
  • 配置参考:next.config.ts
    • output: "export"
    • images.unoptimized: true
    • 生产环境 assetPrefix: "./" 适配 GitHub Pages 子路径

使用 GitHub Pages 自动部署(推荐)

  1. 确认工作流文件已存在:.github/workflows/deploy.yml
    • 触发:推送到 main 或手动 workflow_dispatch
    • 构建:pnpm build,上传 ./out 作为 Pages Artifact
  2. 推送代码到 GitHub 仓库的 main 分支
  3. 打开仓库 Settings → Pages → Source 选择 “GitHub Actions”
  4. 等待 Actions 完成,发布地址显示在 Pages 环境(如 https://<用户名>.github.io/<仓库名>/

手动部署(备选)

  • 本地执行 pnpm build 生成 ./out
  • 使用任意静态服务器托管 out(Nginx、Apache、Vercel 静态、Cloudflare Pages、Netlify 等)
  • 不建议将 out/ 目录提交到 main 分支(已在 .gitignore 忽略)

提交与忽略

  • 需要提交:
    • 源码与配置:src/public/scripts/next.config.tspackage.jsonpnpm-lock.yamltsconfig.json
    • 工作流:.github/workflows/deploy.yml
    • 文档:README.mdLICENSE(如有)
  • 不需要提交(已忽略):
    • node_modules/.next/out/coverage/
    • .DS_Store.env*(敏感信息)
    • 详见 .gitignore

静态导出注意事项

  • 静态导出生成 out/,可部署到任何静态主机
  • 不支持需 Node.js 服务器的特性:
    • API Routes、Rewrites/Redirects、Headers、Proxy
    • Incremental Static Regeneration(ISR)、Draft Mode
    • 默认 next/image 优化(需自定义 Loader)
    • getServerSidePropsgetStaticPathsfallback: true/'blocking'
  • 可用特性(静态场景):
    • getStaticPropsgetStaticPaths(无 fallback
    • 动态路由的静态生成、next/link 预取、动态导入、任意样式方案

故障排查

  • 构建错误:robots.txt 需静态化
    • 已在 robots.ts 设置 export const dynamic = 'force-static'
  • 子路径资源 404:生产已设置 assetPrefix: "./",确保通过 Actions 发布
  • 开发端口占用:使用 PORT=<port> pnpm dev 指定新端口
  • 生产端口修改:使用 DEPLOY_RUN_PORT=<port> pnpm 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(可选)

核心开发规范

1. 组件开发

优先使用 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/ 目录下的具体组件实现。

2. 路由开发

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 });
}

3. 依赖管理

必须使用 pnpm 管理依赖

# ✅ 安装依赖
pnpm install

# ✅ 添加新依赖
pnpm add package-name

# ✅ 添加开发依赖
pnpm add -D package-name

# ❌ 禁止使用 npm 或 yarn
# npm install  # 错误!
# yarn add     # 错误!

项目已配置 preinstall 脚本,使用其他包管理器会报错。

4. 样式开发

使用 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

5. 表单开发

推荐使用 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>
  );
}

6. 数据获取

服务端组件(推荐)

// 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>;
}

常见开发场景

添加新页面

  1. src/app/ 下创建文件夹和 page.tsx
  2. 使用 shadcn 组件构建 UI
  3. 根据需要添加 layout.tsxloading.tsx

创建业务组件

  1. src/components/ 下创建组件文件(非 UI 组件)
  2. 优先组合使用 src/components/ui/ 中的基础组件
  3. 使用 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

参考文档

重要提示

  1. 必须使用 pnpm 作为包管理器
  2. 优先使用 shadcn/ui 组件 而不是从零开发基础组件
  3. 遵循 Next.js App Router 规范,正确区分服务端/客户端组件
  4. 使用 TypeScript 进行类型安全开发
  5. 使用 @/ 路径别名 导入模块(已配置)

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages