"规范是个好东西..." - 鲁迅
如下规范仅做为参考node
命名git
文件命名采用下划线命名法json
// good service_center.js // bad serviceCenter.js
类 & 构造函数命名api
class Person { constructor(name) { this.name = name; } } const person = new Person('小明');
方法名数组
// good function getName() { ... return this.name; } function isExist() { ... return true; }
变量命名服务器
// good let maxLength = 10; // bad let setLength = 10;
常量命名并发
注释规范app
function addNumber() { return 3 + 2; // 5 }
function addNumber(a, b) { return a + b; } // 调用求和方法 addNumber(2, 3);
格式规范curl
其余规范async
// good const a = 1; const b = 2; // good let count = 1; if (true) { count += 1; }
// bad function sayHi(name) { return 'How are you, ' + name + '?'; } // good function sayHi(name) { return `How are you, ${name}?`; }
// 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 };
// 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];
// 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}`; }
// bad const foo = function () { }; // good function foo() { }
// bad function foo() { const that = this; return function() { console.log(that); }; } // good function foo() { return () => { console.log(this); }; }
语法原则
命名规范:
路由规范(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
good:/api/v2/dubhe/tasks bad: /api/v1.1/dubhe/tasks
HTTP Method
good: GET /api/v1/dubhe/tasks bad: GET /api/v1/dubhe/task_list
POST /api/v1/dubhe/start/task/:taskId
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": "" }
◦
{ "success": true, "code": "", "message": "", "content": { "count": 20, // 数据总条数 "currentPage": 1, // 当前页码 "pageSize": 10, // 每页的数据条数 "data":[ ] } } 注:data中的内容及格式由接口实现者给出
标杆API设计样例
{ "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" } ] }
此规范约束的是package.json中的version以及git仓库中打tag的规范。
标准的版本号必须采用 X.Y.Z 的格式,其中 X、Y、Z 为非负的整数,且禁止在数字前方加前导零。X 是主版本号、Y 是次版本号、 Z 为修订号。每一个元素必须以数值来递增。例如:1.9.0 -> 1.10.0 -> 1.11.0
FQ:
A:一旦发现本身破坏了语义化版本控制的规范,就要修正这个问题,并发行一个新的次版本号来更正这个问题,而且恢复向下兼容。即便是这种状况,也不能去修改已发行的版本。能够的话,将有问题的版本号记录到文档中,告诉使用者问题所在,让他们可以意识到这是有问题的版本。
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
{ // 开启了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": { } }