前端项目规范指南:提升代码质量与团队效率的秘诀

724 阅读9分钟

一、命名规范

1. 项目命名

全部采用小写方式,以中划线分隔。

bad:

cloud_music
needCode

good:

cloud-music
need-code

2. 目录命名

全部采用小写方式,以中划线分隔,有复数结构时,采用复数写法,缩写不用复数。

bad:

style / docs / img /demoStyles

good:

styles / doc / imgs / demo-styles 

3. 文件命名

全部采用小写形式,以中划线分隔。React 组件采用大驼峰写法(除了 index.tsx)。组件命名时需要能够直观的感受出当前组件的用途,组件命名始终是多个单词的,避免跟 html 元素或者标签冲突。 类型声明文件后缀为 .d.ts,统一放在项目的 types 文件夹或各自业务文件夹里面。

bad:

UserInfo.vue 
user-info.tsx
Icon.(tsx/vue)

User.ts
randomUtil.ts

good:

user-info.vue
base-icon.vue

UserInfo.tsx
BaseIcon.tsx
index.tsx

random-util.ts
element-ui.(less/scss)
utils.d.ts

cloud-logo.png

4. 路由命名

严格与页面文件命名一致。 多级路由嵌套不可超过三层。

5. JS 命名

(1) 语义化命名

在命名变量时要望文生义,能够让人一眼就能看出这个变量所代表的含义。命名时要使用英语命名,不允许出现拼音数字。

bad:

const a = '';
const yema = 5

good:

const orderNumber = 202408011734
const pageSize = 5;

(2) 命名规范

  • 变量命名:小驼峰命名 userInfo
  • 参数命名:小驼峰命名 pagepageSize
  • 函数命名:小驼峰命名 getUserInfo
  • 常量命名:全部大写字母 + 下划线 DEFAULT_PAGE_SIZE
  • 枚举命名:大驼峰命名 + Enum 结尾 HttpStatusEnum
  • TS类名:大驼峰命名 PageSizeProps

(3) 命名函数

命名函数遵循 A/HC/LC 模式

prefix? + action (A) + high context (HC) +   low context? (LC)
 前缀      动词/动作        强描述(主要内容)   低描述(辅助内容)

常用 action 动词

单词语意单词语意单词语意单词语意
add新建close关闭create创建delete删除
edit编辑encrypt加密fetch请求handle处理
modify修改open打开redo重做refresh刷新
remove移除reset重置revert复原save保存
set设置start开始undo撤销update更新

(4) 常见约定

  • 布尔值类型通常以 ishascanshould 开头
  • 数组/集合等复数形式通常以 sList 结尾

二、CSS 规范(默认使用预处理器)

1. 将嵌套深度限制在3级

避免嵌套层级过多,影响代码阅读。

2. 组织顺序

  • @import
  • 变量声明
  • 样式声明
@import "mixins/size.less"

@primary-color: #f00;

.title {
  color: @primary-color;
  .name {
    font-weight: bold;
  }
}

3. 其他规范

  • 省略小数点前面的0
  • 颜色代码简写
  • 尽量少用或不用元素选择器。

三、注释规范

注释插件:koroFileHeader

1. 单行注释

单行注释通常用于对代码中的某一行进行简短的说明。单行注释采用 //。 单行注释应该紧跟在代码的上一行或同一行的末尾,并且保持一个空格的距离。

bad:

//这是一个单行注释
const count = 1;// 计数器 

good:

// 这是一个单行注释
const count = 1; // 计数器

2. 多行注释

多行注释用于对多行代码进行详细说明,通常在注释中包含更多信息。多行注释采用 /*...*/

/*
* 这是一个多行注释
* 这是一个多行注释
*/

3. 函数注释(非强制)

函数注释通常采用 JSDoc 注释规范,它可以提高代码的可读性,帮助自己和他人快速理解函数代码,增强代码可维护性。

/**
 * 检查给定值的类型是否与指定的类型匹配。
 *
 * @param {unknown} val 要检查的值。
 * @param {string} type 目标类型的名称(如 "String", "Number", "Object" 等)。
 * @returns {boolean} 如果值的类型与指定类型匹配,则返回 true;否则返回 false。
 */
 const is = (val: unknown, type: string): boolean => {
  return toString.call(val) === `[object ${type}]`;
};

