跳到主要内容
知仓学习社ZHICANG

senior-frontend

Frontend development skill for React, Next.js, TypeScript, and Tailwind CSS applications. Use when building React components, optimizing Next.js per…

写文件读环境变量(配置)严重 3 · 高危 3alirezarezvani/claude-skills

它会碰到什么

扫了多少14 个文本文件,148 KB
它会碰到什么写文件读环境变量(配置)
命中总数12 处
命中统计严重 3 · 高 3 · 中 0 · 低 0

关于「读环境变量(配置)」:这个技能会读 process.env 之类的环境变量,但读到的都是端口、目录、超时这类配置项,没有读取密钥类变量。扫描规则原本把「读环境变量」一律算作「读凭据」,本站按变量名做了细化区分,命中明细仍如实列在下面。

逐条看命中(6 条严重或高危)
  • 严重 scripts/frontend_scaffolder.py:797cred-paths
    # Environment
  • 严重 scripts/frontend_scaffolder.py:798cred-paths
    .env
  • 严重 scripts/frontend_scaffolder.py:799cred-paths
    .env.local
  • scripts/frontend_scaffolder.py:57identity-config-write
    "hooks": {
  • scripts/frontend_scaffolder.py:95identity-config-write
    "hooks": {
  • scripts/frontend_scaffolder.py:380cred-envread
    export const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000/api';

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Senior Frontend

Frontend development patterns, performance optimization, and automation tools for React/Next.js applications.

Table of Contents

  • [Project Scaffolding](#project-scaffolding)
  • [Component Generation](#component-generation)
  • [Bundle Analysis](#bundle-analysis)
  • [React Patterns](#react-patterns)
  • [Next.js Optimization](#nextjs-optimization)
  • [Accessibility and Testing](#accessibility-and-testing)

Project Scaffolding

Generate a new Next.js or React project with TypeScript, Tailwind CSS, and best practice configurations.

Workflow: Create New Frontend Project

  1. Run the scaffolder with your project name and template:
   python scripts/frontend_scaffolder.py my-app --template nextjs
  1. Add optional features (auth, api, forms, testing, storybook):
   python scripts/frontend_scaffolder.py dashboard --template nextjs --features auth,api
  1. Navigate to the project and install dependencies:
   cd my-app && npm install
  1. Start the development server:
   npm run dev

Scaffolder Options

| 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 | Add Vitest + Testing Library |

| --dry-run | Preview files without creating them |

Generated Structure (Next.js)

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

Component Generation

Generate React components with TypeScript, tests, and Storybook stories.

Workflow: Create a New Component

  1. Generate a client component:
   python scripts/component_generator.py Button --dir src/components/ui
  1. Generate a server component:
   python scripts/component_generator.py ProductCard --type server
  1. Generate with test and story files:
   python scripts/component_generator.py UserProfile --with-test --with-story
  1. Generate a custom hook:
   python scripts/component_generator.py FormValidation --type hook

Generator Options

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

| --dry-run | Preview without creating files |

Generated Component Example

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

Bundle Analysis

Analyze package.json and project structure for bundle optimization opportunities.

Workflow: Optimize Bundle Size

  1. Run the analyzer on your project:
   python scripts/bundle_analyzer.py /path/to/project
  1. 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
  1. Apply the recommended fixes by replacing heavy dependencies.
  1. Re-run with verbose mode to check import patterns:
   python scripts/bundle_analyzer.py . --verbose

Bundle Score Interpretation

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

Heavy Dependencies Detected

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 |


React Patterns

Reference: references/react_patterns.md

Compound Components

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>

Custom Hooks

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

Render Props

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

Next.js Optimization

Reference: references/nextjs_optimization_guide.md

Server vs Client Components

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

Image Optimization

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>

Data Fetching Patterns

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

Accessibility and Testing

Reference: references/frontend_best_practices.md

Accessibility Checklist

  1. Semantic HTML: Use proper elements (<button>, <nav>, <main>)
  2. Keyboard Navigation: All interactive elements focusable
  3. ARIA Labels: Provide labels for icons and complex widgets
  4. Color Contrast: Minimum 4.5:1 for normal text
  5. Focus Indicators: Visible focus states
// 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>

Testing Strategy

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

Quick Reference

Common Next.js Config

// next.config.js
const nextConfig = {
  images: {
    remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }],
    formats: ['image/avif', 'image/webp'],
  },
  experimental: {
    optimizePackageImports: ['lucide-react', '@heroicons/react'],
  },
};

Tailwind CSS Utilities

// 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'
)} />

TypeScript Patterns

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

Resources

  • React Patterns: references/react_patterns.md
  • Next.js Optimization: references/nextjs_optimization_guide.md
  • Best Practices: references/frontend_best_practices.md
  • Forcing-question library (Matt Pocock grill): references/forcing_questions.md
  • Composition map (which specialist to fork into): references/composition_map.md

Assumptions and Verifiable Success Criteria (Karpathy discipline)

Before this skill scaffolds a component, recommends a framework, or audits a bundle, the following four assumptions MUST be surfaced.

  1. Primary user device + network — mobile-4G, desktop-fiber, low-end-Android, or corporate-network. Drives every perf decision.
  2. LCP target in milliseconds — a single number, not "fast." Drives bundle budget and rendering choice.
  3. SEO-dependent vs. auth-walled — drives rendering (SSR/SSG/RSC vs. SPA).
  4. WCAG target + named a11y owner — AA, AAA, or best-effort. Drives a11y investment and CI gates.

Verifiable success criteria (Karpathy #4) — every recommendation must include:

  • Core Web Vitals targets (LCP, INP, CLS) at p75 on the primary device
  • A per-route JS bundle budget in KB-gzip
  • A Lighthouse a11y floor + perf floor

If any of those three is not stated, the recommendation is incomplete — return to Q2 of the forcing-question library.

The scripts/frontend_decision_engine.py tool encodes these checks: it refuses to recommend a profile without the four assumption inputs and prints the verifiable thresholds for the matched profile.


Customization profiles

Four built-in profiles in profiles/ calibrate every recommendation:

| Profile | When to pick | LCP target (mobile-4G p75) | Bundle budget |

|---|---|---|---|

| next-app-router | SaaS customer-facing, SEO + dynamic, RSC-first | 2000ms | 150 KB-gzip / route |

| remix-or-sveltekit | Mobile-4G primary, low-JS-first, progressive enhancement | 1500ms | 80 KB-gzip / route |

| vite-spa | Auth-walled app, desktop/corporate primary | 2500ms | 200 KB init + 80 KB / route |

| astro-or-static | Marketing / docs / blog, near-zero write, SEO-critical | 1200ms | 30 KB JS / page |

Pick a profile via:

python scripts/frontend_decision_engine.py \
  --primary-device mobile-4g --lcp-target-ms 2000 \
  --seo-dependent true --auth-walled false --team-size 5

The tool returns the best-fit profile, the runner-up tradeoff (if within 15%), the stack picks, the anti-patterns to avoid on that profile, and the required CI gates.

To add a custom profile (e.g., your org's internal-tool defaults): copy profiles/vite-spa.json to profiles/<your-org>.json and adjust constraints + success_thresholds.


Composition map

This skill does NOT reimplement scope owned by the POWERFUL-tier specialists. It forks into them. See references/composition_map.md for the full routing table. Key forks:

| Concern | Fork into |

|---|---|

| WCAG audit, contrast, screen-reader | engineering-team/skills/a11y-audit/ |

| Bundle profiling + runtime perf | engineering/skills/performance-profiler/ |

| Cinematic / scroll-storytelling landing | engineering-team/skills/epic-design/ |

| Apple HIG (iOS / macOS / visionOS) | product-team/skills/apple-hig-expert/ |

| Pre-commit Karpathy review | engineering/karpathy-coder/ |

| Pre-flight architecture grill | engineering/grill-me/ |

The cs-frontend-engineer agent orchestrates these forks via context: fork. Invoke it from another agent with Agent({subagent_type: "cs-frontend-engineer", prompt: "..."}) or via /cs:frontend-review <your problem>.


Forcing-question library (Matt Pocock grill)

Before locking any framework or rendering decision, walk the seven forcing questions in references/forcing_questions.md. Discipline:

  1. One question per turn. No bundling.
  2. Always recommend the answer with cited canon.
  3. Track answers in /tmp/frontend-grill-<date>.md.
  4. If a kill criterion trips, stop. Don't scaffold around an unresolved gap.
  5. After Q7, run frontend_decision_engine.py with the seven answers.

Summary:

  1. Primary device + network?
  2. LCP target in ms (and INP, CLS)?
  3. RSC / SPA / SSR / SSG — pick and defend?
  4. JS bundle budget per route?
  5. SEO-dependent or auth-walled?
  6. Design-system source of truth?
  7. WCAG target + named a11y owner?

Invocation from other agents and skills

Three surfaces:

  1. Slash command: /cs:frontend-review <prompt> — full grill + decision engine + composition routing.
  2. Agent subagent: Agent({subagent_type: "cs-frontend-engineer", prompt: "..."}) — forks context, returns ≤ 200-word digest.
  3. Direct tool call: python scripts/frontend_decision_engine.py ... — deterministic profile match when inputs are known.

See agents/engineering/cs-frontend-engineer.md for the full invocation contract.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。

它属于哪个仓库

星标★ 26,030
本站分层T1
该仓技能数846
原文件路径engineering-team/skills/senior-frontend/SKILL.md

同一个仓库里的其他技能

看这个仓库的全部 846 个技能

同名技能的其他版本

有 2 个不同仓库或目录里都有叫 senior-frontend 的技能。它们内容并不相同,别混用: