一份整理好了的规范文档,node后端开发用到



"规范是个好东西..." - 鲁迅

以下规范仅作为参考


1、代码规范

命名

  • 尽量保证命名更加语义化

文件命名采用下划线命名法

// good
service_center.js
// bad
serviceCenter.js

类 & 构造函数命名

  • 类命名采用 Pascal命名法,大写字母开头,各个单词首字母大写
class Person {
constructor(name) {
this.name = name;
}
}
const person = new Person('小明');

方法名

  • 方法命名采用 Camel命名法,小写字母开头,各个单词首字母大写

    前缀应当是动词

    命名建议:可使用常见动词约定等。
// good
function getName() {
...
return this.name;
} function isExist() {
...
return true;
}

变量命名

  • 采用 Camel命名法,小写字母开头,各个单词首字母大写

    特有大写缩写词汇保持大写如:SQL, URL等

    变量名字不宜过长,可适当采用缩减英文元音字母来缩短长度

    前缀应当是名词(方法名前缀为动词,以此区分变量和方法)
// good
let maxLength = 10; // bad
let setLength = 10;

常量命名

  • 必须采用 全大写命名,且单词以_分割

    const MAX_COUNT = 10;

    const SQL = 'SELECT * from bas_table';

注释规范

  1. 行内注释:行内注释以两个斜线开始,以行尾结束。双斜线与代码以及注释文字之间都都保留一个空格。
function addNumber() {
return 3 + 2; // 5
}
  1. 单行注释:单独一行,单行注释以两个斜线开始,以行尾结束。
function addNumber(a, b) {
return a + b;
} // 调用求和方法
addNumber(2, 3);
  1. 方法注释:函数(方法)注释也是多行注释的一种,但是包含了特殊的注释要求。

    /**
  • 方法描述
  • @param {type} 参数值 参数说明
  • @param {type} 参数值 参数说明

    /

    示例:

    /
    *
  • @param {number} a 参数a
  • @param {Number} b 参数b

    */

    funtion addNumber(a, b) {

    return a + b;

    }

格式规范

  • JS格式规范要严格遵循 Eslint,要求在 husky 钩子中增加Eslint规则校验,校验不通过,代码提交失败。

其他规范

  1. 变量声明
  • 对所有的变量优先使用const,可变的变量使用let,不允许使用var
// good
const a = 1;
const b = 2; // good
let count = 1;
if (true) {
count += 1;
}
  1. Strings
  • 字符串使用单引号 ‘’

    生成字符串时,使用模板字符串代替字符串连接
// bad
function sayHi(name) {
return 'How are you, ' + name + '?';
} // good
function sayHi(name) {
return `How are you, ${name}?`;
}
  1. 对象
  • 使用字面值创建对象
// good
const obj = {}; // bad
const obj = new Object();

对象方法的简写

// bad
const atom = {
value: 1,
addValue: function (value) {
return atom.value + value;
},
}; // good
const atom = {
value: 1,
addValue(value) {
return atom.value + value;
},
};

对象属性值的简写

const lukeSkywalker = 'Hello World';

// bad
const obj = {
lukeSkywalker: lukeSkywalker
}; // good
const obj = {
lukeSkywalker
};
  1. 数组
  • 使用字面值创建数组
// bad
const arr = new Array(); // good
const arr = [];
  • 使用拓展运算符 … 复制数组
// bad
const len = arr.length;
const arrCopy = [];
let i; for (i = 0; i < len; i++) {
arrCopy[i] = arr[i];
} // good
const arrCopy = [...arr];
  1. 解构
  • 使用解构存取和使用多属性对象
// bad
function getFullName(user) {
const firstName = user.firstName;
const lastName = user.lastName;
return `${firstName} ${lastName}`;
} // good
function getFullName(user) {
const { firstName, lastName } = user;
return `${firstName} ${lastName}`;
} // best
function getFullName({ firstName, lastName }) {
return `${firstName} ${lastName}`;
}
  1. 函数
  • 尽可能使用箭头函数

    不允许在一个非函数代码块(if、while 等)中声明一个函数

    使用函数声明代替函数表达式因为函数声明是可命名的,所以他们在调用栈中更容易被识别。此外,函数声明会把整个函数提升(hoisted),而函数表达式只会把函数的引用变量名提升。这条规则使得箭头函数可以取代函数表达式。
