senior-frontend by alirezarezvani/claude-skills
npx skills add https://github.com/alirezarezvani/claude-skills --skill senior-frontend适用于 React/Next.js 应用程序的前端开发模式、性能优化和自动化工具。
使用 TypeScript、Tailwind CSS 和最佳实践配置生成新的 Next.js 或 React 项目。
使用你的项目名称和模板运行脚手架工具:
python scripts/frontend_scaffolder.py my-app --template nextjs
添加可选功能(身份验证、API、表单、测试、Storybook):
python scripts/frontend_scaffolder.py dashboard --template nextjs --features auth,api
进入项目并安装依赖项:
cd my-app && npm install
启动开发服务器:
npm run dev
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 选项 | 描述 |
|---|---|
--template nextjs | Next.js 14+,包含 App Router 和 Server Components |
--template react | React + Vite,包含 TypeScript |
--features auth | 添加 NextAuth.js 身份验证 |
--features api | 添加 React Query + API 客户端 |
--features forms | 添加 React Hook Form + Zod 验证 |
--features testing | 添加 Vitest + Testing Library |
--dry-run | 预览文件而不创建它们 |
my-app/
├── app/
│ ├── layout.tsx # 根布局,包含字体
│ ├── page.tsx # 主页
│ ├── globals.css # Tailwind + CSS 变量
│ └── api/health/route.ts
├── components/
│ ├── ui/ # 按钮、输入框、卡片
│ └── layout/ # 页眉、页脚、侧边栏
├── hooks/ # useDebounce、useLocalStorage
├── lib/ # 工具函数 (cn)、常量
├── types/ # TypeScript 接口
├── tailwind.config.ts
├── next.config.js
└── package.json
生成包含 TypeScript、测试和 Storybook 故事的 React 组件。
生成客户端组件:
python scripts/component_generator.py Button --dir src/components/ui
生成服务器组件:
python scripts/component_generator.py ProductCard --type server
生成包含测试和故事文件:
python scripts/component_generator.py UserProfile --with-test --with-story
生成自定义钩子:
python scripts/component_generator.py FormValidation --type hook
| 选项 | 描述 |
|---|---|
--type client | 客户端组件,包含 'use client'(默认) |
--type server | 异步服务器组件 |
--type hook | 自定义 React 钩子 |
--with-test | 包含测试文件 |
--with-story | 包含 Storybook 故事 |
--flat | 在输出目录中创建,不创建子目录 |
--dry-run | 预览而不创建文件 |
'use client';
import { useState } from 'react';
import { cn } from '@/lib/utils';
interface ButtonProps {
className?: string;
children?: React.ReactNode;
}
export function Button({ className, children }: ButtonProps) {
return (
<div className={cn('', className)}>
{children}
</div>
);
}
分析 package.json 和项目结构,寻找包优化机会。
在你的项目上运行分析器:
python scripts/bundle_analyzer.py /path/to/project
查看健康评分和问题:
Bundle Health Score: 75/100 (C)
HEAVY DEPENDENCIES:
moment (290KB)
Alternative: date-fns (12KB) or dayjs (2KB)
lodash (71KB)
Alternative: lodash-es with tree-shaking
通过替换重型依赖项来应用推荐的修复。
使用详细模式重新运行以检查导入模式:
python scripts/bundle_analyzer.py . --verbose
| 评分 | 等级 | 操作 |
|---|---|---|
| 90-100 | A | 包已优化良好 |
| 80-89 | B | 有少量优化空间 |
| 70-79 | C | 替换重型依赖项 |
| 60-69 | D | 多个问题需要注意 |
| 0-59 | F | 严重的包大小问题 |
分析器识别出这些常见的重型包:
| 包 | 大小 | 替代方案 |
|---|---|---|
| moment | 290KB | date-fns (12KB) 或 dayjs (2KB) |
| lodash | 71KB | lodash-es 配合 tree-shaking |
| axios | 14KB | 原生 fetch 或 ky (3KB) |
| jquery | 87KB | 原生 DOM API |
| @mui/material | 大 | shadcn/ui 或 Radix UI |
参考:references/react_patterns.md
在相关组件之间共享状态:
const Tabs = ({ children }) => {
const [active, setActive] = useState(0);
return (
<TabsContext.Provider value={{ active, setActive }}>
{children}
</TabsContext.Provider>
);
};
Tabs.List = TabList;
Tabs.Panel = TabPanel;
// 用法
<Tabs>
<Tabs.List>
<Tabs.Tab>One</Tabs.Tab>
<Tabs.Tab>Two</Tabs.Tab>
</Tabs.List>
<Tabs.Panel>Content 1</Tabs.Panel>
<Tabs.Panel>Content 2</Tabs.Panel>
</Tabs>
提取可重用的逻辑:
function useDebounce<T>(value: T, delay = 500): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
// 用法
const debouncedSearch = useDebounce(searchTerm, 300);
共享渲染逻辑:
function DataFetcher({ url, render }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url).then(r => r.json()).then(setData).finally(() => setLoading(false));
}, [url]);
return render({ data, loading });
}
// 用法
<DataFetcher
url="/api/users"
render={({ data, loading }) =>
loading ? <Spinner /> : <UserList users={data} />
}
/>
参考:references/nextjs_optimization_guide.md
默认使用服务器组件。仅在需要时添加 'use client':
事件处理程序(onClick、onChange)
状态(useState、useReducer)
副作用(useEffect)
浏览器 API
// 服务器组件(默认)- 无 'use client' async function ProductPage({ params }) { const product = await getProduct(params.id); // 服务器端获取
return ( <div> <h1>{product.name}</h1> <AddToCartButton productId={product.id} /> {/* 客户端组件 */} </div> ); }
// 客户端组件 'use client'; function AddToCartButton({ productId }) { const [adding, setAdding] = useState(false); return <button onClick={() => addToCart(productId)}>Add</button>; }
import Image from 'next/image';
// 首屏内容 - 立即加载
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority
/>
// 响应式图片,使用 fill
<div className="relative aspect-video">
<Image
src="/product.jpg"
alt="Product"
fill
sizes="(max-width: 768px) 100vw, 50vw"
className="object-cover"
/>
</div>
// 并行获取
async function Dashboard() {
const [user, stats] = await Promise.all([
getUser(),
getStats()
]);
return <div>...</div>;
}
// 使用 Suspense 进行流式渲染
async function ProductPage({ params }) {
return (
<div>
<ProductDetails id={params.id} />
<Suspense fallback={<ReviewsSkeleton />}>
<Reviews productId={params.id} />
</Suspense>
</div>
);
}
参考:references/frontend_best_practices.md
<button>、<nav>、<main>)// 可访问的按钮
<button
type="button"
aria-label="关闭对话框"
onClick={onClose}
className="focus-visible:ring-2 focus-visible:ring-blue-500"
>
<XIcon aria-hidden="true" />
</button>
// 供键盘用户使用的跳过链接
<a href="#main-content" className="sr-only focus:not-sr-only">
跳转到主要内容
</a>
// 使用 React Testing Library 进行组件测试
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
test('点击按钮触发操作', async () => {
const onClick = vi.fn();
render(<Button onClick={onClick}>点击我</Button>);
await userEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledTimes(1);
});
// 测试可访问性
test('对话框是可访问的', async () => {
render(<Dialog open={true} title="确认" />);
expect(screen.getByRole('dialog')).toBeInTheDocument();
expect(screen.getByRole('dialog')).toHaveAttribute('aria-labelledby');
});
// next.config.js
const nextConfig = {
images: {
remotePatterns: [{ hostname: 'cdn.example.com' }],
formats: ['image/avif', 'image/webp'],
},
experimental: {
optimizePackageImports: ['lucide-react', '@heroicons/react'],
},
};
// 使用 cn() 进行条件类名
import { cn } from '@/lib/utils';
<button className={cn(
'px-4 py-2 rounded',
variant === 'primary' && 'bg-blue-500 text-white',
disabled && 'opacity-50 cursor-not-allowed'
)} />
// 包含 children 的 Props
interface CardProps {
className?: string;
children: React.ReactNode;
}
// 泛型组件
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {
return <ul>{items.map(renderItem)}</ul>;
}
references/react_patterns.mdreferences/nextjs_optimization_guide.mdreferences/frontend_best_practices.md每周安装数
313
仓库
GitHub 星标
3.6K
首次出现
2026年1月20日
安全审计
安装于
opencode253
gemini-cli248
claude-code245
codex231
github-copilot205
cursor204
Frontend development patterns, performance optimization, and automation tools for React/Next.js applications.
Generate a new Next.js or React project with TypeScript, Tailwind CSS, and best practice configurations.
Run the scaffolder with your project name and template:
python scripts/frontend_scaffolder.py my-app --template nextjs
Add optional features (auth, api, forms, testing, storybook):
python scripts/frontend_scaffolder.py dashboard --template nextjs --features auth,api
Navigate to the project and install dependencies:
cd my-app && npm install
Start the development server:
npm run dev
| Option | Description |
|---|---|
--template nextjs | Next.js 14+ with App Router and Server Components |
--template react | React + Vite with TypeScript |
--features auth | Add NextAuth.js authentication |
--features api | Add React Query + API client |
--features forms | Add React Hook Form + Zod validation |
--features testing |
my-app/
├── app/
│ ├── layout.tsx # Root layout with fonts
│ ├── page.tsx # Home page
│ ├── globals.css # Tailwind + CSS variables
│ └── api/health/route.ts
├── components/
│ ├── ui/ # Button, Input, Card
│ └── layout/ # Header, Footer, Sidebar
├── hooks/ # useDebounce, useLocalStorage
├── lib/ # utils (cn), constants
├── types/ # TypeScript interfaces
├── tailwind.config.ts
├── next.config.js
└── package.json
Generate React components with TypeScript, tests, and Storybook stories.
Generate a client component:
python scripts/component_generator.py Button --dir src/components/ui
Generate a server component:
python scripts/component_generator.py ProductCard --type server
Generate with test and story files:
python scripts/component_generator.py UserProfile --with-test --with-story
Generate a custom hook:
python scripts/component_generator.py FormValidation --type hook
| Option | Description |
|---|---|
--type client | Client component with 'use client' (default) |
--type server | Async server component |
--type hook | Custom React hook |
--with-test | Include test file |
--with-story | Include Storybook story |
--flat | Create in output dir without subdirectory |
'use client';
import { useState } from 'react';
import { cn } from '@/lib/utils';
interface ButtonProps {
className?: string;
children?: React.ReactNode;
}
export function Button({ className, children }: ButtonProps) {
return (
<div className={cn('', className)}>
{children}
</div>
);
}
Analyze package.json and project structure for bundle optimization opportunities.
Run the analyzer on your project:
python scripts/bundle_analyzer.py /path/to/project
Review the health score and issues:
Bundle Health Score: 75/100 (C)
HEAVY DEPENDENCIES:
moment (290KB)
Alternative: date-fns (12KB) or dayjs (2KB)
lodash (71KB)
Alternative: lodash-es with tree-shaking
Apply the recommended fixes by replacing heavy dependencies.
Re-run with verbose mode to check import patterns:
python scripts/bundle_analyzer.py . --verbose
| Score | Grade | Action |
|---|---|---|
| 90-100 | A | Bundle is well-optimized |
| 80-89 | B | Minor optimizations available |
| 70-79 | C | Replace heavy dependencies |
| 60-69 | D | Multiple issues need attention |
| 0-59 | F | Critical bundle size problems |
The analyzer identifies these common heavy packages:
| Package | Size | Alternative |
|---|---|---|
| moment | 290KB | date-fns (12KB) or dayjs (2KB) |
| lodash | 71KB | lodash-es with tree-shaking |
| axios | 14KB | Native fetch or ky (3KB) |
| jquery | 87KB | Native DOM APIs |
| @mui/material | Large | shadcn/ui or Radix UI |
Reference: references/react_patterns.md
Share state between related components:
const Tabs = ({ children }) => {
const [active, setActive] = useState(0);
return (
<TabsContext.Provider value={{ active, setActive }}>
{children}
</TabsContext.Provider>
);
};
Tabs.List = TabList;
Tabs.Panel = TabPanel;
// Usage
<Tabs>
<Tabs.List>
<Tabs.Tab>One</Tabs.Tab>
<Tabs.Tab>Two</Tabs.Tab>
</Tabs.List>
<Tabs.Panel>Content 1</Tabs.Panel>
<Tabs.Panel>Content 2</Tabs.Panel>
</Tabs>
Extract reusable logic:
function useDebounce<T>(value: T, delay = 500): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
// Usage
const debouncedSearch = useDebounce(searchTerm, 300);
Share rendering logic:
function DataFetcher({ url, render }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url).then(r => r.json()).then(setData).finally(() => setLoading(false));
}, [url]);
return render({ data, loading });
}
// Usage
<DataFetcher
url="/api/users"
render={({ data, loading }) =>
loading ? <Spinner /> : <UserList users={data} />
}
/>
Reference: references/nextjs_optimization_guide.md
Use Server Components by default. Add 'use client' only when you need:
Event handlers (onClick, onChange)
State (useState, useReducer)
Effects (useEffect)
Browser APIs
// Server Component (default) - no 'use client' async function ProductPage({ params }) { const product = await getProduct(params.id); // Server-side fetch
return ( <div> <h1>{product.name}</h1> <AddToCartButton productId={product.id} /> {/* Client component */} </div> ); }
// Client Component 'use client'; function AddToCartButton({ productId }) { const [adding, setAdding] = useState(false); return <button onClick={() => addToCart(productId)}>Add</button>; }
import Image from 'next/image';
// Above the fold - load immediately
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority
/>
// Responsive image with fill
<div className="relative aspect-video">
<Image
src="/product.jpg"
alt="Product"
fill
sizes="(max-width: 768px) 100vw, 50vw"
className="object-cover"
/>
</div>
// Parallel fetching
async function Dashboard() {
const [user, stats] = await Promise.all([
getUser(),
getStats()
]);
return <div>...</div>;
}
// Streaming with Suspense
async function ProductPage({ params }) {
return (
<div>
<ProductDetails id={params.id} />
<Suspense fallback={<ReviewsSkeleton />}>
<Reviews productId={params.id} />
</Suspense>
</div>
);
}
Reference: references/frontend_best_practices.md
<button>, <nav>, <main>)// Accessible button
<button
type="button"
aria-label="Close dialog"
onClick={onClose}
className="focus-visible:ring-2 focus-visible:ring-blue-500"
>
<XIcon aria-hidden="true" />
</button>
// Skip link for keyboard users
<a href="#main-content" className="sr-only focus:not-sr-only">
Skip to main content
</a>
// Component test with React Testing Library
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
test('button triggers action on click', async () => {
const onClick = vi.fn();
render(<Button onClick={onClick}>Click me</Button>);
await userEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledTimes(1);
});
// Test accessibility
test('dialog is accessible', async () => {
render(<Dialog open={true} title="Confirm" />);
expect(screen.getByRole('dialog')).toBeInTheDocument();
expect(screen.getByRole('dialog')).toHaveAttribute('aria-labelledby');
});
// next.config.js
const nextConfig = {
images: {
remotePatterns: [{ hostname: 'cdn.example.com' }],
formats: ['image/avif', 'image/webp'],
},
experimental: {
optimizePackageImports: ['lucide-react', '@heroicons/react'],
},
};
// Conditional classes with cn()
import { cn } from '@/lib/utils';
<button className={cn(
'px-4 py-2 rounded',
variant === 'primary' && 'bg-blue-500 text-white',
disabled && 'opacity-50 cursor-not-allowed'
)} />
// Props with children
interface CardProps {
className?: string;
children: React.ReactNode;
}
// Generic component
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {
return <ul>{items.map(renderItem)}</ul>;
}
references/react_patterns.mdreferences/nextjs_optimization_guide.mdreferences/frontend_best_practices.mdWeekly Installs
313
Repository
GitHub Stars
3.6K
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
opencode253
gemini-cli248
claude-code245
codex231
github-copilot205
cursor204
xdrop 文件传输脚本:Bun 环境下安全上传下载工具,支持加密分享
20,700 周安装
| Add Vitest + Testing Library |
--dry-run | Preview files without creating them |
--dry-run | Preview without creating files |