mcpField
N
nextjs-shadcn-builder

nextjs-shadcn-builder

github.com/ovachiever开发56262 次安装48 周前更新
代码仓库

关于 nextjs-shadcn-builder

用于创建 Next.js 应用或将现有前端迁移到 Next.js 和 shadcn/ui 的技能。它将代码分析、组件映射、分批转换和验证组织为流程,并强调设计令牌、响应式布局与无障碍性。

主要功能

  1. 01初始化带 App Router 的 Next.js
  2. 02分析前端代码库与组件
  3. 03规划并分批迁移组件
  4. 04将界面映射到 shadcn/ui 组件
  5. 05验证测试、响应式设计和无障碍性

适用场景

  1. 01启动 Next.js 应用
  2. 02迁移 React 前端
  3. 03转换 Vue 或 Angular 界面
  4. 04迁移期间统一样式

MCP 相关

工作流通过 shadcn MCP 服务查找组件、文档、区块、图表和设计令牌参考,并说明如何检查服务是否可用及在不可用时进行初始化。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ovachiever/droid-tings --skill nextjs-shadcn-builder

安装后在 Claude Code 中输入/nextjs-shadcn-builder确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
assets/
theme-example-oklch.css
assets/component-templates/
complex-form.tsx
example-feature-card.tsx
example-user-profile.tsx
responsive-dashboard.tsx
responsive-data-table.tsx
responsive-navigation.tsx
references/
accessibility-best-practices.md
advanced-shadcn-components.md
react-to-nextjs.md
responsive-design-patterns.md
shadcn-component-mapping.md
styling-migration.md
vue-to-nextjs.md
scripts/
analyze-codebase.py
detect-hardcoded-values.sh
generate-migration-report.py
init-nextjs-shadcn.sh

详细介绍

Next.js + shadcn/ui 构建与迁移工具

构建可用于生产环境的 Next.js 应用,或按照严格的设计原则和最佳实践,将现有前端系统性地迁移到 Next.js + shadcn/ui。

概述

此技能支持两种主要工作流:

  1. 创建新的 Next.js 应用 - 使用 Next.js 15+(App Router)、shadcn/ui 和完善的设计系统配置初始化项目
  2. 迁移现有前端 - 分析任意前端代码库(React、Vue、Angular、原生 JavaScript),并系统性地将其转换为 Next.js + shadcn/ui

核心理念:100% 遵循 shadcn/ui 设计原则:

  • 所有主题设置(颜色、间距、排版)都使用 CSS 变量
  • 仅使用标准 shadcn/ui 组件(不使用自定义 UI 组件)
  • 不使用硬编码值(颜色、间距、字体)
  • 在整个应用中保持设计令牌一致
  • 面向移动设备优先,为所有设备(手机、平板、桌面)提供响应式设计
  • 符合 WCAG 2.1 AA 级无障碍标准
  • 遵循 https://ui.shadcn.com 中的最佳实践

工作流决策树

User Request
    ├─ Creating New Next.js App
    │   └─ Follow "Creating New Application" workflow (Phase 3 onwards)
    │
    └─ Migrating Existing Codebase
        ├─ Phase 1: Codebase Analysis
        ├─ Phase 2: Migration Planning
        ├─ Phase 3: Next.js + shadcn Setup
        ├─ Phase 4: Systematic Conversion
        └─ Phase 5: Verification & Cleanup

迁移高级工作流

阶段 1:代码库分析

自动分析现有前端,以了解范围和复杂程度。

步骤:

  1. 检测框架和版本
  2. 盘点组件并进行分类
  3. 检测硬编码值(颜色、间距、自定义组件)
  4. 分析样式方案(CSS、SCSS、CSS-in-JS、Tailwind 等)
  5. 识别状态管理和路由模式
  6. 生成全面的分析报告

交付内容:

  • 框架分析报告
  • 组件清单(JSON)
  • 硬编码值报告
  • 复杂度评估
阶段 2:迁移规划

制定系统化转换计划,并按优先级分批处理。

步骤:

  1. 将现有组件映射到对应的 shadcn/ui 组件
  2. 确定需要自定义开发的组件
  3. 将转换工作分批组织(每批 5-10 个组件)
  4. 评估每批的风险和复杂程度
  5. 制定详细的迁移计划

交付内容:

  • 组件映射表
  • 分批转换计划
  • 风险评估
  • 各组件的预估复杂度
阶段 3:Next.js + shadcn 配置

在现有代码库旁初始化 Next.js 基础设施,或用其替换现有代码库。

步骤:

  1. 检查并安装 shadcn MCP 服务,以访问文档
  2. 使用 App Router 和 TypeScript 初始化 Next.js 15+
  3. 安装并配置 Tailwind CSS
  4. 运行 shadcn/ui 初始化
  5. 设置 CSS 变量和设计令牌
  6. 配置路径别名(@/)
  7. 安装必要的 shadcn 组件
  8. 创建设计系统文档

交付内容:

  • 配置完成的 Next.js 项目
  • 设计令牌系统(CSS 变量)
  • 组件库配置
  • 已配置路径别名
阶段 4:系统化转换

分批转换组件,并在每批完成后进行测试。

步骤:

  1. 第 1 批:布局与结构(页眉、页脚、布局包装器)
  2. 第 2 批:简单 UI 组件(按钮、卡片、徽章、警告框)
  3. 第 3 批:表单组件(输入框、选择框、复选框、表单)
  4. 第 4 批:复杂组件(表格、对话框、命令菜单、数据可视化)
  5. 第 5 批:样式标准化(移除硬编码值,应用 CSS 变量)
  6. 第 6 批:页面与路由(转换页面,设置 Next.js 路由)

