(建议收藏)快来看看我们团队是如何制定前端开发规范的?

3,488 阅读9分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战

前言

这次来把之前的前端开发规范文章重写一下,其实文章内容是没有毛病的,就是文章的排版使想表达的内容不直观,没让运营人员看上,也就导致没有得到更多的展现和访问量,所以我决定对其进行优化并增加我们团队在实际开发中实行的规范内容。

我发现之前输出的文章,收藏的人还挺多的,就是为什么不点赞不评论呢?写文不易,既然点进来了,不妨请继续看下去吧^_^

思考

无规矩不成方圆,无规范难以协同

今天看到一句话:一个人可能走的更快,但是一群人会走得更远。一个人的确能进步和变好,但是一个人的想法、认知、眼界、能力和执行力都远远比不上一群人的。之所以需要开发规范来约束团队,就是想让团队成员编写出高质量的代码,让团队成员每天在一起都心情愉悦,从而让团队做得更好走的更远。

为什么需要开发规范?

要回答这个问题,那就得用反证法来说没有规范会怎样?缺乏规范首先最直接得问题就是团队编码风格不一,增加了成员间代码的阅读成本,加大了团队协作成本和维护成本;其次就是团队成员如若不稳定,项目就会一团糟,甚至失控;最后就是即便是个人开发,不良的编码习惯可能给自己和他人造成阅读上的麻烦。所以,建立一套适合团队的开发规范是很有必要的。

开发规范的意义?

1、提高团队的协作能力,降低新成员融入团队的成本, 同时也一定程度避免挖坑

2、提高开发效率、团队协作效率, 降低沟通成本;

3、实现高度统一的代码风格,方便review

4、为后期维护提供更好的支持

规范

下面就开始介绍,我们团队的前端规范是怎样的?以及包含了哪些内容?

一、命名风格

(一)CSS命名规范

1、选择器命名一律用小写字母, 避免用拼音命名

正例: 
#name / .name1

反例: 
._name / .Name / .NAME / .$name / .22name / .yemian

2、选择器统一采用 横线 - 作为分隔符,禁止使用下划线 _ 分割,且分隔符尽量不超过4个

正例:
.page-wrapper / .page-wrapper-box

反例:
.page_wrapper / .page_wrapper_ / #_page

(二)JS命名规范

1、代码中的命名均不能用美元符号 $ 和下划线 _ 开始,也不能以 $ 和 _ 以及数字结束

2、代码中的命名禁止使用拼音、拼音+英文、中文

3、类名使用帕斯卡法命名

如:UserPermissio

4、函数名、方法名、属性名、变量名统一用驼峰法命名

如:submitHandle / getName

5、常量统一用大写,单词之间用下划线 _ 隔开

如:GLOBAL_CONFIG

6、TS接口名统一用大写字母 I 作为前缀

如:IPersonProps

7、TS枚举类名称及其属性统一用大写字母,单词间用下划线( \color{red}__ )隔开

// 性别 
enum SEX_TYPE { 
    MALE, 
    FEMALE
}

8、函数名、方法名、属性名、变量名命名规约

  • 获取单个对象用 get 做前缀。

  • 获取多个对象用 list 做前缀。

  • 查询用 query/search 做前缀。

  • 插入用 add/save 做前缀。

  • 编辑、更新用 edit/update 做前缀。

  • 删除用 remove 做前缀。

  • 数组对象用 List 做后缀。

二、代码格式

(一)CSS代码格式

1、个样式独占一行,并且使用Tab或4个空格缩进,禁止不换行书写

说明: 如果使用Tab缩进,必须设置1个Tab为4个空格。

正例:
.page { 
    .margin: 10px; 
    .padding: 10px; 
    .background: #000; 
}

