通过分析github代码库总结出来的工程师代码书写习惯✍
为提高团队协作效率, 便于后台人员添加功能及前端后期优化维护, 输出高质量的作品, 特制订此文档.
本规范文档一经确认, 前端开发人员必须按本文档规范进行前台页面开发. 本文档如有不对或者不合适的地方请及时提出, 经讨论决定后可以更改此文档.
坚持制定好的代码规范。
无论团队人数多少,代码应该同出一门,易读易维护。
1、全部采用小写的英文字母、数字和下划线的组合,其中不得包含汉字、空格和特殊字符。
2、指导思想:团队的每一个成员能够方便的理解每一个文件的意义。
3、第三方依赖包按原有命名和结构,无需按规范重新命名。
4、作品交付给公司其它团队后,不干涉其后续目录结构调整和命名规范。
1、根目录下目录结构必须按照 业务职能进行划分,划分出的子目录,名称必须为一个单词,不宜过长。如:例子中的biz1。
2、业务目录中,如果文件太多不好管理,需要划分子目录时,也必须继续遵守根据业务逻辑划分的原则,划分子业务。如:例子中的subbiz1。
3、业务目录下可以按资源类型(js、css)划分子目录,也可以直接将资源文件放在目录下
另:较小规模的业务项目,允许不划分业务子目录,直接按第3条要求放在根目录下。
${root}/
common/
biz1/
subbiz1/
js/
list.js
css/
list.css
list.html
subbiz2/
index.js
index.css
index.html
biz2/
简洁。有习惯性缩写的单词,采用容易理解的缩写。不允许使用复数形式。如:imgs、docs是不被允许的。
img: 图片。 不允许使用image、images、imgs等。
js: javascript脚本。 不允许使用script、scripts等。
css: 样式表。 不允许使用style、styles等。
doc: 文档目录。 不允许使用source、docs等。
lib: 引入的第三方依赖包目录。 不允许使用dep、library、dependency等。
</li>
和 </body>
。<!DOCTYPE html>
<html>
<head>
<title>Page title</title>
</head>
<body>
<img src="images/company_logo.png" alt="Company">
<h1 class="hello-world">Hello, world!</h1>
</body>
</html>
这些规范已经在脚手架中定义好,可直接复用;
1、在页面开头使用这个简单地doctype来启用标准模式,使其在每个浏览器中尽可能一致的展现;
2、应在html标签上加上lang属性。这会给语音工具和翻译工具帮助,告诉它们应当怎么去发音和翻译。
3、通过声明一个明确的字符编码,让浏览器轻松、快速的确定适合网页内容的渲染方式,通常指定为'UTF-8'。
4、用 <meta>
标签可以指定页面应该用什么版本的IE来渲染;
5、用 <meta>
标签viewport定义移动端兼容模式;
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,minimum-scale=1.0,maximum-scale=1.0" />
<meta name="apple-touch-fullscreen" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="x5-fullscreen" content="true">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
</head>
<body>
……
</body>
</html>
1、在 head 中引入页面需要的所有 CSS 资源。
解释:在页面渲染的过程中,新的CSS可能导致元素的样式重新计算和绘制,页面闪烁。
2、JavaScript 应当放在页面末尾,或采用异步加载。
解释:将 script 放在页面中间将阻断页面的渲染。出于性能方面的考虑,如非必要,请遵守此条建议。
3、如果html中css或js超过50行,必须另写css、js文件方式引入。
<!-- External CSS -->
<link rel="stylesheet" href="code_guide.css">
<!-- In-document CSS -->
<style>
...
</style>
<!-- External JS -->
<script src="code_guide.js"></script>
<!-- In-document JS -->
<script>
...
</script>
在JS文件中生成html dom标签让内容变得更难查找,更难编辑,性能更差。应该尽量避免这种情况的出现。
属性应该按照特定的顺序出现以保证易读性;
class
id
name
data-*
src
, for
, type
, href
, value
, max-length
, max
, min
, pattern
placeholder
, title
, alt
aria-*
, role
required
, readonly
, disabled
class是为高可复用组件设计的,所以应处在第一位;
id更加具体且应该尽量少使用,所以将它放在第二位。
<a class="..." id="..." data-modal="toggle" href="#">Example link</a>
<input class="form-control" type="text">
<img src="..." alt="...">
在编写HTML代码时,需要尽量避免多余的父节点;
很多时候,需要通过迭代和重构来使HTML变得更少。
<!-- 不好 -->
<span class="avatar">
<img src="...">
</span>
<!-- 更好 -->
<img class="avatar" src="...">
尽量遵循HTML标准和语义,但是不应该以浪费实用性作为代价;
任何时候都要用尽量小的复杂度和尽量少的标签来解决问题。
需要使用缩进,交付作品前请格式化css代码。
每个属性声明末尾都要加分号。
.element {
position: absolute;
top: 10px;
left: 10px;
border-radius: 10px;
width: 50px;
height: 50px;
}
注释统一用'/* */',具体参照右边的各种写法;
缩进与下一行代码保持一致;
可位于一个代码行的末尾,与代码间隔一个空格。
/* Modal header */
.modal-header {
...
}
/*
* Modal header
*/
.modal-header {
...
}
.modal-header {
/* 50px */
width: 50px;
color: red; /* color red */
}
最外层统一使用双引号;
url的内容要用引号;
属性选择器中的属性值需要引号。
.element:after {
content: "";
background-image: url("logo.png");
}
li[data-type="single"] {
...
}
/* class */
.element-content {
...
}
/* id */
#myDialog {
...
}
/* 变量 */
$colorBlack: #000;
/* 函数 */
@function pxToRem($px) {
...
}
/* 混合 */
@mixin centerBlock {
...
}
/* placeholder */
%myDialog {
...
}
尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。
.element {
...
}
.element-avatar{
...
}
@media (min-width: 480px) {
.element {
...
}
.element-avatar {
...
}
}
元素选择器用小写字母;
如无必要,不得为 id,尽量使用class
选择器的嵌套层级应不大于 4 级
选择器限定条件应尽可能精确
/* good */
#username input {}
.comment .avatar {}
/* bad */
.page .header .login #username input {}
.comment div * {}
不允许有空的规则;
同个属性不同前缀的写法需要在垂直方向保持对齐,具体参照右边的写法;
无前缀的标准属性应该写在有前缀的属性后面;
不要在同个规则里出现重复的属性,如果重复的属性是连续的则没关系;
不要在一个文件里出现两个相同的规则;
发布的代码中不要有 @import
;
尽量少用'*'选择器。
/* not good */
.element {
}
/* not good */
.element {
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
background: linear-gradient(to bottom, #fff 0, #eee 100%);
background: -webkit-linear-gradient(top, #fff 0, #eee 100%);
background: -moz-linear-gradient(top, #fff 0, #eee 100%);
}
/* not good */
.element {
color: rgb(0, 0, 0);
width: 50px;
color: rgba(0, 0, 0, .5);
}
需要使用缩进,交付作品前请格式化js代码。
var x = 1,y = 1;
if (x < y) {
x += 10;
} else {
x += 1;
}
单行注释双斜线后,必须跟一个空格;
建议在以下情况下加注释:
/*
* 多行注释
*/
var x = 1;
if (condition) {
// 单行注释
allowed();
}
var zhangsan = 'zhangsan'; // one space after code
实体类(可以new的类)定义规范按示例定义
类的属性和方法都在一起,易读和理解
//实体类的定义,首字母大写
function TextNode(value, engine) {//构造方法
this.value = value;
this.engine = engine;
}
//【建议】方法1,直接prototype等于对象
TextNode.prototype = {
constructor: TextNode, //必须,需要修正constructor
clone:function(){
return this;
},
fun1 : function (opts) {
……
}
};
//方法2:,或单个定义
TextNode.prototype.clone = function () {
return this;
};
TextNode.prototype.fun1 = function (opts) {
……
};
//类的使用
var textNode = new TextNode('testvalue','testengine');
textNode.fun1();
静态类(无需new的,直接通过"."使用内部方法的类)定义规范按示例定义
类的属性和方法都在一起,易读和理解
//静态类的定义,首字母小写
var textNode = {
value:null,
engine:null,
clone:function(){
return this;
},
fun1 : function (opts) {
……
}
};
//类的使用
textNode.fun1();
函数划分原则:尽量扁平化,嵌套不得超过3层
一个函数的代码行长度控制在 50 行以内(除var定义的文本内容外)
一个函数的参数控制在 6 个以内,建议通过 options 参数传递非数据输入型参数
不同行为或逻辑的语句集,使用空行隔开,更易阅读。
在语句的行长度超过 120 时,根据逻辑条件合理缩进。
var loadingModules = {}; //变量
var $body = $('body'); //jquery对象变量
//类
function TextNode(value, engine) {
this.value = value;
this.engine = engine;
}
TextNode.prototype.clone = function () {
return this;
};
var textNode = new TextNode();
尽量加分号,避免潜在bug,以下几种情况后需加分号:
/* var declaration */
var x = 1;
/* expression statement */
x++;
/* do-while */
do {
x++;
} while (x < 10);
最外层统一使用单引号。
// not good
var x = "test";
// good
var y = 'foo',z = '<div id="test"></div>';
下列关键字后必须有大括号(即使代码块的内容只有一行):if
, else
, for
, while
, do
, switch
, try
, catch
, finally
, with
。
// not good
if (condition)
doSomething();
// good
if (condition) {
doSomething();
}
永远不要直接使用undefined进行变量判断;
使用typeof和字符串'undefined'对变量进行判断。
// not good
if (person === undefined) {
...
}
// good
if (typeof person === 'undefined') {
...
}
遍历数组不使用 for in,数组对象可能存在数字以外的属性, 这种情况下 for in 不会得到正确结果。
应该在for第1个参数中定义len获取长度,第2个参数中不要出现取length值情况。
var arr = ['a', 'b', 'c'];
// 这里仅作演示, 实际中应使用 Object 类型
arr.other = 'other things';
// 正确的遍历方式
for (var i = 0, len = arr.length; i < len; i++) {
console.log(i);
}
// 错误的遍历方式
for (var i in arr) {
console.log(i);
}
用'===', '!==' 代替 '==', '!=';
switch、if各分支情况和一定要有注释特别说明;
不要在内层作用域的代码里声明了变量,之后却访问到了外层作用域的同名变量;
尽量避免使用 eval 函数。
尽量减少 DOM 操作;
对上下文this的引用只能使用 'that', 'self','$this'其中一个来命名;
debugger不要出现在提交的代码里;