每批工作流:

  1. 选择 5-10 个相关组件
  2. 使用 MCP 查找合适的 shadcn 组件
  3. 按照 shadcn 模式转换组件
  4. 将硬编码值替换为 CSS 变量
  5. 测试功能
  6. 检查视觉一致性
  7. 继续下一批

交付内容:

  • 已迁移的组件(逐批完成)
  • 使用 CSS 变量更新的样式
  • Next.js App Router 页面
  • 每批均通过测试
阶段 5:验证与清理

最终测试、优化并移除旧代码。

步骤:

  1. 运行完整测试套件
  2. 视觉回归测试
  3. 响应式设计测试(移动设备、平板电脑、桌面设备)
  4. 性能审查
  5. 无障碍审查(符合 WCAG 2.1 AA 级标准)
  6. 移除旧框架代码
  7. 更新文档
  8. 生成完成报告

交付物:

  • 测试结果
  • 响应式设计验证报告
  • 性能指标
  • 无障碍审查报告(WCAG 2.1 AA)
  • 整洁的代码库
  • 迁移摘要

阶段 1:代码库分析(详细说明)

1.1 框架检测

运行自动化分析脚本:

python ./scripts/analyze-codebase.py /path/to/existing/codebase

此脚本将:

  • 检测框架(React、Vue、Angular、Svelte、vanilla JS 等)
  • 识别框架版本
  • 检测构建工具(Vite、Webpack、Parcel 等)
  • 查找 package.json 依赖项
  • 映射目录结构

输出: 包含框架元数据的 codebase-analysis.json

1.2 组件清单

分析脚本会自动生成组件清单,包括:

  • 组件名称和文件路径
  • 组件类型(函数式、类、Vue SFC 等)
  • Props/输入
  • 状态用法
  • 子组件
  • 外部依赖项

输出: component-inventory.json

结构示例:

{
  "components": [
    {
      "name": "UserCard",
      "path": "src/components/UserCard.tsx",
      "type": "functional",
      "complexity": "simple",
      "shadcn_equivalent": "Card",
      "hardcoded_values": ["#3b82f6", "16px padding"],
      "dependencies": ["react", "styled-components"]
    }
  ]
}
1.3 硬编码值检测

运行检测脚本:

bash ./scripts/detect-hardcoded-values.sh /path/to/existing/codebase

此脚本可检测:

  • 硬编码颜色:#hex、rgb()、rgba()、hsl()、颜色名称
  • 内联间距:margin: 20px、padding: 1rem
  • 自定义字体声明:非标准字体
  • 魔法数字:组件中的任意值
  • 内联样式:style={{...}}
  • 非标准模式:应使用 Tailwind 的 CSS-in-JS、styled-components

输出: 按类别归纳违规项的 hardcoded-values-report.md

1.4 生成分析报告

运行报告生成器:

python ./scripts/generate-migration-report.py

此操作会将所有分析数据整合为一份完整的 Markdown 报告:

输出: migration-analysis-report.md

# Frontend Migration Analysis Report

## Executive Summary
[One-paragraph overview: framework, size, complexity]

## Current State Analysis
- **Framework**: React 18.2.0
- **Build Tool**: Vite 4.3.0
- **Component Count**: 47 components
- **Styling**: styled-components + custom CSS
- **State Management**: Redux Toolkit
- **Routing**: React Router v6

## Hardcoded Values Detected
- Colors: 142 instances across 34 files
- Spacing: 89 instances across 28 files
- Custom fonts: 3 non-standard fonts
- Inline styles: 67 instances

## Component Categorization
- **Simple (shadcn mapping exists)**: 28 components
- **Moderate (requires adaptation)**: 13 components
- **Complex (custom development needed)**: 6 components

## Recommended Migration Plan
1. Phase 3: Setup Next.js + shadcn infrastructure
2. Phase 4.1: Convert layout components (Header, Footer, Layout)
3. Phase 4.2: Convert simple UI (Button, Card, Badge → shadcn equivalents)
4. Phase 4.3: Convert forms (Input, Select → shadcn/ui Form components)
5. Phase 4.4: Convert complex components (DataTable, Charts)
6. Phase 4.5: Styling standardization (CSS variables)
7. Phase 4.6: Pages and routing
8. Phase 5: Verification and cleanup

## Estimated Effort
- **Total Components**: 47
- **Batches**: 9-10 batches
- **Complexity**: Moderate

阶段 2:迁移规划(详细说明)

2.1 组件映射策略

查看 component-inventory.json,并使用 shadcn 组件参考资料创建映射表。

非常重要:使用 MCP 发现 shadcn 组件

映射前,检查 shadcn MCP 服务是否可用:

# Check if MCP server is available
# Try accessing https://ui.shadcn.com/docs/mcp

如果 MCP 不可用,请安装:

npx shadcn@latest mcp init --client claude

使用 MCP 查询可用组件:

  • “shadcn 中有哪些按钮组件?”
  • “展示 shadcn 中的表单组件”
  • “shadcn 中与模态框/对话框等效的组件是什么?”
  • “shadcn 中有哪些数据展示组件?”

组件映射表模板:

现有组件shadcn 等效组件复杂度优先级备注
CustomButtonButton低1Props 大多兼容
ModalDialog中2API 不同,使用 Radix
DataTableTable + DataTable高3需要自定义钩子
DropdownDropdownMenu低1可直接映射
DatePickerCalendar + Popover中2组合模式