反例:
.page{margin: 10px;padding: 10px;background: #000;}

2、选择器单独一行,且其与左大括号 { 之间留出一个空格,右大括号 } 单独成行; 冒号 : 后面留出一个空格,每个样式用分号 ; 结尾

正例:
.page { 
    .padding: 10px; 
}

反例:
.page{ padding:10px }

3、以逗号分隔的属性值,每个逗号后留出一个空格

正例:
.page { 
    rgba: (255, 55, 55, 5); 
}

反例:
.page{ 
    rgba: (255,255,255,.5); 
}

4、免层级嵌套过多,尽量不超过4层

正例:
.page .wrapper .box { 
    /* ... /* 
}

反例:
.page .wrapper .box div p { 
    /* ... /* 
}

(二)JS代码格式

1、尽量使用 const 和 let 声明变量

说明: var 会引起变量提升,使用const 确保你无法重新对常量赋值,使用let确保你无法重新声明变量。

const a = 1;
let b = 2;

2、大括号使用规约

  • 左大括号前不换行,并留一个空格
  • 左大括号后换行
  • else 等代码与右大括号之间留一个空格
  • 表示终止的右大括号必须单独成行
  • 箭头函数内如果只有一条表达式可以省略左右大括号
正例:
function getNumber(x) { 
    /* ... */ 
} 

if (x > 5) { 
    /* ... */ 
} else { 
    /* ... */ 
} 

[1, 2, 3, 4, 5].map(item => item.filter > 2);


反例:
function getNumber(x) 
{ 
    /* ... */ 
} 
if (x > 5){ 
    /* ... */ 
}else{ 
    /* ... */ 
}

3、引号使用规约

  • HTML代码中的class、id或其它属性的值均采用双引号
  • JS代码中字符串均采用单引号
正例:
<input type= "file" />
let name = 'zhangsan';

反例:
<input type= 'file' />
let name = "zhangsan";

4、注意 === 和 == 、 != 和 !== 的使用

说明: 使用 == 和 != 容易造成隐式转换,如 5 == '5' = true; 5 != '5' = false

5、采用4个空格或者Tab缩进

说明: 如果使用Tab缩进,必须设置1个Tab为4个空格。

6、if / for / while / switch / catch 等关键字与小括号之间都必须加空格

if (x === 100) {}
for (let i = 0; i < 10; i++) {}

7、左小括号与字符间不留空格,右小括号与字符间也不留空格

正例: 
if (x === 100) {}

反例: 
if ( x === 100 ) {}

8、任何二目、三目运算符(如:+ - * / % = += *= && ||) 的左右两边都要加空格

a + b = 2;
x * y = z; 
x == y ? x : y;

9、注释的双斜线与注释内容之间留一个空格

10、三元运算符在一条表达式中最多出现两次

正例:
let num = x === y ? x : x > 100 ? z : y;

反例:
let num = x === 100 ? x : x === 120 ? y : x === 150 ? z : 200;

11、多个参数后边统一加一个空格

foo(x, y, z)

12、for循环体内的代码不超过50行

说明: 包括注释、空行、回车总的行数不超过50行,如果的确无法避免需将部分代码抽离出来成为独立函数。

13、函数/方法之间插入两个空行分隔以提升代码可读性

正例:
getMax() { 
    /* ... */ 
} 


listUser() { 
    /* ... */ 
}


反例:
getMax() { 
    /* ... */ 
} 
listUser() { 
    /* ... */ 
}

三、对象处理

1、不要修改标准JS对象的原型

说明: 修改标准JS对象的原型会可能会覆盖原有的方法或属性。

2、不要通过原型向对象添加新的属性或方法,可以将指定功能封装为工具函数,通过导出的方式引用

正例:
export function format(date, format) {
    /* ... */
};

反例:
Date.prototype.format = function(format) {
    /* ... */
}

3、使用对象直接量创建对象或数组

let obj = {}; 
let list = [];

4、使用展开运算符 ... 复制或合并数组/对象

let a = {name: 'zhangsan'}; 
let b = {age: 22}; 
let c = {...a, ...b}; // {name: 'zhangsan', age: 22} 

let x = [1, 2]; 
let y = [3, 4]; 
let z = [...x, ...y]; // [1, 2, 3, 4]

5、使用解构获取对象的属性值

正例:
function getUser(user) { 
    const { name, age } = user; 
}

反例:
function getUser(user) { 
    let name = user.name; 
    let age = user.age; 
}

6、使用数组对象的方法前,如果无法确定变量为数组类型,需要对变量做类型检查

if (Array.isArray(obj)) { 
    /* ... */ 
}

7、使用 JSON.parse 方法解析变量前,需对变量做类型及JSON格式检查

说明: 如果变量为undefiend或不是json结构的字符串, js会抛出语法异常,阻塞js的执行。

8、在组件生命周期内调用setTimeout或者setInterval时,一定要在销毁组件时,使用clearTimeout或clearInterval清除定时器对象

说明: 如果组件销毁后,定时器对象并未清除,则在回调函数执行时,组件可能并不存在,从而可能会造成内存溢出的问题。

四、注释规约

1、自定义函数/方法应加上相应的注释,说明该函数/方法的用途,如果有需要应对参数标注说明,如果是在TS中则应定义返回值类型(无返回值的可省略)

// 获取最大值 
function max(x, y) { 
    return x > y ? x : y; 
} 


/** 
 * 获取最大值 
 * @param x 
 * @param y 
 */ 
const max = (x: number, y: number): number => { 
    return x > y ? x : y; 
} 
 
 
/** 
 * 删除数组中某元素 
 * @param list 数组 
 * @param index 下标 
 */ 
remove(list: string[], index: number) { 
    /* ... */ 
}

2、组件、类、类方法的注释使用 /** xxx */ 方式,禁止使用 // xxx 方式

/** 
 * 用户列表组件 
 */ 
class UserList { 
    /** 
     * 刷新列表 
     */ 
    refresh = () => { 
        /* ... */ 
    } 
}

3、所有字典、枚举类型字段必须要有主注释说明,说明该字段用途

// 用户角色 
const roleOptions = [ 
    {value: 1, name: '管理员'}, 
    {value: 2, name: '普通用户'}, 
]; 

// 性别 
enum SEX_TYPE { 
    MALE, 
    FEMALE
}

4、代码修改的同时,注释也要进行相应的修改,尤其是参数,返回值的修改

5、注释力求简明扼要,要能够使自己及别的程序员能够及时了解注释的含义,不用的注释及时删除

五、Git版本管理

1、永远不要把Test(测试)分支代码合并到自己的分支上;

2、新建分支一定是基于Master分支;

3、自己的分支合并到UatMaster分支前,用Master分支刷一次自己的分支;

4、某些IDE(webstorm)的项目管理器可能与实际目录更新不同步,会导致Git管理出现异常(解决办法:使用小乌龟或其它Git管理工具直接在实际项目目录中操作)。

至此,前端开发规范的制定内容也就聊完了。看文至此,不要只收藏不点赞不评论呀,顺手点个赞👍再走呀,3Q^_^

往期精彩文章

后语

伙伴们,如果觉得本文对你有些许帮助,点个👍或者➕个关注在走呗^_^ 。另外如果本文章有问题或有不理解的部分,欢迎大家在评论区评论指出,我们一起讨论共勉。