4. 文档注释

通用文件通常都要启用头部注释,用来描述这个文件的作用。

/*
 * @Author: 文件作者
 * @Date: 创建时间
 * @LastEditors: 最后修改人
 * @LastEditTime: 最后修改时间
 * @FilePath: 文件路径
 * @Description: 文件描述
 */

注释的【Author】不允许被删除,任何劳动成果都应该被尊重。

5. 特殊注释标记

注释高亮插件:better-comments、vscode-todo-highlight

  • TODO 表示代码中将来需要添加或者完成的功能。通常用来提醒开发者还有功能未实现
  • FIXME 指出代码中存在问题,需要修复优化。
  • HACK 指代码中的临时解决方案或者不够优雅的代码。
  • NOTE 用于强调代码中的某个特别重要的信息。
  • OPTIMIZE 提示代码的性能可以进一步优化。
  • REVIEW 表示代码需要额外的审查
  • DEPRECATED 表明代码已经过时,不应该被使用或将来会被移除。

使用这些标记可以帮助团队快速识别代码中的特定部分,不过也不能过度使用。应该定期进行代码审查清理这些标记。

四、React 项目规范

1. 组件规范

(1) 单文件行数限制

一个组件最大不能超过 500 行,超过后需要拆分。

(2) 组件命名

始终是多个单词组成(大于等于2)。

2. 编码规范

(1) 注释

写主要注释,对于简单易懂的代码不需要注释。太多注释反而影响代码可读性。

(2) 文件导入顺序

1. 与react相关的第三方包
   比如react、react-redux、react-router (按照包使用的先后顺序排序)
2. 其他第三方包
3. 组件库
   (1). chopperui-react
   (2). @ant-design/icons
   (3). 自定义组件
        ①. 公共组件    
        ②. 非公共组件
4. 常量
   (1). 全局常量
   (2). 局部常量
5. 方法
   (1). 工具方法
   (2). 其他文件中的方法
6. api
7. store
8. 图片
9. 样式

PS: 同类型的资源按照在文件中出现的先后顺序排序

(3) 编码顺序

1. 解构`props`(如果有)
2. react相关的第三方包中的钩子函数(除了useEffect)
3. 方法(跟api有关的方法放最后)
4. 内部组件
5. useEffect
   (1). 无依赖
   (2). 有依赖(按照调用的先后顺序排序)
   (3). 返回值是函数

(4) 编码规则

1. 没有子节点的组件,使用自闭合标签
2. 组件属性
   (1). 每个属性占一行
   (2). 属性值使用双引号,其余均使用单引号 
   (3). 属性值是字符串,则使用字面量复赋值 name='小前端'
   (4). 属性值如果是 true,则省略属性值,只写属性 disable
   (5). 属性在前,方法在后
   (6). 闭标签另起一行
3. 组件的 key 要使用有意义的变量,而不是数组下标等标识

五、Vue 项目规范

1. 组件规范

(1) 单文件行数限制

一个组件最大不能超过 500 行,超过后需要拆分。

(2) 组件命名

始终是多个单词组成(大于等于2)。

2. 编码规范

(1) 模板中使用简单表达式

bad:

<template>
  <p>
       {{
          fullName.split(' ').map(function (word) {
             return word[0].toUpperCase() + word.slice(1)
           }).join(' ')
        }}
  </p>
</template>

good:

<template>
  <p>{{ normalizedFullName }}</p>
</template>

// 复杂表达式已经移入一个计算属性
computed: {
  normalizedFullName: function () {
    return this.fullName.split(' ').map(function (word) {
      return word[0].toUpperCase() + word.slice(1)
    }).join(' ')
  }
}

(2) 指令都使用缩写

指令推荐都使用缩写形式,用 : 表示 v-bind:、用 @ 表示 v-on: 和用 # 表示 v-slot:

(3) 标签顺序保持一致

templatescriptstyle 顺序必须一致,之间空一行隔开。