加载特定框架的迁移指南:

  • 对于 React:阅读 ./references/react-to-nextjs.md
  • 对于 Vue:阅读 ./references/vue-to-nextjs.md
  • 对于 Angular:阅读 ./references/angular-to-nextjs.md
  • 对于样式:阅读 ./references/styling-migration.md
2.2 批次组织

按照以下原则将组件组织为多个批次:

批次策略:

  1. 按类型分组(布局、表单、数据展示、导航)
  2. 由简单到复杂(从容易完成的任务开始)
  3. 按依赖顺序排列(先转换依赖项)
  4. 批次规模:每批 5-10 个组件

批次计划示例:

批次 1:布局与结构(优先级:关键)

  • Header
  • Footer
  • MainLayout
  • Container
  • Sidebar

批次 2:简单 UI 组件(优先级:高)

  • Button → shadcn Button
  • Card → shadcn Card
  • Badge → shadcn Badge
  • Alert → shadcn Alert
  • Avatar → shadcn Avatar

批次 3:表单组件(优先级:高)

  • Input → shadcn Input
  • Select → shadcn Select
  • Checkbox → shadcn Checkbox
  • RadioGroup → shadcn RadioGroup
  • 表单验证 → shadcn Form + react-hook-form

批次 4:导航(优先级:中)

  • NavBar → shadcn NavigationMenu
  • Breadcrumbs → shadcn Breadcrumb
  • Tabs → shadcn Tabs
  • Pagination → shadcn Pagination

批次 5:数据展示(优先级:中)

  • Table → shadcn Table
  • DataGrid → shadcn DataTable(含排序、筛选)
  • List → shadcn 自定义组合
  • Accordion → shadcn Accordion

批次 6:覆盖层与模态框(优先级:中)

  • Modal → shadcn Dialog
  • Tooltip → shadcn Tooltip
  • Popover → shadcn Popover
  • DropdownMenu → shadcn DropdownMenu

批次 7:复杂组件(优先级:低)

  • Charts → shadcn Charts(集成 Recharts)
  • Calendar/DatePicker → shadcn Calendar
  • CommandPalette → shadcn Command
  • DataVisualization → 使用 shadcn 基元自定义实现

批次 8:样式标准化(优先级:关键)

  • 提取所有硬编码颜色 → CSS 变量
  • 将间距转换为 Tailwind 类
  • 统一字体排版
  • 一致地应用主题系统

批次 9:页面与路由(优先级:关键)

  • 将页面转换为 Next.js App Router
  • 使用 Next.js layout.tsx 设置布局
  • 实现路由模式
  • 添加加载和错误状态
2.3 风险评估

针对每个批次,识别风险:

  • API 差异:API 差异显著的组件
  • 功能缺失:旧组件中有而 shadcn 中没有的功能
  • 状态管理:需要重构的复杂状态
  • 依赖项:需要替换的外部库
  • 自定义逻辑:与 UI 紧密耦合的业务逻辑

风险缓解:

  • 在转换前记录 API 差异
  • 必要时创建适配器/包装组件
  • 在迁移前编写测试
  • 在过渡期间暂时保留旧组件
2.4 创建详细的迁移计划

生成详细的计划文档:migration-plan.md

# Next.js + shadcn Migration Plan

## Project: [Project Name]
## Date: [Current Date]
## Estimated Timeline: [X batches]

## Migration Strategy

### Approach
- Incremental migration with parallel running old and new code
- Batch-based conversion (5-10 components per batch)
- Test after each batch before proceeding
- Feature flag new components during transition

### Success Criteria
- All components use shadcn/ui or shadcn patterns
- Zero hardcoded colors/spacing (CSS variables only)
- 100% TypeScript coverage
- Passing test suite
- Lighthouse score >= 90
- No accessibility violations

## Detailed Batch Plan

[Include all batches from 2.2 with specific components listed]

## Timeline

Batch 1: Layout & Structure (Days 1-2)
Batch 2: Simple UI (Days 3-4)
[etc.]

## Notes and Considerations
[Any special requirements, blockers, or dependencies]

阶段 3:Next.js + shadcn 设置(详细说明)

3.1 检查/安装 shadcn MCP 服务

重要:始终使用 MCP 发现 shadcn 组件

  1. 检查 MCP 服务是否可访问:

    • 尝试访问 https://ui.shadcn.com/docs/mcp 中的文档
    • 检查能否通过 MCP 查询 shadcn 组件
  2. 如果不可用,请安装 MCP 服务:

npx shadcn@latest mcp init --client claude

这将启用:

  • 实时访问 shadcn 文档
  • 组件发现与搜索
  • 区块和图表模板发现
  • 主题和设计令牌参考

开发期间使用 MCP:

  • “针对[使用场景]有哪些可用组件?”
  • “显示 shadcn Button 的 props”
  • “shadcn 中有哪些可用的图表类型?”
  • “如何使用 shadcn Form 进行验证?”
3.2 初始化 Next.js 项目

运行初始化脚本:

bash ./scripts/init-nextjs-shadcn.sh [project-name]

或手动初始化:

# Check Node.js version (18+ required)
node -v

# Create Next.js project with App Router
npx create-next-app@latest [project-name] \
  --typescript \
  --tailwind \
  --app \
  --src-dir \
  --import-alias "@/*" \
  --no-turbopack

cd [project-name]
3.3 安装并配置 shadcn/ui
# Initialize shadcn/ui
npx shadcn@latest init

# Configuration prompts:
# - TypeScript: Yes
# - Style: Default
# - Base color: Choose from slate/gray/zinc/neutral/stone
# - CSS variables: Yes (CRITICAL - required for theming)
# - Import alias: @/components

这将创建:

  • components.json 配置文件
  • 包含 cn() 助手函数的 lib/utils.ts
  • 更新后的 shadcn 主题 tailwind.config.ts
  • app/globals.css 中的 CSS 变量
3.4 配置设计令牌(CSS 变量)

非常重要:所有主题样式都必须使用 CSS 变量

颜色格式:OKLCH(推荐)

此技能使用 OKLCH(OKLab 亮度、彩度、色相)色彩空间,而不是 HSL,以获得更好的感知均匀性和色彩准确度。

OKLCH 的优点:

  • 感知均匀(相同的变化 = 相同的感知差异)
  • 渐变插值效果更好
  • 亮度更可预测
  • 更适用于无障碍设计(对比度更准确)

编辑 app/globals.css 以定义设计系统:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  :root {
    --radius: 0.65rem;

    /* Background - Pure white */
    --background: 1 0 0;
    --foreground: 0.141 0.005 285.823;

    /* Card */
    --card: 1 0 0;
    --card-foreground: 0.141 0.005 285.823;

    /* Popover */
    --popover: 1 0 0;
    --popover-foreground: 0.141 0.005 285.823;

    /* Primary - Warm orange */
    --primary: 0.646 0.222 41.116;
    --primary-foreground: 0.98 0.016 73.684;

    /* Secondary - Light purple-gray */
    --secondary: 0.967 0.001 286.375;
    --secondary-foreground: 0.21 0.006 285.885;

    /* Muted - Subtle elements */
    --muted: 0.967 0.001 286.375;
    --muted-foreground: 0.552 0.016 285.938;

    /* Accent */
    --accent: 0.967 0.001 286.375;
    --accent-foreground: 0.21 0.006 285.885;

    /* Destructive - Red */
    --destructive: 0.577 0.245 27.325;

    /* Border and Input */
    --border: 0.92 0.004 286.32;
    --input: 0.92 0.004 286.32;

    /* Focus ring */
    --ring: 0.75 0.183 55.934;

    /* Chart colors */
    --chart-1: 0.837 0.128 66.29;
    --chart-2: 0.705 0.213 47.604;
    --chart-3: 0.646 0.222 41.116;
    --chart-4: 0.553 0.195 38.402;
    --chart-5: 0.47 0.157 37.304;
  }

  .dark {
    /* Dark mode backgrounds */
    --background: 0.141 0.005 285.823;
    --foreground: 0.985 0 0;

    /* Dark mode card */
    --card: 0.21 0.006 285.885;
    --card-foreground: 0.985 0 0;

    /* Dark mode popover */
    --popover: 0.21 0.006 285.885;
    --popover-foreground: 0.985 0 0;

    /* Dark mode primary - Brighter for contrast */
    --primary: 0.705 0.213 47.604;
    --primary-foreground: 0.98 0.016 73.684;

    /* Dark mode secondary */
    --secondary: 0.274 0.006 286.033;
    --secondary-foreground: 0.985 0 0;

    /* Dark mode muted */
    --muted: 0.274 0.006 286.033;
    --muted-foreground: 0.705 0.015 286.067;

    /* Dark mode accent */
    --accent: 0.274 0.006 286.033;
    --accent-foreground: 0.985 0 0;

    /* Dark mode destructive */
    --destructive: 0.704 0.191 22.216;

    /* Dark mode borders (with alpha) */
    --border: 1 0 0 / 10%;
    --input: 1 0 0 / 15%;

    /* Dark mode focus ring */
    --ring: 0.408 0.123 38.172;

    /* Chart colors (consistent) */
    --chart-1: 0.837 0.128 66.29;
    --chart-2: 0.705 0.213 47.604;
    --chart-3: 0.646 0.222 41.116;
    --chart-4: 0.553 0.195 38.402;
    --chart-5: 0.47 0.157 37.304;
  }
}

@layer base {
  * {
    @apply border-border;
  }
  body {
    @apply bg-background text-foreground;
  }
}

为迁移的项目自定义:

如果要迁移已有设计系统的应用,请提取现有颜色并映射到 CSS 变量:

# Use the detection script to find existing colors
bash ./scripts/detect-hardcoded-values.sh /path/to/old/codebase

# Map old colors to new CSS variables (OKLCH format)
# Use https://oklch.com or https://colorjs.io to convert
# Example:
# Old: #FF6B35 (brand orange) → --primary: 0.646 0.222 41.116
# Old: #3B82F6 (blue) → --primary: 0.630 0.213 255.5
# Old: #10B981 (green) → --success: 0.710 0.180 165.4
3.5 安装必要的 shadcn 组件

使用 MCP 查找所需组件!

安装核心组件:

# Layout & Structure
npx shadcn@latest add card
npx shadcn@latest add separator

# Forms
npx shadcn@latest add button
npx shadcn@latest add input
npx shadcn@latest add label
npx shadcn@latest add select
npx shadcn@latest add checkbox
npx shadcn@latest add radio-group
npx shadcn@latest add form

# Navigation
npx shadcn@latest add navigation-menu
npx shadcn@latest add tabs
npx shadcn@latest add breadcrumb

# Feedback
npx shadcn@latest add alert
npx shadcn@latest add toast
npx shadcn@latest add dialog
npx shadcn@latest add tooltip

# Data Display
npx shadcn@latest add table
npx shadcn@latest add badge
npx shadcn@latest add avatar

# Overlays
npx shadcn@latest add popover
npx shadcn@latest add dropdown-menu
npx shadcn@latest add sheet

在开发过程中,根据需要通过 MCP 查询其他组件。

3.6 设置主题提供程序(支持深色模式)

安装 next-themes:

npm install next-themes

创建 components/theme-provider.tsx:

"use client"

import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}

更新 app/layout.tsx:

import { ThemeProvider } from "@/components/theme-provider"

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider
          attribute="class"
          defaultTheme="system"
          enableSystem
          disableTransitionOnChange
        >
          {children}
        </ThemeProvider>
      </body>
    </html>
  )
}
3.7 创建示例组件

创建 components/example-card.tsx,展示最佳实践:

import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"

export function ExampleCard() {
  return (
    <Card className="w-full max-w-md">
      <CardHeader>
        <CardTitle>shadcn/ui Best Practices</CardTitle>
        <CardDescription>
          This card demonstrates proper shadcn patterns
        </CardDescription>
      </CardHeader>
      <CardContent>
        <p className="text-sm text-muted-foreground">
          Notice: No hardcoded colors, using CSS variables via Tailwind classes,
          standard shadcn components, and proper typography scale.
        </p>
      </CardContent>
      <CardFooter className="flex justify-between">
        <Button variant="outline">Cancel</Button>
        <Button>Continue</Button>
      </CardFooter>
    </Card>
  )
}

展示的关键模式:

  • 使用标准 shadcn 组件(Card、Button)
  • 不使用硬编码颜色(使用 text-muted-foreground)
  • 通过 Tailwind 自动应用 CSS 变量
  • 语义化变体(outline、默认)
  • 合理组合组件

第 4 阶段:系统化转换(详细说明)

4.1 组件转换工作流

每批处理 5–10 个组件:

步骤 1:检查本批次的组件

加载组件文件并了解:

  • 当前功能
  • Props/API
  • 样式方案
  • 状态管理
  • 事件处理程序

步骤 2:查询 MCP,查找 shadcn 对应组件

转换前,使用 MCP:

  • “哪种 shadcn 组件适用于 [组件类型]?”
  • “展示 shadcn [组件] 的 props 和示例”
  • “如何将 shadcn [组件] 与 [功能] 配合使用?”

步骤 3:转换组件

遵循以下模式:

// OLD: Custom button with hardcoded styles
const CustomButton = ({ children, onClick, variant = 'primary' }) => {
  const styles = {
    primary: {
      backgroundColor: '#3b82f6', // HARDCODED!
      color: '#ffffff',
      padding: '8px 16px', // HARDCODED!
      borderRadius: '6px'
    },
    secondary: {
      backgroundColor: '#6b7280',
      color: '#ffffff',
      padding: '8px 16px',
      borderRadius: '6px'
    }
  }

  return (
    <button style={styles[variant]} onClick={onClick}>
      {children}
    </button>
  )
}

// NEW: shadcn Button with CSS variables
import { Button } from "@/components/ui/button"

const CustomButton = ({ children, onClick, variant = 'default' }) => {
  return (
    <Button variant={variant} onClick={onClick}>
      {children}
    </Button>
  )
}

转换检查清单:

  • ✅ 替换为 shadcn 组件
  • ✅ 移除所有硬编码颜色
  • ✅ 移除内联样式
  • ✅ 仅使用 Tailwind 类
  • ✅ 使用语义化变体(default、outline、destructive 等)
  • ✅ 保留所有功能
  • ✅ 正确定义 TypeScript 类型

步骤 4:将硬编码值替换为 CSS 变量

// OLD: Hardcoded spacing and colors
<div style={{
  backgroundColor: '#f3f4f6',  // WRONG
  padding: '20px',              // WRONG
  margin: '10px 0'              // WRONG
}}>

// NEW: Tailwind classes using CSS variables
<div className="bg-secondary p-5 my-2.5">

// Or for custom spacing:
<div className="bg-secondary" style={{ padding: 'var(--spacing-5)' }}>

步骤 5:测试功能

转换每个组件后:

# Run tests
npm test

# Visual testing
npm run dev
# Manually verify component renders correctly

步骤 6:确认不存在违规项

对新组件运行检测脚本:

bash ./scripts/detect-hardcoded-values.sh src/components/[batch-name]

应返回 0 个违规项。

步骤 7:完成本批次,继续下一批

更新待办列表和 migration-plan.md 中的进度。

4.2 常见组件迁移

详细映射请参阅 ./references/shadcn-component-mapping.md。

快速参考:

模式旧方案shadcn 方案
按钮自定义样式按钮<Button variant="...">
模态框/对话框自定义遮罩层<Dialog> 与 <DialogTrigger> 和 <DialogContent>
表单输入带验证的自定义输入框<Form> + <FormField> + react-hook-form
下拉菜单自定义选择框<Select> 或 <DropdownMenu>
表格自定义表格<Table> 或 DataTable 模式
工具提示自定义悬停组件<Tooltip>
Toast/通知自定义通知useToast() hook + <Toaster>
选项卡自定义选项卡组件<Tabs> 与 <TabsList> 和 <TabsContent>
卡片自定义卡片<Card> 与子组件
徽章自定义徽章/胶囊标签<Badge variant="...">
4.3 处理复杂组件

对于没有直接对应 shadcn 组件的组件:

选项 1:组合

使用 shadcn 基础组件构建:

// Complex dashboard widget using shadcn primitives
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"