// bad
const foo = function () {
}; // good
function foo() {
}
  • 别保存 this 的引用。使用箭头函数或 Function#bind。
// bad
function foo() {
const that = this;
return function() {
console.log(that);
};
} // good
function foo() {
return () => {
console.log(this);
};
}

语法原则

  1. 统一使用Node.js支持的 ES6 及以上版本的新特性写法
  2. 尽量使用常用常规的方法去实现一个功能,避免使用各种奇技淫巧
  3. 能用原生语法或原生函数实现的功能尽量不要借助 lodash 等额外的库来实现
  4. 统一使用 Promise + async/await 取代 callback, 解决回调地狱
  5. require() 引入的模块和库按代码长度排序,且库和自定义模块分开,库引用在前,自定义模块在后
  6. 对象定义统一用 {} 定义,而不是 new Object()
  7. 使用字面值创建数组,数组定义统一用 [],而不是 new Array()
  8. 向数组添加元素时使用 push 替代直接赋值
  9. 使用拓展运算符 ... 复制数组
  10. 使用 map、reduce、filter 时如果函数简单应省略 return
  11. 给注释增加 FIXME 或 TODO 的前缀,帮助其他开发者快速了解这是一个需要复查的问题,或是给需要实现的功能提供一个解决方式。

命名规范:

  1. 函数名/变量名:

    方式: 小驼峰

    good: testFunction/testVar

    bad: test_function/test_var
  2. 全局常量:

    方式: 大写下划线分隔

    good: TEST_CONST

    bad: test_const
  3. 文件名:

    方式: 小写下划线分隔

    good: test_file.js

    bad: test-file.js
  4. 类名:

    方式: 小写下划线分隔

    good: TestClass

    bad: testClass

2、api设计

路由规范(URI)

  • URI必须全部使用小写
good: /api/v1/uic/check/login
bad: /api/v1/uic/checkLogin
  • 如需连接多个单词则必须使用 下划线
good:/api/v1/dubhe/task_run_history
bad: /api/v1/dubhe/task-run-history
  • 版本号格式(必须是 v + 整数)
good:/api/v2/dubhe/tasks
bad: /api/v1.1/dubhe/tasks

HTTP Method

  • 能抽象成资源的CURD则使用标准的HTTP Method来区分,URI中尽量不使用动词(特殊情况除外[1])
  1. GET 读取资源(必须保证接口的幂等性)
  2. POST 新增资源
  3. PUT 更新资源
  4. DELETE 删除资源
  • 资源的描述尽量采用复数形式
good: GET /api/v1/dubhe/tasks
bad: GET /api/v1/dubhe/task_list
  • 对于不方便直接抽象为资源的操作,例如 启动一个任务 可采用如下动词的方式
POST /api/v1/dubhe/start/task/:taskId
  • 参数传递主要使用如下三种方式(文件上传除外)
  1. 路由参数(Route Param)
  2. URL查询参数(Query String)
  3. JSON参数(Request Body)
  • 单个资源的操作推荐使用动态路由参数(Route Param)
good:GET /api/v1/uic/users/:userId
bad: GET /api/v1/uic/users?userId=1234
  • 参数命名方式统一采用驼峰式
good:
POST /api/v1/uic/users
body:
{
"userId": 1,
"userName": "用户名",
"tenantId": 1,
"tenantName": "租户名"
}
◦ bad:
POST /api/v1/uic/users
body:
{
"user_id": 1,
"user_name": "用户名",
"tenant_id": 1,
"tenant_name": "租户名"
}

接口返回值格式

  • 默认统一格式为 application/json (文件下载除外)

  • 返回体json数据中包含如下4个字段:

success : 描述接口返回成功还是失败,取值 true or false

code: 接口返回的错误码,错误码的规范由各个业务系统自行约束
推荐使用英文大写枚举值,如: ERROR_UNAUTH ERROR_INVALID_PARAM ERROR_NO_PERMISSION
message: 接口返回错误时的描述信息,如: param transform failed, userId should be a number. content: 接口返回成功时的数据内容, json格式

示例:

成功:
{
"success": true,
"code": "",
"message": "",
"content": {
"id": 1,
"name": 2,
"email": "12345@sina.cn"
}
}
注:content的内容及格式由接口实现者给出 失败:
{
"success": false,
"code": "ERROR_NO_PERMISSION",
"message": "you have no permission",
"content": ""
}

◦

  • 查询接口分页返回场景
  • 查询参数(querystring):?currentPage=1&pageSize=10
{
"success": true,
"code": "",
"message": "",
"content": {
"count": 20, // 数据总条数
"currentPage": 1, // 当前页码
"pageSize": 10, // 每页的数据条数
"data":[
]
}
}
注:data中的内容及格式由接口实现者给出

标杆API设计样例

  • 名称:查询功能点列表
  • 方法:GET
  • 路径:/api/v1/uic/functions
  • 成功返回接口示例:
{
"success": true,
"code": 0,
"message": null,
"content": [
{
"functionId": 6530,
"functionName": "登录权限",
"functionCode": "dsp_page",
"description": null,
"type": "1",
"productId": 102,
"groupId": null,
"groupName": null,
"enabled": 1,
"invalid": "N",
"createTime": "2018-03-21T03:13:06.000Z",
"modifyTime": "2018-03-21T03:13:06.000Z"
},
{
"functionId": 6528,
"functionName": "用户页面-管理",
"functionCode": "user_page",
"description": null,
"type": "1",
"productId": 85,
"groupId": null,
"groupName": null,
"enabled": 1,
"invalid": "N",
"createTime": "2018-03-13T13:35:11.000Z",
"modifyTime": "2018-03-13T13:35:11.000Z"
}
]
}

3、版本号规范

此规范约束的是package.json中的version以及git仓库中打tag的规范。

  • 版本号格式:

标准的版本号必须采用 X.Y.Z 的格式,其中 X、Y、Z 为非负的整数,且禁止在数字前方加前导零。X 是主版本号、Y 是次版本号、 Z 为修订号。每个元素必须以数值来递增。例如:1.9.0 -> 1.10.0 -> 1.11.0

  • 版本号修改规则:
  1. 主版本号:当你做了不兼容的API修改的情况需要增加
  2. 次版本号:当你做了向下兼容的功能性新增需要增加
  3. 修订号 :当你做了向下兼容的问题修正需要增加

    基本规范
  4. 主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共 API 不应该被视为稳定版。
  5. 1.0.0 的版本号用于标识稳定 API 的发布。这一版本之后,所有的版本号更新都基于公共 API 的修改内容
  6. 带版本号的软件发行后,禁止改变该版本软件的内容。任何修改都必须以新版本发行。

    修订号 Z(x.y.Z | x > 0)必须在只做了向下兼容的 bug 修复时才递增。
  7. bug 修复的定义是,修改程序内部行为,使其输出正确的结果

    次版本号 Y(x.Y.z | x > 0)必须在有向下兼容的新功能出现时递增。
  8. 在任何公共 API 的功能被标记为弃用时也必须递增。也可以在内部程序有大量功能更新或改进时递增。其中可能包括修订号的改变。每当次版本号递增时,修订号必须置零。

    主版本号 X(X.y.z | X > 0)必须在有任何不向下兼容的修改被加入公共 API 时递增。其中可能包括次版本号及修订号的改变。
  9. 每当主版本号递增时,次版本号和修订号必须置零

    修改版本号的MR里需要描述此次版本更新和上一版本的区别内容

FQ:

  • Q:万一不小心发布了不兼容的更新,但只更改了次版本号,该如何补救?

  • A:一旦发现自己破坏了语义化版本控制的规范,就要修正这个问题,并发行一个新的次版本号来更正这个问题,并且恢复向下兼容。即使是这种情况,也不能去修改已发行的版本。可以的话,将有问题的版本号记录到文档中,告诉使用者问题所在,让他们能够意识到这是有问题的版本。

  • Q:如何判断发布 1.0.0 版本的时机?

  • A:当你的软件被用于正式环境,它应该已经达到了 1.0.0 版。如果你已经有个稳定的 API 被使用者依赖,也应是 1.0.0 版。如果你有很多向下兼容的问题要考虑,也应该算是 1.0.0 版了。

  • Q:对于公共 API,若即使是最小但不向下兼容的改变都需要产生新的主版本号,岂不是很快就达到 42.0.0 版?

  • A:这是开发者的责任感和前瞻性的问题。不兼容的改变不应该轻易被加入到有许多依赖代码的软件中。升级所付出的代价必须是有意义的。要递增主版本号来发行不兼容的版本,意味着你已经为这些改变所带来的影响慎重考虑过,并且评估了所涉及的成本/效益比。

    操作

    项目每周迭代情况下,每次发布时增加次版本号,如果发布失败重新修改后发布则增加修订号。

package.js
{
"version": "1.0.0"
}
Makefile
tag:
@cat package.json | xargs -0 node -p 'JSON.parse(process.argv[1]).version' | xargs git tag
@git push origin --tags

提交版本号:

使用make命令

$make tag

或

// 删除版本号
git tag -d 1.0.0
// 添加版本号
git tag 1.0.0
// 推送到git服务器
git push origin --tags

4、eslint配置规则

{
// 开启了Node.js 和 Mocha 两个环境,会自动识别其中的全局变量
"env": {
"node": true,
"mocha": true
},
"plugins": [],
"parserOptions": {
// 使用 ES2017 的语法
"ecmaVersion": 8,
"sourceType": "script",
"ecmaFeatures": {
}
},
"rules": {
// 强制驼峰法命名变量
"camelcase": ["error"],
// 不允许在条件判断语句中使用赋值语句
"no-cond-assign": ["error"],
// 禁用行尾空格
"no-trailing-spaces": ["error"],
// 不允许在代码里写 console.xxx 语句
"no-console": ["error"],
// 不允许使用 var 声明变量
"no-var": ["error"],
// 不能直接 return 赋值语句
"no-return-assign": ["error"],
// 不允许给函数参数重新赋值
"no-param-reassign": ["error"],
// 不允许注释跟代码在同一行
"no-inline-comments": ["error"],
// 逗号前面不允许有空格,逗号后面必须有空格
"comma-spacing": ["error", {"before": false, "after": true}],
// 强制始终使用分号结尾
"semi": ["error", "always"],
// 强制始终使用大括号,就算代码块中只有一条语句
"curly": ["error", "all"],
// 强制使用 === 和 !==
"eqeqeq": ["error", "always"],
// 大括号的风格,前面一个在行末,后面一个在行首
"brace-style": ["error"],
// 缩进格式为2个空格,switch语句的case子句也是缩进2个空格
"indent": ["error", 2, {"SwitchCase": 1}],
// 一行代码的最大长度,tab计算为2个空格,忽略注释部分
"max-len": ["error", 180, 2, {"ignoreComments": true}],
// 禁止出现未被使用过的变量
"no-unused-vars": ["error"],
// 可以使用的地方强制使用箭头函数
"prefer-arrow-callback": ["error"],
// 强制统一使用单引号
"quotes": ["error", "single"],
// 强制在关键字前后使用空格
"keyword-spacing": ["error"],
// 冒号前面不允许有空格,冒号后面强制需要一个空格
"key-spacing": ["error"],
// 分号前不允许有空格,分号后强制需要空格
"semi-spacing": ["error", {"before": false, "after": true}],
// json 对象大括号前后不允许有空格
"object-curly-spacing": ["error", "never"],
// 操作符前后必须有空格
"space-infix-ops": ["error"],
// (左)大括号前强制空格
"space-before-blocks": ["error"]
},
"globals": {
}
}

