Cursor rule
.cursor/rules/naming.mdc[object Object]
Cursor rules
Quality
58/100
Scores the file, not the repository.Length
1,843 words
47 headings · 21 code blocksRepository
0
— · pushed 377 days agoLast changed
3 days ago
First indexed 3 days ago.123456# SoybeanAdmin React 命名规范78## 概述910本文档定义了 SoybeanAdmin React 项目的命名规范,旨在确保代码的一致性、可读性和可维护性。所有团队成员都应严格遵循这些规范。1112## 文件和目录命名1314### 📁 目录命名规范1516**规则:统一使用小写字母 + 连字符(kebab-case)**1718```bash19# ✅ 正确示例20src/21├── components/22├── pages/23├── user-center/24├── role-manage/25├── global-header/26├── theme-drawer/27├── multi-menu/28└── system-config/2930# ❌ 错误示例31src/32├── userCenter/ # 不使用 camelCase33├── RoleManage/ # 不使用 PascalCase34├── global_header/ # 不使用 snake_case35└── SYSTEM_CONFIG/ # 不使用 UPPER_CASE36```3738### 📄 文件命名规范3940#### React 组件文件41- **页面组件**:`index.tsx`42- **动态路由**:`[id].tsx`、`[...slug].tsx`43- **布局组件**:`layout.tsx`44- **异步状态组件**:`loading.tsx`、`error.tsx`45- **普通组件**:使用 PascalCase,如 `UserProfile.tsx`4647```bash48# ✅ 正确示例49components/50├── UserProfile.tsx51├── GlobalHeader.tsx52├── ThemeDrawer.tsx53└── DataTable.tsx5455pages/56├── index.tsx57├── [id].tsx58├── [...slug].tsx59├── layout.tsx60├── loading.tsx61└── error.tsx6263# ❌ 错误示例64components/65├── userProfile.tsx # 不使用 camelCase66├── global-header.tsx # 不使用 kebab-case67└── THEME_DRAWER.tsx # 不使用 UPPER_CASE68```6970#### 其他文件类型71```bash72# ✅ 样式文件73styles/74├── global.scss75├── user-card.module.scss76└── theme-config.css7778# ✅ 工具文件79utils/80├── common.ts81├── date-format.ts82└── api-helper.ts8384# ✅ 类型文件85types/86├── api.d.ts87├── user-info.d.ts88└── common.d.ts8990# ✅ 配置文件91config/92├── app-config.ts93├── theme-config.ts94└── router-config.ts95```9697## JavaScript/TypeScript 命名9899### 🔤 变量命名100101**规则:使用 camelCase**102103```typescript104// ✅ 正确示例105const userName = 'admin';106const userAge = 25;107const isLoading = false;108const hasPermission = true;109const userList = [];110const currentUser = null;111const pageConfig = {};112113// ❌ 错误示例114const user_name = 'admin'; // 不使用 snake_case115const UserAge = 25; // 不使用 PascalCase116const is_loading = false; // 不使用 snake_case117const HAS_PERMISSION = true; // 不使用 UPPER_CASE118```119120### 🔧 函数命名121122**规则:使用 camelCase,动词开头**123124```typescript125// ✅ 正确示例126function getUserInfo() {}127function handleClick() {}128function validateForm() {}129function formatDate() {}130function checkPermission() {}131function toggleTheme() {}132function calculateTotal() {}133function renderComponent() {}134135// ❌ 错误示例136function GetUserInfo() {} // 不使用 PascalCase137function handle_click() {} // 不使用 snake_case138function user_info() {} // 缺少动词139function VALIDATE_FORM() {} // 不使用 UPPER_CASE140```141142### 📦 常量命名143144**规则:使用 UPPER_SNAKE_CASE**145146```typescript147// ✅ 正确示例148const MAX_RETRY_COUNT = 3;149const API_BASE_URL = 'https://api.example.com';150const DEFAULT_PAGE_SIZE = 20;151const STORAGE_KEYS = {152 USER_TOKEN: 'user_token',153 THEME_CONFIG: 'theme_config',154 LANGUAGE: 'language'155};156157const HTTP_STATUS = {158 SUCCESS: 200,159 NOT_FOUND: 404,160 SERVER_ERROR: 500161} as const;162163// ❌ 错误示例164const maxRetryCount = 3; // 不使用 camelCase 表示常量165const apiBaseUrl = 'https://...'; // 不使用 camelCase 表示常量166const Max_Retry_Count = 3; // 混合命名风格167```168169### 🏗️ 类型和接口命名170171**规则:使用 PascalCase**172173```typescript174// ✅ 正确示例 - 接口175interface UserInfo {176 id: string;177 name: string;178 email: string;179}180181interface ApiResponse<T> {182 code: number;183 message: string;184 data: T;185}186187interface ComponentProps {188 title: string;189 visible?: boolean;190 onClose?: () => void;191}192193// ✅ 正确示例 - 类型别名194type Theme = 'light' | 'dark';195type UserRole = 'admin' | 'user' | 'guest';196type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';197198// ✅ 正确示例 - 泛型199type Partial<T> = {200 [P in keyof T]?: T[P];201};202203type ApiResult<T = any> = {204 success: boolean;205 data: T;206 error?: string;207};208209// ❌ 错误示例210interface userInfo {} // 不使用 camelCase211interface api_response {} // 不使用 snake_case212interface COMPONENT_PROPS {} // 不使用 UPPER_CASE213type theme = 'light' | 'dark'; // 不使用 camelCase214```215216### 🏛️ 类命名217218**规则:使用 PascalCase**219220```typescript221// ✅ 正确示例222class UserService {223 private apiClient: ApiClient;224225 constructor(apiClient: ApiClient) {226 this.apiClient = apiClient;227 }228}229230class HttpClient {231 private baseURL: string;232233 get(url: string) {}234 post(url: string, data: any) {}235}236237class ValidationError extends Error {238 constructor(message: string) {239 super(message);240 this.name = 'ValidationError';241 }242}243244// ❌ 错误示例245class userService {} // 不使用 camelCase246class http_client {} // 不使用 snake_case247class VALIDATION_ERROR {} // 不使用 UPPER_CASE248```249250### 🔗 枚举命名251252**规则:枚举名使用 PascalCase,成员使用 PascalCase**253254```typescript255// ✅ 正确示例256enum UserRole {257 Admin = 'admin',258 User = 'user',259 Guest = 'guest'260}261262enum RequestStatus {263 Pending = 'pending',264 Success = 'success',265 Failed = 'failed'266}267268enum ThemeMode {269 Light = 'light',270 Dark = 'dark',271 Auto = 'auto'272}273274// ❌ 错误示例275enum userRole { // 不使用 camelCase276 ADMIN = 'admin', // 不使用 UPPER_CASE 成员277 USER = 'user'278}279280enum REQUEST_STATUS { // 不使用 UPPER_CASE 枚举名281 pending = 'pending', // 不使用 camelCase 成员282 success = 'success'283}284```285286## React 组件命名287288### 🧩 组件命名规范289290**规则:使用 PascalCase**291292```typescript293// ✅ 正确示例294const UserProfile: React.FC = () => {295 return <div>User Profile</div>;296};297298const GlobalHeader: React.FC = () => {299 return <header>Global Header</header>;300};301302const DataTable: React.FC<DataTableProps> = ({ data }) => {303 return <table>{/* table content */}</table>;304};305306const ThemeDrawer: React.FC = () => {307 return <div>Theme Drawer</div>;308};309310// ❌ 错误示例311const userProfile = () => {}; // 不使用 camelCase312const global_header = () => {}; // 不使用 snake_case313const DATA_TABLE = () => {}; // 不使用 UPPER_CASE314```315316### 🏷️ Props 接口命名317318**规则:组件名 + Props 后缀**319320```typescript321// ✅ 正确示例322interface UserProfileProps {323 user: UserInfo;324 onEdit?: (user: UserInfo) => void;325 onDelete?: (id: string) => void;326}327328interface DataTableProps<T = any> {329 data: T[];330 columns: ColumnConfig[];331 loading?: boolean;332 onRowClick?: (record: T) => void;333}334335interface ModalProps {336 visible: boolean;337 title: string;338 children: React.ReactNode;339 onCancel: () => void;340 onConfirm: () => void;341}342343// ❌ 错误示例344interface UserProfileProperties {} // 不使用完整的 Props345interface userProfileProps {} // 不使用 PascalCase346interface UserProfile_Props {} // 不使用下划线347```348349### 🎯 事件处理函数命名350351**规则:handle + 动作名称**352353```typescript354// ✅ 正确示例355const UserCard: React.FC<UserCardProps> = ({ user, onEdit, onDelete }) => {356 const handleEdit = () => {357 onEdit?.(user);358 };359360 const handleDelete = () => {361 if (window.confirm('确认删除?')) {362 onDelete?.(user.id);363 }364 };365366 const handleSubmit = (event: React.FormEvent) => {367 event.preventDefault();368 // 处理提交逻辑369 };370371 const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {372 setValue(event.target.value);373 };374375 return (376 <div>377 <button onClick={handleEdit}>编辑</button>378 <button onClick={handleDelete}>删除</button>379 </div>380 );381};382383// ❌ 错误示例384const onEditClick = () => {}; // 不使用 handle 前缀385const deleteHandler = () => {}; // 不使用 handle 前缀386const HandleEdit = () => {}; // 不使用 PascalCase387const handle_delete = () => {}; // 不使用 snake_case388```389390## Hook 命名规范391392### 🪝 自定义 Hook 命名393394**规则:use + 功能描述(PascalCase)**395396```typescript397// ✅ 正确示例398const useUserInfo = (userId: string) => {399 const [user, setUser] = useState<UserInfo | null>(null);400 const [loading, setLoading] = useState(false);401402 useEffect(() => {403 fetchUserById(userId).then(setUser);404 }, [userId]);405406 return { user, loading };407};408409const useLocalStorage = <T>(key: string, defaultValue: T) => {410 const [value, setValue] = useState<T>(() => {411 const stored = localStorage.getItem(key);412 return stored ? JSON.parse(stored) : defaultValue;413 });414415 return [value, setValue] as const;416};417418const useDebounce = <T>(value: T, delay: number) => {419 const [debouncedValue, setDebouncedValue] = useState(value);420421 useEffect(() => {422 const handler = setTimeout(() => {423 setDebouncedValue(value);424 }, delay);425426 return () => clearTimeout(handler);427 }, [value, delay]);428429 return debouncedValue;430};431432// ❌ 错误示例433const userInfo = () => {}; // 缺少 use 前缀434const getUserInfo = () => {}; // 不是 Hook,应该是普通函数435const useuser_info = () => {}; // 不使用 snake_case436const USE_USER_INFO = () => {}; // 不使用 UPPER_CASE437```438439## API 和服务命名440441### 🌐 API 函数命名442443**规则:fetch + 资源名称(PascalCase)**444445```typescript446// ✅ 正确示例447export const fetchUserList = (params: UserListParams) => {448 return request<UserListResponse>({449 url: '/user/list',450 method: 'GET',451 params,452 });453};454455export const fetchUserById = (id: string) => {456 return request<UserInfo>({457 url: `/user/${id}`,458 method: 'GET',459 });460};461462export const createUser = (data: CreateUserData) => {463 return request<ApiResponse>({464 url: '/user',465 method: 'POST',466 data,467 });468};469470export const updateUser = (id: string, data: UpdateUserData) => {471 return request<ApiResponse>({472 url: `/user/${id}`,473 method: 'PUT',474 data,475 });476};477478export const deleteUser = (id: string) => {479 return request<ApiResponse>({480 url: `/user/${id}`,481 method: 'DELETE',482 });483};484485// ❌ 错误示例486export const getUserList = () => {}; // 不使用 fetch 前缀487export const fetch_user_list = () => {}; // 不使用 snake_case488export const FETCH_USER_LIST = () => {}; // 不使用 UPPER_CASE489export const userListApi = () => {}; // 不清晰的命名490```491492### 🏢 服务类命名493494**规则:资源名称 + Service 后缀**495496```typescript497// ✅ 正确示例498class UserService {499 async getList(params: UserListParams) {500 return fetchUserList(params);501 }502503 async getById(id: string) {504 return fetchUserById(id);505 }506507 async create(data: CreateUserData) {508 return createUser(data);509 }510}511512class AuthService {513 async login(credentials: LoginCredentials) {514 return request('/auth/login', { method: 'POST', data: credentials });515 }516517 async logout() {518 return request('/auth/logout', { method: 'POST' });519 }520}521522// ❌ 错误示例523class userService {} // 不使用 PascalCase524class User_Service {} // 不使用下划线525class USERSERVICE {} // 不使用 UPPER_CASE526class UserApi {} // 不使用 Service 后缀527```528529## 样式和CSS命名530531### 🎨 CSS 类名命名532533**规则:使用 kebab-case,遵循 BEM 规范**534535```scss536// ✅ 正确示例537.user-card {538 padding: 16px;539 border-radius: 8px;540541 &__header {542 display: flex;543 justify-content: space-between;544 margin-bottom: 12px;545546 &__title {547 font-size: 18px;548 font-weight: bold;549 }550551 &__actions {552 display: flex;553 gap: 8px;554 }555 }556557 &__content {558 color: #666;559 line-height: 1.5;560 }561562 &--active {563 border: 2px solid #1890ff;564 }565566 &--disabled {567 opacity: 0.5;568 pointer-events: none;569 }570}571572.data-table {573 width: 100%;574575 &__row {576 &:hover {577 background-color: #f5f5f5;578 }579580 &--selected {581 background-color: #e6f7ff;582 }583 }584}585586// ❌ 错误示例587.userCard {} // 不使用 camelCase588.user_card {} // 不使用 snake_case589.USER_CARD {} // 不使用 UPPER_CASE590.user-card-header-title {} // 不使用 BEM 规范591```592593### 🏷️ CSS Modules 命名594595```scss596// UserCard.module.scss597// ✅ 正确示例598.userCard {599 @apply bg-white rounded-lg shadow-md p-4;600601 .header {602 @apply flex items-center justify-between mb-4;603604 .title {605 @apply text-lg font-bold text-gray-800;606 }607608 .actions {609 @apply flex gap-2;610 }611 }612613 .content {614 @apply text-gray-600;615 }616617 .footer {618 @apply mt-4 pt-4 border-t border-gray-200;619 }620}621622// ❌ 错误示例623.user-card {} // CSS modules 中不使用 kebab-case624.user_card {} // 不使用 snake_case625.USER_CARD {} // 不使用 UPPER_CASE626```627628## 图标命名规范629630### 🎯 Iconify 图标使用631632**规则:使用 kebab-case,遵循 iconify 规范**633634```tsx635// ✅ 正确示例636<IconMdiHome />637<iconTablerSearch />638639640// ❌ 错误示例641<icon-carbon-settings /> // 不使用 kebab-case642<icon_mdi_home /> // 不使用 snake_case643<ICON-MDI-HOME /> // 不使用 UPPER_CASE644```645646### 🖼️ 本地 SVG 图标647648```bash649# ✅ 正确示例650src/assets/svg-icon/651├── arrow-left.svg652├── arrow-right.svg653├── user-circle.svg654├── settings-gear.svg655└── notification-bell.svg656657# ❌ 错误示例658src/assets/svg-icon/659├── arrowLeft.svg # 不使用 camelCase660├── arrow_right.svg # 不使用 snake_case661├── USERCIRCLE.svg # 不使用 UPPER_CASE662└── settings.Gear.svg # 不使用混合命名663```664665## 配置和环境变量666667### ⚙️ 环境变量命名668669**规则:使用 UPPER_SNAKE_CASE,项目前缀**670671```bash672# ✅ 正确示例673VITE_API_BASE_URL=https://api.example.com674VITE_APP_TITLE=SoybeanAdmin675VITE_APP_VERSION=1.0.0676VITE_ENABLE_MOCK=true677VITE_STORAGE_PREFIX=soybean_678VITE_DEFAULT_THEME=light679680# ❌ 错误示例681viteApiBaseUrl= # 不使用 camelCase682vite-api-base-url= # 不使用 kebab-case683ViteApiBaseUrl= # 不使用 PascalCase684```685686### 📋 配置对象命名687688```typescript689// ✅ 正确示例690export const appConfig = {691 name: 'SoybeanAdmin',692 version: '1.0.0',693 description: 'A fresh and elegant admin template'694};695696export const themeConfig = {697 defaultTheme: 'light' as const,698 enableDarkMode: true,699 primaryColor: '#1890ff'700};701702export const routeConfig = {703 homePath: '/home',704 loginPath: '/login',705 enableAuth: true706};707708// ❌ 错误示例709export const AppConfig = {}; // 不使用 PascalCase 用于对象710export const theme_config = {}; // 不使用 snake_case711export const ROUTE_CONFIG = {}; // 不使用 UPPER_CASE712```713714## 总结715716### 📝 命名规范速查表717718| 类型 | 规范 | 示例 |719|------|------|------|720| 文件/文件夹 | kebab-case | `user-center/`, `global-header.tsx` |721| React 组件 | PascalCase | `UserProfile`, `DataTable` |722| 变量/函数 | camelCase | `userName`, `getUserInfo()` |723| 常量 | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT`, `API_BASE_URL` |724| 类型/接口 | PascalCase | `UserInfo`, `ApiResponse<T>` |725| CSS 类名 | kebab-case (BEM) | `.user-card__header--active` |726| CSS Modules | camelCase | `.userCard`, `.headerTitle` |727| Hooks | use + PascalCase | `useUserInfo`, `useLocalStorage` |728| API 函数 | fetch + PascalCase | `fetchUserList`, `createUser` |729| 图标 | kebab-case | `<icon-mdi-home />` |730| 环境变量 | UPPER_SNAKE_CASE | `VITE_API_BASE_URL` |731732### ⚡ 最佳实践7337341. **保持一致性**:在整个项目中使用相同的命名约定7352. **语义化命名**:名称应该能清楚地表达其用途和含义7363. **避免缩写**:除非是公认的缩写,否则使用完整的单词7374. **使用英文**:所有命名都应该使用英文,避免中文拼音7385. **遵循约定**:优先使用团队和社区认可的命名约定739740遵循这些命名规范将有助于提高代码的可读性、可维护性和团队协作效率。741
Also in crunl/Xingyu-Frontend
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| crunl/Xingyu-Frontend.cursor/rules/api.mdc · 0 | Cursor rules | api | 45/100 | 3 days ago | |
| crunl/Xingyu-Frontend.cursor/rules/comments.mdc · 0 | Cursor rules | securityapidocs | 46/100 | 3 days ago | |
| crunl/Xingyu-Frontend.cursor/rules/componenting.mdc · 0 | Cursor rules | no sections | 45/100 | 3 days ago | |
| crunl/Xingyu-Frontend.cursor/rules/project.mdc · 0 | Cursor rules | no sections | 50/100 | 3 days ago | |
| crunl/Xingyu-Frontend.cursor/rules/reduxing.mdc · 0 | Cursor rules | no sections | 45/100 | 3 days ago | |
| crunl/Xingyu-Frontend.cursor/rules/routing.mdc · 0 | Cursor rules | no sections | 53/100 | 3 days ago | |
| crunl/Xingyu-Frontend.cursor/rules/styling.mdc · 0 | Cursor rules | archui | 54/100 | 3 days ago | |
| crunl/Xingyu-Frontend.cursor/rules/typescript.mdc · 0 | Cursor rules | typesdocs | 42/100 | 3 days ago |
Diff against .cursor/rules/api.mdc Diff against .cursor/rules/comments.mdc Diff against .cursor/rules/componenting.mdc Diff against .cursor/rules/project.mdc Diff against .cursor/rules/reduxing.mdc Diff against .cursor/rules/routing.mdc Diff against .cursor/rules/styling.mdc Diff against .cursor/rules/typescript.mdc
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 3 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 3 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 3 days ago |