export function DashboardWidget({ title, data, onRefresh }) {
  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between">
        <CardTitle>{title}</CardTitle>
        <Button variant="outline" size="sm" onClick={onRefresh}>
          Refresh
        </Button>
      </CardHeader>
      <CardContent>
        {data.map(item => (
          <div key={item.id} className="flex items-center justify-between py-2">
            <span className="text-sm">{item.label}</span>
            <Badge variant={item.status === 'success' ? 'default' : 'destructive'}>
              {item.value}
            </Badge>
          </div>
        ))}
      </CardContent>
    </Card>
  )
}

选项 2:扩展 shadcn 组件

创建扩展 shadcn 的自定义组件:

// Custom component extending shadcn Button
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"

interface IconButtonProps extends React.ComponentProps<typeof Button> {
  icon: React.ReactNode
}

export function IconButton({ icon, children, className, ...props }: IconButtonProps) {
  return (
    <Button className={cn("flex items-center gap-2", className)} {...props}>
      {icon}
      {children}
    </Button>
  )
}

选项 3:使用 shadcn Blocks

使用 MCP 查找 shadcn blocks(预构建的复杂组件):

“shadcn 中有哪些适用于 [use case] 的 blocks?”

安装 blocks:

npx shadcn@latest add [block-name]
4.4 页面和路由转换

将页面转换为 Next.js App Router 结构:

旧结构(React Router):

src/
  pages/
    Home.tsx
    About.tsx
    Dashboard.tsx
    users/
      UserList.tsx
      UserDetail.tsx

新结构(Next.js App Router):

app/
  page.tsx          # Home
  about/
    page.tsx        # About
  dashboard/
    page.tsx        # Dashboard
    layout.tsx      # Dashboard layout
  users/
    page.tsx        # UserList
    [id]/
      page.tsx      # UserDetail
  layout.tsx        # Root layout
  loading.tsx       # Loading state
  error.tsx         # Error boundary

转换示例:

// OLD: React Router page
// src/pages/Dashboard.tsx
import { useNavigate } from 'react-router-dom'

export function Dashboard() {
  const navigate = useNavigate()
  return (
    <div style={{ padding: '20px' }}>
      <h1>Dashboard</h1>
      <button onClick={() => navigate('/users')}>
        View Users
      </button>
    </div>
  )
}

// NEW: Next.js App Router page
// app/dashboard/page.tsx
import Link from 'next/link'
import { Button } from '@/components/ui/button'

export default function DashboardPage() {
  return (
    <div className="container py-6">
      <h1 className="text-3xl font-bold mb-6">Dashboard</h1>
      <Link href="/users">
        <Button>View Users</Button>
      </Link>
    </div>
  )
}

主要变更:

  • 页面使用默认导出
  • 使用 Next.js <Link> 替代路由导航
  • 移除硬编码的内边距 → 使用 Tailwind 类
  • 使用 shadcn Button
4.5 状态管理迁移

加载参考资料: ./references/react-to-nextjs.md,了解状态管理模式

常见模式:

本地状态(useState):

  • 在 Next.js App Router 中保持不变
  • 使用 "use client" 标记客户端组件

全局状态:

  • Redux → Zustand 或 React Context
  • MobX → Zustand
  • Recoil → Zustand 或 Jotai

服务端状态:

  • React Query → TanStack Query(在 Next.js 中仍可使用)
  • SWR → SWR(兼容 Next.js)
  • 或使用 Next.js Server Components 获取服务端数据

第 5 阶段:验证与清理(详细说明)

5.1 运行测试套件
# Run all tests
npm test

# Run with coverage
npm test -- --coverage

# Ensure 100% of migrated components have passing tests
5.2 视觉回归测试

手动验证清单:

  • 所有页面均可正确渲染
  • 所有组件均符合设计系统
  • 深色模式运行正常
  • 保持响应式设计
  • 不显示硬编码颜色
  • 整体间距保持一致
  • 排版符合设计系统

可选:使用 Percy、Chromatic 或 Playwright 设置自动化视觉回归测试。

5.3 响应式设计测试

关键:在真实设备上测试,而不仅仅是使用浏览器 DevTools

参考: ./references/responsive-design-patterns.md,查看完整的响应式测试指南。

设备测试清单:

  • iPhone SE(320px - 现代视口中的最小尺寸)
  • iPhone 14 Pro(390px)
  • iPad(768px)
  • iPad Pro(1024px)
  • 桌面设备(1280px - 1920px)
  • 超宽屏(2560px+)

方向测试:

  • 手机/平板竖屏模式
  • 手机/平板横屏模式
  • 旋转设备时的响应行为

响应式模式验证:

  • 导航:手机汉堡菜单 → 平板侧边栏 → 桌面导航栏
  • 数据表格:手机卡片 → 平板可滚动表格 → 桌面完整表格
  • 网格:手机 1 列 → 平板 2 列 → 桌面 3-4 列
  • 表单:手机单列 → 桌面多列
  • 触控目标:手机上最小尺寸为 44x44px
  • 排版:在所有屏幕尺寸下均清晰易读(正文最小字号为 16px)
  • 图片:采用响应式尺寸并保持正确的宽高比

断点验证:

# Test all Tailwind breakpoints
# sm: 640px, md: 768px, lg: 1024px, xl: 1280px, 2xl: 1536px

# Verify components respond correctly at each breakpoint

组件示例: 查看 ./assets/component-templates/ 中的响应式设计示例:

  • responsive-navigation.tsx - 手机/平板/桌面导航模式
  • responsive-data-table.tsx - 带手机卡片布局的响应式表格
  • responsive-dashboard.tsx - 响应式网格布局
  • complex-form.tsx - 多步骤响应式表单
5.4 最后检查硬编码值
bash ./scripts/detect-hardcoded-values.sh src/

预期结果: 0 项违规

如果发现违规项,请返回第 4 阶段并修复。

5.5 无障碍审计(WCAG 2.1 AA 级)

关键:达到 WCAG 2.1 AA 级合规要求

参考: ./references/accessibility-best-practices.md,了解全面的无障碍测试指南。

# Install axe DevTools or use Lighthouse
npm install -D @axe-core/playwright

# Run accessibility tests
npm run test:a11y

shadcn/ui 组件在设计时考虑了无障碍性(使用 Radix UI 基元),但仍需验证:

自动化测试:

  • 在所有页面上运行 axe DevTools 浏览器扩展
  • Lighthouse 无障碍评分 >= 90
  • 自动化工具未报告任何 WCAG 违规问题
  • eslint-plugin-jsx-a11y 检查通过(如已配置)

键盘导航(WCAG 2.1.1、2.1.2):

  • 所有交互元素均可通过 Tab 键访问
  • Tab 顺序合理(与视觉布局一致)
  • 不存在键盘陷阱(可通过 Tab 键移出所有组件)
  • 按 Enter/Space 键可激活按钮/链接
  • 按 Escape 键可关闭模态框/对话框
  • 可使用方向键在组件内部导航(标签页、菜单、单选组)
  • 所有交互元素均显示清晰的焦点指示器

屏幕阅读器测试: 使用实际的屏幕阅读器进行测试:

  • macOS:VoiceOver(Cmd + F5)
  • Windows:NVDA(免费)或 JAWS
  • 移动设备:VoiceOver(iOS)或 TalkBack(Android)

屏幕阅读器检查清单(WCAG 1.3.1、4.1.2):

  • 所有图像均有替代文本
  • 表单输入框均有关联的标签
  • 按钮有描述性文本或 aria-label
  • 标题遵循逻辑层级(h1 → h2 → h3)
  • 页面区域标记齐全(header、nav、main、aside、footer)
  • 通过 aria-live 区域播报动态内容
  • 向屏幕阅读器播报错误消息

颜色对比度(WCAG 1.4.3):

  • 正文文本:对比度至少为 4.5:1
  • 大号文本(18pt+):对比度至少为 3:1
  • UI 组件:对比度至少为 3:1
  • 焦点指示器:对比度至少为 3:1
  • 测试浅色和深色模式

表单无障碍性(WCAG 3.3.1、3.3.2):

  • 所有输入框均有可见标签
  • 清晰标明必填字段
  • 错误消息具体且有帮助
  • 错误消息与输入框相关联(aria-describedby)
  • 表单验证不单靠颜色提示

触控目标(WCAG 2.5.5):

  • 移动设备上的所有触控目标至少为 44x44 CSS 像素
  • 触控目标之间间距充足(至少 8px)

ARIA 用法(WCAG 4.1.2):

  • 仅含图标的按钮使用 ARIA 标签
  • 可折叠区域使用 aria-expanded
  • 标签页使用 aria-selected
  • 装饰性元素使用 aria-hidden
  • 错误消息使用 role="alert"
  • 非关键更新使用 role="status"

完整 WCAG 2.1 AA 检查清单: 完整的 WCAG 2.1 AA 级检查清单请参阅 ./references/accessibility-best-practices.md。

5.6 性能审计
# Build for production
npm run build

# Analyze bundle
npm run analyze  # If you have bundle analyzer configured

运行 Lighthouse 审计:

  • 性能 >= 90
  • 无障碍性 >= 90
  • 最佳实践 >= 90
  • SEO >= 90

性能检查清单:

  • Core Web Vitals 达到“良好”阈值
    • LCP(最大内容绘制)< 2.5s
    • FID(首次输入延迟)< 100ms
    • CLS(累积布局偏移)< 0.1
  • 优化图像(使用 Next.js Image 组件)
  • 为大型组件实现代码拆分
  • 对首屏以下内容进行延迟加载
  • 包体积合理(使用 bundle analyzer 检查)
5.7 移除旧代码

确认迁移无误后:

# Remove old framework code
rm -rf src/old-components/  # or whatever old structure was

# Remove old dependencies
npm uninstall [old-framework] [old-ui-library] styled-components emotion ...

# Clean up old config files
rm -f .babelrc webpack.config.js  # etc.
5.8 生成完成报告

创建 migration-complete-report.md:

# Migration Completion Report

## Summary
Successfully migrated [Project Name] from [Old Framework] to Next.js + shadcn/ui.

## Statistics
- **Components Migrated**: 47
- **Lines of Code Changed**: ~5,200
- **Hardcoded Values Removed**: 231
- **CSS Variables Added**: 48
- **shadcn Components Used**: 18

## Test Results
- **Unit Tests**: 142/142 passing
- **Integration Tests**: 23/23 passing
- **Accessibility Score**: 98/100
- **Lighthouse Performance**: 94/100

## Before/After Comparison

### Before
- Framework: React 18 + Vite
- Styling: styled-components + custom CSS
- Hardcoded values: 231 violations
- Bundle size: 523 KB
- Lighthouse: 76

### After
- Framework: Next.js 15 + App Router
- Styling: Tailwind CSS + shadcn/ui
- Hardcoded values: 0 violations
- Bundle size: 398 KB (24% reduction)
- Lighthouse: 94 (23% improvement)