代码规范、API设计等规范的更多相关文章

  1. RESTful API设计原则与规范

    RESTful API设计原则与规范 一.背景与基础概念 2 二.RESTful API应遵循的原则 3 1.协议(Protocol) 3 2.域名(ROOT URL) 3 3.版本(Versioni ...

  2. .NET代码设计简单规范

    以下转载于:http://www.it28.cn/ASPNET/825095.html 下面这个规范是我为朋友写的几点建议,写的很范,作为BLOG,愿与大家一起分享.只给出部分设计规范样例,关于.NE ...

  3. API 接口开发规范

    整体规范建议采用RESTful 方式来实施. 协议 API与用户的通信协议,总是使用HTTPs协议,确保交互数据的传输安全. 域名 应该尽量将API部署在专用域名之下.https://api.exam ...

  4. Atitit usrQBF2312 命名空间pkg 以及 api命名 spec规范

    Atitit usrQBF2312 命名空间pkg 以及 api命名 spec规范 简化英文1 常用类库sdk的命名单词统计表1 简化时间规则1 Namsspace nam spec,参照java . ...

  5. Web UI 网站用户界面设计命名规范

    Web UI 网站用户界面设计命名规范 WEB UI设计命名规范,也就是网站用户界面设计(网页设计)命名规范. 这套规范并非单纯的CSS.html或JavaScript命名规范,它涉及了很多使用Pho ...

  6. (2.15)Mysql之SQL基础——开发设计最佳规范

    (2.15)Mysql之SQL基础——开发设计最佳规范 关键字:mysql三大范式,mysql sql开发规范 分析: show profile.mysqllsla.mysqldrmpslow.exp ...

  7. vscode保存代码,自动按照eslint规范格式化代码设置

    # vscode保存代码,自动按照eslint规范格式化代码设置 编辑器代码风格一致,是前端代码规范的一部分.同一个项目,或者同一个小组,保持代码风格一致很必要.就拿vue项目来说,之前做的几个项目, ...

  8. Web UI 设计(网页设计)命名规范

    Web UI 设计命名规范 一.网站设计及基本框架结构: 1.    Container“container“ 就是将页面中的所有元素包在一起的部分,这部分还可以命名为: “wrapper“, “wr ...

  9. MySQL(9)— 规范数据库设计

    九.规范数据库设计 9-1.为什么要设计? 当数据库比较复杂时,我们就需要设计了! 糟糕的数据库设计: 数据冗余,浪费大量存储空间 使用物理外键,大量的增删改操作麻烦,异常 查询效率低下 良好的数据库 ...

随机推荐

  1. HDU 2157 How many ways?? 题解

    题目 春天到了, HDU校园里开满了花, 姹紫嫣红, 非常美丽. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这迷人的校园, 葱头决定, 每次上课都走不同的路线 ...

  2. 在react中使用到的好用的插件

    1)antd UI组件 蚂蚁金服出品的 挺好用的 还有个移动端的antd-moblie 2) moment 日期处理类库 3)prop-types 第三方库 对组件props变量进行类型检测 4)qs ...

  3. cmake的下载和安装

    背景: 最近迷上了 vscode 编辑器, 快速便捷,而且插件丰富,使用起来很爽.既然这样,本身游戏也是用 mingw 加 cygwin 开发的, 可以配置一下,开搞. 实操: 1.登陆cmake官网 ...

  4. ecs架构思考

    系统管理者, ecs本身要处理的是遍历, 遍历结构处理事情. 而不同的场景要处理的事务是不一样的, 所以系统是要动态增加或者减少的. 而实体代表着一个真正的对象, 对象本身是复杂的, 拥有多种属性的. ...

  5. 【学习】从.txt文件读取生成编译代码。

    string code = null; String projectName = Assembly.GetExecutingAssembly().GetName().Name; // 1. 生成要编译 ...

  6. MySQL 对window函数执行sum函数疑似Bug

    MySQL 对window函数执行sum函数疑似Bug 使用MySql的窗口函数统计数据时,发现一个小的问题,与大家一起探讨下. 环境配置: mysql-installer-community-8.0 ...

  7. 开发者必备——API设计问题

    本文主要探讨RPC和RESTFul两种API风格的特点以及在开发中应该如何进行技术选型,同时截取了网上社区,文章一部分关于API设计的想法和观点供读者参考,取舍. 1,背景简述 API学名:应用程序接 ...

  8. 事件的event对象基本解释

    事件流: 描述的是在页面中接受事件的顺序主要分为两种: 事件冒泡.事件捕获 事件event对象:1. type 获取事件类型2. target获取事件目标3. stopPropagation() 阻止 ...

  9. Ethical Hacking - GAINING ACCESS(9)

    Server Side Attack Nexpose - Analysing Scan Results and Generating Reports OS and Software Inforatio ...

  10. 想用@Autowired注入static静态成员?官方不推荐你却还偏要这么做

    生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...