ogt-docs-rules-code-front
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOGT Docs - Rules Code Front
OGT 文档 - 前端代码规则
Frontend-specific coding standards for React/TypeScript applications.
适用于React/TypeScript应用的前端专属编码规范。
Overview
概述
Frontend rules establish consistent patterns for React components, state management, styling, and client-side architecture.
mermaid
flowchart TB
subgraph front ["docs/rules/code/front/"]
COMP["components/"]
STATE["state/"]
HOOKS["hooks/"]
STYLE["styling/"]
ROUTE["routing/"]
FETCH["data_fetching/"]
end
COMP --> |patterns| C1["composition"]
COMP --> |patterns| C2["props"]
STATE --> |patterns| S1["context"]
STATE --> |patterns| S2["local"]
HOOKS --> |patterns| H1["custom"]
STYLE --> |patterns| ST1["css-in-js"]前端规则为React组件、状态管理、样式及客户端架构建立统一模式。
mermaid
flowchart TB
subgraph front ["docs/rules/code/front/"]
COMP["components/"]
STATE["state/"]
HOOKS["hooks/"]
STYLE["styling/"]
ROUTE["routing/"]
FETCH["data_fetching/"]
end
COMP --> |patterns| C1["composition"]
COMP --> |patterns| C2["props"]
STATE --> |patterns| S1["context"]
STATE --> |patterns| S2["local"]
HOOKS --> |patterns| H1["custom"]
STYLE --> |patterns| ST1["css-in-js"]When to Use
适用场景
- Creating React component standards
- Defining state management patterns
- Establishing styling conventions
- Writing custom hook guidelines
- Setting data fetching patterns
- Defining routing conventions
- 创建React组件规范
- 定义状态管理模式
- 建立样式约定
- 编写自定义Hook指南
- 设置数据获取模式
- 定义路由约定
Folder Structure
目录结构
docs/rules/code/front/
├── components/ # Component patterns
│ ├── composition/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── props/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── naming/
│ │ ├── rule.md
│ │ └── examples.md
│ └── file_structure/
│ ├── rule.md
│ └── examples.md
│
├── state/ # State management
│ ├── local_state/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── context/
│ │ ├── rule.md
│ │ └── examples.md
│ └── derived_state/
│ ├── rule.md
│ └── examples.md
│
├── hooks/ # Custom hooks
│ ├── naming/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── dependencies/
│ │ ├── rule.md
│ │ └── examples.md
│ └── patterns/
│ ├── rule.md
│ └── examples.md
│
├── styling/ # CSS/Styling
│ ├── approach/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── naming/
│ │ ├── rule.md
│ │ └── examples.md
│ └── responsive/
│ ├── rule.md
│ └── examples.md
│
├── data_fetching/ # Data fetching
│ ├── patterns/
│ │ ├── rule.md
│ │ └── examples.md
│ └── error_handling/
│ ├── rule.md
│ └── examples.md
│
└── routing/ # Routing
├── structure/
│ ├── rule.md
│ └── examples.md
└── navigation/
├── rule.md
└── examples.mddocs/rules/code/front/
├── components/ # 组件模式
│ ├── composition/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── props/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── naming/
│ │ ├── rule.md
│ │ └── examples.md
│ └── file_structure/
│ ├── rule.md
│ └── examples.md
│
├── state/ # 状态管理
│ ├── local_state/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── context/
│ │ ├── rule.md
│ │ └── examples.md
│ └── derived_state/
│ ├── rule.md
│ └── examples.md
│
├── hooks/ # 自定义Hook
│ ├── naming/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── dependencies/
│ │ ├── rule.md
│ │ └── examples.md
│ └── patterns/
│ ├── rule.md
│ └── examples.md
│
├── styling/ # CSS/样式
│ ├── approach/
│ │ ├── rule.md
│ │ └── examples.md
│ ├── naming/
│ │ ├── rule.md
│ │ └── examples.md
│ └── responsive/
│ ├── rule.md
│ └── examples.md
│
├── data_fetching/ # 数据获取
│ ├── patterns/
│ │ ├── rule.md
│ │ └── examples.md
│ └── error_handling/
│ ├── rule.md
│ └── examples.md
│
└── routing/ # 路由
├── structure/
│ ├── rule.md
│ └── examples.md
└── navigation/
├── rule.md
└── examples.mdExample: docs/rules/code/front/components/composition/
示例:docs/rules/code/front/components/composition/
Component composition patterns.
组件组合模式。
rule.md
rule.md
markdown
undefinedmarkdown
undefinedRule: Component Composition
规则:组件组合
Summary
概述
Components MUST use composition over prop drilling for flexible, reusable designs.
为实现灵活、可复用的设计,组件必须优先使用组合而非属性透传。
Rationale
设计理由
Composition patterns:
- Reduce prop drilling
- Increase reusability
- Improve testability
- Enable flexible layouts
组合模式:
- 减少属性透传
- 提升复用性
- 增强可测试性
- 支持灵活布局
The Rules
具体规则
1. Prefer Children Over Props
1. 优先使用Children而非Props
SHOULD pass content via children rather than render props.
tsx
// PREFERRED
<Card>
<CardHeader>Title</CardHeader>
<CardBody>Content</CardBody>
</Card>
// AVOID
<Card
header={<span>Title</span>}
body={<span>Content</span>}
/>undefined应通过children传递内容,而非渲染属性。
tsx
// 推荐写法
<Card>
<CardHeader>Title</CardHeader>
<CardBody>Content</CardBody>
</Card>
// 避免写法
<Card
header={<span>Title</span>}
body={<span>Content</span>}
/>undefined2. Use Compound Components
2. 使用复合组件
SHOULD use compound component pattern for related components.
tsx
// CORRECT - compound components
<Select>
<Select.Option value="a">Option A</Select.Option>
<Select.Option value="b">Option B</Select.Option>
</Select>
// AVOID - array of objects
<Select options={[
{ value: 'a', label: 'Option A' },
{ value: 'b', label: 'Option B' },
]} />应为关联组件使用复合组件模式。
tsx
// 正确写法 - 复合组件
<Select>
<Select.Option value="a">Option A</Select.Option>
<Select.Option value="b">Option B</Select.Option>
</Select>
// 避免写法 - 对象数组形式
<Select options={[
{ value: 'a', label: 'Option A' },
{ value: 'b', label: 'Option B' },
]} />3. Avoid Prop Drilling
3. 避免属性透传
MUST NOT pass props more than 2 levels deep. Use context or composition.
tsx
// BAD - prop drilling
<App user={user}>
<Layout user={user}>
<Header user={user}>
<UserMenu user={user} /> // 4 levels!
</Header>
</Layout>
</App>
// GOOD - context
<UserProvider user={user}>
<App>
<Layout>
<Header>
<UserMenu /> // Uses useUser()
</Header>
</Layout>
</App>
</UserProvider>严禁将属性透传超过2层。应使用Context或组合模式替代。
tsx
// 错误写法 - 属性透传
<App user={user}>
<Layout user={user}>
<Header user={user}>
<UserMenu user={user} /> // 透传了4层!
</Header>
</Layout>
</App>
// 推荐写法 - Context
<UserProvider user={user}>
<App>
<Layout>
<Header>
<UserMenu /> // 使用useUser()获取
</Header>
</Layout>
</App>
</UserProvider>4. Single Responsibility
4. 单一职责
Each component MUST have one clear purpose.
- Display components: render UI
- Container components: manage state/data
- Layout components: arrange children
每个组件必须只有一个明确的职责。
- 展示组件:负责渲染UI
- 容器组件:负责管理状态/数据
- 布局组件:负责排列子组件
Examples
示例
Correct: Flexible Card Component
正确示例:灵活的Card组件
tsx
// Compound component pattern
const Card = ({ children, className }: CardProps) => (
<div className={cn("card", className)}>{children}</div>
);
Card.Header = ({ children }: { children: ReactNode }) => (
<div className="card-header">{children}</div>
);
Card.Body = ({ children }: { children: ReactNode }) => (
<div className="card-body">{children}</div>
);
Card.Footer = ({ children }: { children: ReactNode }) => (
<div className="card-footer">{children}</div>
);
// Usage - flexible composition
<Card>
<Card.Header>
<h2>Title</h2>
<IconButton icon="close" />
</Card.Header>
<Card.Body>
<p>Any content here</p>
</Card.Body>
</Card>;tsx
// 复合组件模式
const Card = ({ children, className }: CardProps) => (
<div className={cn("card", className)}>{children}</div>
);
Card.Header = ({ children }: { children: ReactNode }) => (
<div className="card-header">{children}</div>
);
Card.Body = ({ children }: { children: ReactNode }) => (
<div className="card-body">{children}</div>
);
Card.Footer = ({ children }: { children: ReactNode }) => (
<div className="card-footer">{children}</div>
);
// 使用方式 - 灵活组合
<Card>
<Card.Header>
<h2>Title</h2>
<IconButton icon="close" />
</Card.Header>
<Card.Body>
<p>可放置任意内容</p>
</Card.Body>
</Card>;Incorrect: Inflexible Props-Based
错误示例:灵活性不足的Props写法
tsx
// BAD - limited flexibility
interface CardProps {
title: string;
subtitle?: string;
body: string;
footer?: string;
showCloseButton?: boolean;
onClose?: () => void;
headerIcon?: ReactNode;
// Props multiply as requirements grow...
}
const Card = ({ title, subtitle, body, ... }: CardProps) => (
// Complex conditional rendering
);tsx
// 错误写法 - 灵活性受限
interface CardProps {
title: string;
subtitle?: string;
body: string;
footer?: string;
showCloseButton?: boolean;
onClose?: () => void;
headerIcon?: ReactNode;
// 需求增长时,Props会不断增加...
}
const Card = ({ title, subtitle, body, ... }: CardProps) => (
// 复杂的条件渲染
);Enforcement
落地执行
- Code review checklist
- ESLint custom rules for prop drilling detection
---- 代码审查检查清单
- 自定义ESLint规则检测属性透传
---Example: docs/rules/code/front/state/local_state/
示例:docs/rules/code/front/state/local_state/
Local state management rules.
本地状态管理规则。
rule.md
rule.md
markdown
undefinedmarkdown
undefinedRule: Local State Management
规则:本地状态管理
Summary
概述
Component state MUST be kept as local as possible and lifted only when necessary.
组件状态必须尽可能保持本地化,仅在必要时才向上提升。
Rationale
设计理由
Local state:
- Improves performance (fewer re-renders)
- Reduces complexity
- Makes components self-contained
- Easier to test
本地状态:
- 提升性能(减少重渲染次数)
- 降低复杂度
- 使组件具备独立性
- 更易于测试
The Rules
具体规则
1. Start Local
1. 从本地状态开始
MUST start with local state and lift only when needed.
tsx
// START HERE - local state
const [count, setCount] = useState(0);
// LIFT when siblings need it
// LIFT when parent needs it
// LIFT when distant components need it必须先使用本地状态,仅在需要时再向上提升。
tsx
// 初始写法 - 本地状态
const [count, setCount] = useState(0);
// 当兄弟组件需要时再提升
// 当父组件需要时再提升
// 当跨层级组件需要时再提升2. Colocation
2. 就近原则
MUST keep state close to where it's used.
tsx
// CORRECT - state in component that uses it
function SearchInput() {
const [query, setQuery] = useState("");
return <input value={query} onChange={(e) => setQuery(e.target.value)} />;
}
// INCORRECT - state lifted unnecessarily
function App() {
const [searchQuery, setSearchQuery] = useState("");
return <SearchInput query={searchQuery} setQuery={setSearchQuery} />;
}必须将状态放在其使用位置附近。
tsx
// 正确写法 - 状态在使用它的组件中
function SearchInput() {
const [query, setQuery] = useState("");
return <input value={query} onChange={(e) => setQuery(e.target.value)} />;
}
// 错误写法 - 不必要的状态提升
function App() {
const [searchQuery, setSearchQuery] = useState("");
return <SearchInput query={searchQuery} setQuery={setSearchQuery} />;
}3. Derive Don't Duplicate
3. 推导而非复制
MUST derive state from existing state rather than duplicating.
tsx
// CORRECT - derived
const [items, setItems] = useState<Item[]>([]);
const completedCount = items.filter((i) => i.completed).length;
// INCORRECT - duplicated state
const [items, setItems] = useState<Item[]>([]);
const [completedCount, setCompletedCount] = useState(0);
// Now you have to keep them in sync!必须从现有状态推导新状态,而非复制状态。
tsx
// 正确写法 - 推导状态
const [items, setItems] = useState<Item[]>([]);
const completedCount = items.filter((i) => i.completed).length;
// 错误写法 - 重复状态
const [items, setItems] = useState<Item[]>([]);
const [completedCount, setCompletedCount] = useState(0);
// 现在你需要手动保持两者同步!4. Use Appropriate Hook
4. 使用合适的Hook
| Scenario | Hook |
|---|---|
| Simple value | |
| Complex object with many updates | |
| Previous value needed | |
| Derived async data | |
| 场景 | Hook |
|---|---|
| 简单值 | |
| 包含多个更新操作的复杂对象 | |
| 需要获取之前的值 | |
| 异步推导数据 | |
Examples
示例
Correct: Appropriate State Location
正确示例:状态位置合理
tsx
// Form with local state
function ContactForm() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
// Derived state
const isValid = name.length > 0 && email.includes("@");
return (
<form>
<input value={name} onChange={(e) => setName(e.target.value)} />
<input value={email} onChange={(e) => setEmail(e.target.value)} />
<textarea value={message} onChange={(e) => setMessage(e.target.value)} />
<button disabled={!isValid}>Submit</button>
</form>
);
}tsx
// 带本地状态的表单
function ContactForm() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
// 推导状态
const isValid = name.length > 0 && email.includes("@");
return (
<form>
<input value={name} onChange={(e) => setName(e.target.value)} />
<input value={email} onChange={(e) => setEmail(e.target.value)} />
<textarea value={message} onChange={(e) => setMessage(e.target.value)} />
<button disabled={!isValid}>提交</button>
</form>
);
}Correct: useReducer for Complex State
正确示例:使用useReducer处理复杂状态
tsx
type State = {
items: Item[];
filter: "all" | "active" | "completed";
editingId: string | null;
};
type Action =
| { type: "ADD_ITEM"; payload: Item }
| { type: "TOGGLE_ITEM"; payload: string }
| { type: "SET_FILTER"; payload: State["filter"] }
| { type: "START_EDITING"; payload: string };
function reducer(state: State, action: Action): State {
switch (action.type) {
case "ADD_ITEM":
return { ...state, items: [...state.items, action.payload] };
// ... other cases
}
}
function TodoList() {
const [state, dispatch] = useReducer(reducer, initialState);
// ...
}tsx
type State = {
items: Item[];
filter: "all" | "active" | "completed";
editingId: string | null;
};
type Action =
| { type: "ADD_ITEM"; payload: Item }
| { type: "TOGGLE_ITEM"; payload: string }
| { type: "SET_FILTER"; payload: State["filter"] }
| { type: "START_EDITING"; payload: string };
function reducer(state: State, action: Action): State {
switch (action.type) {
case "ADD_ITEM":
return { ...state, items: [...state.items, action.payload] };
// ... 其他case
}
}
function TodoList() {
const [state, dispatch] = useReducer(reducer, initialState);
// ...
}Enforcement
落地执行
- Code review
- ESLint react-hooks/exhaustive-deps
---- 代码审查
- ESLint规则react-hooks/exhaustive-deps
---Example: docs/rules/code/front/hooks/naming/
示例:docs/rules/code/front/hooks/naming/
Custom hook naming rules.
自定义Hook命名规则。
rule.md
rule.md
markdown
undefinedmarkdown
undefinedRule: Custom Hook Naming
规则:自定义Hook命名
Summary
概述
Custom hooks MUST be named with prefix and describe their purpose.
use自定义Hook必须以为前缀,并清晰描述其用途。
useRationale
设计理由
Consistent naming:
- Enables React's hooks linting
- Communicates purpose clearly
- Follows React conventions
- Makes hooks discoverable
统一命名:
- 支持React的Hook语法检查
- 清晰传达Hook用途
- 遵循React约定
- 便于Hook的发现和使用
The Rules
具体规则
1. Use Prefix Required
1. 必须使用use前缀
MUST start with followed by PascalCase description.
usetypescript
// CORRECT
useUserData
useLocalStorage
useDebounce
useCreatureList
// INCORRECT
getUserData // Not a hook name
UseUserData // Wrong case
use_user_data // Wrong format必须以开头,后跟大驼峰式描述。
usetypescript
// 正确写法
useUserData
useLocalStorage
useDebounce
useCreatureList
// 错误写法
getUserData // 不是Hook命名方式
UseUserData // 大小写错误
use_user_data // 格式错误2. Describe the Data or Action
2. 描述数据或操作
SHOULD name after what it returns or does.
| Hook Returns | Name Pattern |
|---|---|
| User data | |
| List of items | |
| Boolean state | |
| Toggle function | |
| Async operation | |
应根据Hook返回的内容或执行的操作命名。
| Hook返回内容 | 命名模式 |
|---|---|
| 用户数据 | |
| 项目列表 | |
| 布尔状态 | |
| 切换函数 | |
| 异步操作 | |
3. File Naming
3. 文件命名
MUST match file name to hook name in kebab-case.
hooks/
use-user-data.ts -> export function useUserData()
use-local-storage.ts -> export function useLocalStorage()
use-debounce.ts -> export function useDebounce()必须使文件名与Hook名称匹配,采用短横线分隔式(kebab-case)。
hooks/
use-user-data.ts -> export function useUserData()
use-local-storage.ts -> export function useLocalStorage()
use-debounce.ts -> export function useDebounce()Examples
示例
Correct
正确示例
typescript
// use-creature-data.ts
export function useCreatureData(slug: string) {
const [creature, setCreature] = useState<Creature | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetchCreature(slug)
.then(setCreature)
.finally(() => setIsLoading(false));
}, [slug]);
return { creature, isLoading };
}
// use-toggle.ts
export function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = useCallback(() => setValue((v) => !v), []);
const setTrue = useCallback(() => setValue(true), []);
const setFalse = useCallback(() => setValue(false), []);
return { value, toggle, setTrue, setFalse };
}typescript
// use-creature-data.ts
export function useCreatureData(slug: string) {
const [creature, setCreature] = useState<Creature | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetchCreature(slug)
.then(setCreature)
.finally(() => setIsLoading(false));
}, [slug]);
return { creature, isLoading };
}
// use-toggle.ts
export function useToggle(initial = false) {
const [value, setValue] = useState(initial);
const toggle = useCallback(() => setValue((v) => !v), []);
const setTrue = useCallback(() => setValue(true), []);
const setFalse = useCallback(() => setValue(false), []);
return { value, toggle, setTrue, setFalse };
}Incorrect
错误示例
typescript
// BAD - not descriptive
export function useData() { ... }
// BAD - wrong prefix
export function fetchUserData() { ... } // Looks like regular function
// BAD - file mismatch
// File: userData.ts
export function useUserData() { ... } // Should be use-user-data.tstypescript
// 错误写法 - 描述不清晰
export function useData() { ... }
// 错误写法 - 前缀错误
export function fetchUserData() { ... } // 看起来像普通函数
// 错误写法 - 文件与Hook名称不匹配
// 文件: userData.ts
export function useUserData() { ... } // 应为use-user-data.tsEnforcement
落地执行
- ESLint react-hooks/rules-of-hooks
- File naming linter
---- ESLint规则react-hooks/rules-of-hooks
- 文件命名检查工具
---Example: docs/rules/code/front/styling/approach/
示例:docs/rules/code/front/styling/approach/
Styling approach rules.
样式方案规则。
rule.md
rule.md
markdown
undefinedmarkdown
undefinedRule: Styling Approach
规则:样式方案
Summary
概述
Projects MUST use a consistent styling approach and SHOULD prefer CSS-in-JS or utility classes.
项目必须使用统一的样式方案,且应优先选择CSS-in-JS或工具类方案。
Rationale
设计理由
Consistent styling:
- Reduces context switching
- Enables type-safe styles
- Improves maintainability
- Colocates styles with components
统一的样式方案:
- 减少上下文切换
- 支持类型安全的样式
- 提升可维护性
- 样式与组件就近存放
The Rules
具体规则
1. Choose One Approach
1. 选择一种方案
MUST use one primary styling approach per project:
| Approach | When to Use |
|---|---|
| Tailwind CSS | Utility-first, rapid development |
| CSS Modules | Scoped CSS, traditional CSS knowledge |
| styled-components | Component-based, dynamic styles |
| Vanilla Extract | Type-safe, zero runtime |
必须为每个项目选择一种主要的样式方案:
| 方案 | 适用场景 |
|---|---|
| Tailwind CSS | 工具类优先,快速开发 |
| CSS Modules | 作用域CSS,适合熟悉传统CSS的团队 |
| styled-components | 组件级样式,支持动态样式 |
| Vanilla Extract | 类型安全,零运行时 |
2. Consistent Application
2. 统一应用
MUST apply chosen approach consistently across all components.
必须在所有组件中一致地应用所选方案。
3. Component-Scoped Styles
3. 组件作用域样式
MUST NOT use global styles except for:
- CSS reset/normalize
- CSS variables (design tokens)
- Base typography
严禁使用全局样式,以下场景除外:
- CSS重置/标准化样式
- CSS变量(设计令牌)
- 基础排版
4. Design Tokens
4. 设计令牌
SHOULD use design tokens for colors, spacing, typography.
tsx
// CORRECT - using tokens
<div className="p-4 bg-primary text-white" />
<div style={{ padding: tokens.spacing.md }} />
// INCORRECT - magic values
<div style={{ padding: '16px', backgroundColor: '#3b82f6' }} />应使用设计令牌定义颜色、间距、排版等样式属性。
tsx
// 正确写法 - 使用令牌
<div className="p-4 bg-primary text-white" />
<div style={{ padding: tokens.spacing.md }} />
// 错误写法 - 魔法值
<div style={{ padding: '16px', backgroundColor: '#3b82f6' }} />Examples
示例
Tailwind CSS Approach
Tailwind CSS方案
tsx
// Component with Tailwind
function Card({ title, children }: CardProps) {
return (
<div className="rounded-lg border border-gray-200 bg-white p-4 shadow-sm">
<h2 className="mb-2 text-lg font-semibold text-gray-900">{title}</h2>
<div className="text-gray-600">{children}</div>
</div>
);
}
// With cn() for conditional classes
function Button({ variant, children }: ButtonProps) {
return (
<button
className={cn(
"rounded px-4 py-2 font-medium transition-colors",
variant === "primary" && "bg-blue-500 text-white hover:bg-blue-600",
variant === "secondary" &&
"bg-gray-200 text-gray-900 hover:bg-gray-300",
)}
>
{children}
</button>
);
}tsx
// 使用Tailwind的组件
function Card({ title, children }: CardProps) {
return (
<div className="rounded-lg border border-gray-200 bg-white p-4 shadow-sm">
<h2 className="mb-2 text-lg font-semibold text-gray-900">{title}</h2>
<div className="text-gray-600">{children}</div>
</div>
);
}
// 使用cn()处理条件类名
function Button({ variant, children }: ButtonProps) {
return (
<button
className={cn(
"rounded px-4 py-2 font-medium transition-colors",
variant === "primary" && "bg-blue-500 text-white hover:bg-blue-600",
variant === "secondary" &&
"bg-gray-200 text-gray-900 hover:bg-gray-300",
)}
>
{children}
</button>
);
}CSS Modules Approach
CSS Modules方案
tsx
// Card.module.css
.card {
border-radius: var(--radius-lg);
border: 1px solid var(--color-border);
padding: var(--spacing-md);
}
.title {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-semibold);
}
// Card.tsx
import styles from './Card.module.css';
function Card({ title, children }: CardProps) {
return (
<div className={styles.card}>
<h2 className={styles.title}>{title}</h2>
{children}
</div>
);
}tsx
// Card.module.css
.card {
border-radius: var(--radius-lg);
border: 1px solid var(--color-border);
padding: var(--spacing-md);
}
.title {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-semibold);
}
// Card.tsx
import styles from './Card.module.css';
function Card({ title, children }: CardProps) {
return (
<div className={styles.card}>
<h2 className={styles.title}>{title}</h2>
{children}
</div>
);
}Enforcement
落地执行
- ESLint Tailwind plugin (if using Tailwind)
- Code review
---- ESLint Tailwind插件(若使用Tailwind)
- 代码审查
---Creating Frontend Rules
创建前端规则
mermaid
flowchart TD
A[Identify Pattern] --> B{Category}
B -->|Components| C[components/]
B -->|State| D[state/]
B -->|Hooks| E[hooks/]
B -->|Styling| F[styling/]
B -->|Data| G[data_fetching/]
B -->|Routes| H[routing/]
C --> I[Create Rule Folder]
D --> I
E --> I
F --> I
G --> I
H --> I
I --> J[Write rule.md]
J --> K[Add examples.md]
K --> L[Configure ESLint if applicable]
L --> M[Add to review checklist]mermaid
flowchart TD
A[识别模式] --> B{分类}
B -->|组件| C[components/]
B -->|状态| D[state/]
B -->|Hook| E[hooks/]
B -->|样式| F[styling/]
B -->|数据| G[data_fetching/]
B -->|路由| H[routing/]
C --> I[创建规则目录]
D --> I
E --> I
F --> I
G --> I
H --> I
I --> J[编写rule.md]
J --> K[添加examples.md]
K --> L[配置ESLint(如适用)]
L --> M[加入审查检查清单]Signal Files Reference
标识文件参考
| Signal | Content | Purpose |
|---|---|---|
| JSON | Schema version |
| List | Tools that enforce |
| Rule name | ESLint rule if applicable |
| Version | React version requirement |
| 标识文件 | 内容格式 | 用途 |
|---|---|---|
| JSON | 架构版本 |
| 列表 | 执行工具集合 |
| 规则名称 | 对应的ESLint规则(如适用) |
| 版本号 | React版本要求 |
Frontend Rule Checklist
前端规则检查清单
- Rule is React/frontend specific
- Examples use TypeScript + React
- Shows correct and incorrect patterns
- Mentions relevant ESLint rules
- Considers React best practices
- References React documentation if applicable
- Performance implications noted
- 规则为React/前端专属
- 示例使用TypeScript + React
- 展示正确和错误的模式
- 提及相关的ESLint规则
- 考虑React最佳实践
- 如适用,参考React官方文档
- 标注性能影响