## Design System
All components now use CSS variables defined in globals.css:
- 24 color tokens
- 12 spacing tokens
- 8 typography tokens
- Full dark mode support

## Next Steps
- Deploy to production
- Monitor performance metrics
- Gather user feedback
- Optional: Implement additional shadcn blocks

shadcn 设计原则(关键)

核心原则

1. 使用 CSS 变量进行所有主题设置

  • 绝不要硬编码颜色、间距或排版样式
  • 在 globals.css 中将所有设计令牌定义为 CSS 变量
  • 使用引用这些变量的 Tailwind 类

2. 仅使用标准组件

  • 原样使用 shadcn/ui 组件
  • 通过组合扩展,而非修改组件
  • 如果 shadcn 没有所需组件,则使用 shadcn 基础组件构建

3. 保持设计语言一致

  • 遵循 shadcn 的设计模式
  • 使用语义化变体(default、outline、destructive、ghost、link、secondary)
  • 保持间距比例一致
  • 遵循 shadcn 的排版层级

4. 不创建自定义 UI 组件

  • 不要创建自定义按钮、输入框、卡片等
  • 使用 shadcn 组件,或使用 shadcn 基础组件构建
  • 例外:业务逻辑组件(非 UI 基础组件)

5. 优先考虑无障碍性

  • shadcn 使用 Radix UI(默认支持无障碍性)
  • 不要覆盖无障碍功能
  • 使用键盘导航和屏幕阅读器进行测试
应避免的反模式

绝不要这样做:

❌ 硬编码颜色

// WRONG
<div style={{ backgroundColor: '#3b82f6' }}>

// RIGHT
<div className="bg-primary">

❌ 硬编码间距

// WRONG
<div style={{ padding: '20px', margin: '10px' }}>

// RIGHT
<div className="p-5 m-2.5">

❌ 为 UI 基础组件创建自定义样式组件

// WRONG
const CustomButton = styled.button`
  background: #3b82f6;
  padding: 8px 16px;
  border-radius: 6px;
`

// RIGHT
import { Button } from '@/components/ui/button'

❌ 内联样式

// WRONG
<div style={{ color: 'red', fontSize: '14px' }}>

// RIGHT
<div className="text-destructive text-sm">

❌ 硬编码字体

// WRONG
<h1 style={{ fontFamily: 'Montserrat' }}>

// RIGHT
<h1 className="font-sans text-4xl font-bold">

❌ 表情符号图标(请改用 Lucide React 图标)

// WRONG
<span>❌ Delete</span>

// RIGHT
import { X } from 'lucide-react'
<Button variant="destructive">
  <X className="mr-2 h-4 w-4" />
  Delete
</Button>

❌ 任意 CSS 值

// WRONG
<div className="text-[#ff0000]">

// RIGHT
<div className="text-destructive">
最佳实践

✅ 使用语义化颜色名称

// Use semantic CSS variable names
bg-background
text-foreground
bg-primary
text-primary-foreground
bg-secondary
text-muted-foreground
border-border

✅ 使用 Tailwind 间距比例

// Consistent spacing using Tailwind
p-2, p-4, p-6, p-8  // padding
m-2, m-4, m-6, m-8  // margin
gap-2, gap-4        // flex/grid gap

✅ 组合组件

// Build complex UIs by composing shadcn components
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'

✅ 使用 MCP 进行发现

// Before building, ask MCP:
// "What shadcn component should I use for [use case]?"
// "Show me examples of shadcn [component]"

✅ 通过组合扩展

// Create higher-level components that compose shadcn
export function FeatureCard({ feature }: { feature: Feature }) {
  return (
    <Card>
      <CardHeader>
        <CardTitle>{feature.title}</CardTitle>
      </CardHeader>
      <CardContent>
        <p className="text-muted-foreground">{feature.description}</p>
        <Button className="mt-4">Learn More</Button>
      </CardContent>
    </Card>
  )
}

参考文件

特定框架迁移:

组件与样式:

响应式设计与无障碍性:

组件模板示例:

脚本:

  • ./scripts/analyze-codebase.py - 自动分析代码库
  • ./scripts/detect-hardcoded-values.sh - 查找反模式
  • ./scripts/init-nextjs-shadcn.sh - 初始化项目
  • ./scripts/generate-migration-report.py - 生成迁移报告

官方文档:


新项目快速入门

如果要创建新的 Next.js 应用(而非进行迁移):

  1. 初始化

    bash ./scripts/init-nextjs-shadcn.sh my-app
    
  2. 检查 MCP 访问权限

    npx shadcn@latest mcp init --client claude
    
  3. 安装组件

    • 使用 MCP 查找所需组件
    • 使用 npx shadcn@latest add [component] 安装
  4. 按照最佳实践构建

    • 仅使用 CSS 变量
    • 组合 shadcn 组件
    • 遵循上述设计原则

概述

此技能可系统地将前端迁移至 Next.js + shadcn/ui,并严格遵循设计原则:

  • 自动分析现有代码库
  • 系统化批量转换(每次处理 5-10 个组件)
  • 零容忍硬编码值(仅使用 CSS 变量)
  • 集成 MCP,用于发现 shadcn 组件
  • 支持多种框架(React、Vue、Angular、原生 JS)
  • 全面验证(测试、无障碍性、性能)

**结果:**符合 shadcn/ui 最佳实践的生产级 Next.js 应用,拥有一致的设计系统、完整的深色模式支持,且没有反模式。

评论

支持 Markdown