<template>
 
</template>

<script setup lang="ts">

</script>

<style lang="less" scoped>

</style>

(4) 自闭合标签应省略闭合标签

bad:

<template>
  <MyComponent></MyComponent>
</template>

good:

<template>
  <MyComponent />
</template>

(5) 组件引用以 PascalCase 方式引用

采用 PascalCase 风格,具有较高可读性,同时避免跟现有的以及未来的 HTML 元素相冲突。

<template>
  <UserInfo />
</template>

<script>
import UserInfo from "UserInfo";
</script>

(6) 组件/实例编码顺序

1. components
2. props
3. data
4. computed
5. watch
6. filter
7. methods

六、Git 规范

1. 分支管理

  • PRO 环境:生产环境,用户实际使用的环境。代码需稳定,经过充分测试。

  • DEV 环境:开发环境,用于开发和测试新功能。开发人员在此环境中进行日常开发和调式。

  • FAT 环境:功能验收测试环境,用于在生产前验证新功能的完整性和可用性。通常由 QA 团队执行全面测试。

  • UAT 环境:用户验收测试环境,用户或业务部门在此环境中验证系统是否符合业务需求和预期。

    分支名称命名规范运行环境
    master主分支/PRO
    release预发布分支/UAT
    develop开发分支/FAT
    feature功能开发分支feat-xxxDEV
    hotfix热修复分支fix-xxxDEV
# master(主分支)
a. 用于部署到正式环境(PRO)
b. 仅从 release 分支合并,任何情况下不允许修改 master 分支代码 

# release(预发布分支)
a. 用于部署到预发布环境(UAT)
b. 从 develop 分支中创建,用于进行功能冻结和最终错误修复。
c. 命名格式为 release-xxx,其中 xxx 为版本号。
d. release 分支只能进行 bug 修复、版本号更新、文档更新等操作,不能新增功能。
e. 发布完成后,必须合并到 develop 和 master 分支。

# develop(开发分支)
a. 用于部署到测试环境(FAT)
b. 所有开发工作都在 develop 分支下进行。develop 分支只能从 master 分支中合并,不建议直接在 develop 分支上修改代码。

# feature(功能开发分支)
a. 从 develop 分支拉出来的功能分支,命名格式为 feat-xxx,其中 xxx 为功能或者任务ID。
b. 功能分支开发完成后,合并到 develop 分支。
c. 需求上线后,本地分支预留 3-7 天后删除。
d. 定期从 develop 分支创建 release-xxx 分支用于预发布。

# hotfix(热修复分支)
a. 只能从 master 或 release 分支创建,命名格式为 fix-xxx,其中 xxx 为该修复的名称。
b. hotfix 分支只能进行紧急修复工作,不能新增功能。
c. 修复完成后,必须合并到 develop 或 relerae。
d. bug 修复上线后,分支本地预留 1-3 天后删除。

2. 版本号管理

版本号 Tag 采用三段式,v 版本.里程碑.序号,如:v1.0.0

修改第1位 - 架构升级或架构重大调整
修改第2位 - 新功能上线或者模块大的调整
修改第3位 - bug修复上线、需求完善等调整

3. 提交规范

目前社区流行的 commit 规范(来自于 Angular 团队的 commit 规范)。 commit message 包括三部分:HeaderBodyFooter。其中 Header 必需,其余可选。

(1) Header(必需)

<type>(<scope>): <subject>
  • type(必需)--- 用于说明 commit 类别

    • feat:新功能
    • fix:修复 bug
    • docs:仅仅修改了文档
    • style:格式修改(不改变代码逻辑)
    • refactor:代码重构,没有新增功能或修复bug
    • chore:改变构建流程、或者增加依赖库、工具变动
    • perf:优化相关,如提升性能、用户体验等
  • scope(可选)--- 用于说明 commit 影响范围。

  • subject(必需)--- 用于 commit 内容的简短描述。

(2) Body(可选)

对本次 commit 修改内容的具体描述。描述为什么修改,修改了什么,以及思路等等。

(3) Footer(可选)

仅处理 不兼容 或 关闭 Issue 使用。