代码规范

mac2025-06-03  32

es6代码规范 js代码规范


Vue 中的风格统一工具

eslint / prettier 是什么,有何区别:https://zhuanlan.zhihu.com/p/80574300

.eslintrc.js

ESLint 支持几种格式的配置文件,如果同一个目录下有多个配置文件,ESLint 只会使用一个。优先级顺序如下

JavaScript- 使用 .eslintrc.js 然后输出一个配置对象YAML - 使用 .eslintrc.yaml 或 .eslintrc.yml 去定义配置的结构JSON -使用 .eslintrc.json 去定义配置的结构,ESLint 的 JSON 文件允许 JavaScript 风格的注释Deprecated -使用 .eslintrc,可以使 JSON 也可以是 YAMLpackage.json 在 package.json 里创建一个 eslintConfig 属性,在那里定义你的配置

代码规范

推荐项目目录结构
dist css doc src ... .editorconfig .travis.yml README.md
.editorconfig

每个项目应当「SHOULD」包含 .editorconfig 用来统一配置编辑器的换行、缩进存储格式

[*.{js,jsx,ts,tsx,vue}] indent_style = space indent_size = 2 trim_trailing_whitespace = true insert_final_newline = true
Readme

每个项目都必须「MUST」包含一个README.md文件,此文件中应当「SHOULD」概要描述此项目的功能和特点等信息

eslint + prettierrc
.eslintrc.js module.exports = { root: true, env: { node: true, }, extends: ['plugin:vue/essential', '@vue/prettier'], rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'comma-dangle': ['error', 'always-multiline'], quotes: [ 'error', 'single', { avoidEscape: true, }, ], curly: ['error', 'all'], }, parserOptions: { parser: 'babel-eslint', }, }; .eslintignore # eslintIgnore files src/api/indexApi.js .prettierrc.js ? prettier.config.js 到底哪个目前未知 module.exports = { trailingComma: 'all', singleQuote: true, arrowParens: 'always', endOfLine: 'lf', };

js 代码风格

在文件结尾处,保留一个空行二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格代码块左花括号 { 前必须有一个空格[强制] if / else / for / while / function / switch / do / try / catch / finally 关键字后,必须有一个空格对象属性 key: value 中,: 后必须有空格,: 前不允许有空格函数声明、具名函数表达式、函数调用中,函数名和 ( 之间不允许有空格,)与{之间空格[强制] , 和 ; 前不允许有空格。[强制] 在函数调用、函数声明、括号表达式、属性访问、if / for / while / switch / catch 等语句中,() 和 [] 内紧贴括号部分不允许有空格[强制] 行尾不得有多余的空格, 每行不得超过 120 个字符运算符处换行时,运算符必须在新行的行首[建议] 不同行为或逻辑的语句集,使用回车隔开,更易阅读对于 if…else…、try…catch…finally 等语句,推荐使用在 } 号后添加一个换行 的风格,使代码层次结构更清晰,阅读性更好[强制] 在 if / else / for / do / while 语句中,即使只有一行,也不得省略块 {…} a++; a = b + c; if ('代码规范') { console.log('那你真棒'); } // 无分号 var obj = { key: value, // 尾逗号 }; function isAGoodMan() { return true; } callFunc(param1, this.obj[index += (count--)], param3); if (a > b) { some code... } // good if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin') || user.hasAuthority('delete-admin') ) { // Code } var result = number1 + number2 + number3 + number4 + number5; if (true) { } else if (false) { } else { } [强制] 函数定义结束不允许添加分号,函数表达式,分号是不允许省略if 结尾没分号 function a() { } var b = function () { };
命名
[强制] 常量:全部字母大写,单词间下划线分隔[强制] 类名 使用 名词,大驼峰[强制] 枚举变量 使用 Pascal 命名法,枚举的属性 使用 全部字母大写,单词间下划线分隔 的命名方式。[强制] 命名空间 使用 Camel命名法[建议] 函数名 使用 动宾短语[建议] boolean 类型的变量使用 is 或 has 开头[建议] Promise 对象 用 动宾短语的进行时 表达。 var MY_LOVE = '//www.4399.com'; class Person(name, age) { }; var TargetState = { READING: 1, READED: 2, APPLIED: 3, READY: 4, }; var isReady = true; function getUserInfo() { }; var loadingData = ajax.get('url'); loadingData.then(callback);
多用 let const,少用 varconst > let js 编译器加持字符串静态用' ' 动态用``数组/对象成员对变量赋值时,优先使用解构赋值 const arr = [1, 2, 3, 4]; // bad const first = arr[0]; const second = arr[1]; // good const [first, second] = arr; // bad function getFullName(user) { const firstName = user.firstName; const lastName = user.lastName; } // good function getFullName(obj) { const { firstName, lastName } = obj; } // best function getFullName({ firstName, lastName }) { } 单行定义的对象,最后一个成员不以逗号结尾。多行定义的对象,最后一个成员以逗号结尾。 const obj = {name:'zhangsan'} const obj = { name: 'zhangsan', } 箭头函数及时一个参数也要()class 代替 构造函数

谷歌 HTML/CSS 规范

CSS
CSS 引号 属性选择器和属性值用单引号,URI 的值不需要引号 (对单引号保持中立) @import url(//www.google.com/css/maia.css); html { font-family: 'open sans', arial, sans-serif; }

注释

[强制] 必须独占一行。// 后跟一个空格,缩进与下一行被注释说明的代码一致[建议] 避免使用 /…/ 这样的多行注释。有多行注释内容时,使用多个单行注释[强制] 文档注释前必须空一行。[建议] 自文档化的文档说明 what,而不是 how。
类型注释
[强制] 类型定义都是以{开始, 以}结束。常用类型如:{string}, {number}, {boolean}, {Object}, {Function}, {RegExp}, {Array}, {Date}[强制] 对于基本类型 {string}, {number}, {boolean},首字母必须小写 类型定义语法示例解释String{string}—Number{number}—Boolean{boolean}—Object{Object}—Function{Function}—RegExp{RegExp}—Array{Array}—Date{Date}—单一类型集合{Array.<string>}string 类型的数组多类型{(number|boolean)}可能是 number 类型, 也可能是 boolean类型允许为null{?number}可能是 number, 也可能是 null不允许为null{!Object}Object 类型, 但不是 nullFunction类型{function(number, boolean)}函数,形参类型Function带返回值{function(number, boolean):string}函数, 形参, 返回值类型参数可选@param {string=} name可选参数, =为类型后缀可变参数@param {…number} args变长参数, …为类型前缀任意类型{*}任意类型可选任意类型@param {*=} name可选参数,类型不限可变任意类型@param {…*} args变长参数,类型不限 /** 数据发送 ex:sendMessage({event,params}) * @param {string} event 事件名 * @param {Array|all} params 事件入参 根据数组顺序入参 */
文档注释
[强制] 文件顶部必须包含文件注释,用 @file 标识文件说明[建议] 文件注释中可以用 @author 标识开发者信息

开发者信息能够体现开发人员对文件的贡献,并且能够让遇到问题或希望了解相关信息的人找到维护人。通常情况文件在被创建时标识的是创建者。随着项目的进展,越来越多的人加入,参与这个文件的开发,新的作者应该被加入 @author 标识。

@author 标识具有多人时,原则是按照 责任 进行排序。通常的说就是如果有问题,就是找第一个人应该比找第二个人有效。比如文件的创建者由于各种原因,模块移交给了其他人或其他团队,后来因为新增需求,其他人在新增代码时,添加 @author 标识应该把自己的名字添加在创建人的前面。

@author 中的名字不允许被删除。任何劳动成果都应该被尊重。

业务项目中,一个文件可能被多人频繁修改,并且每个人的维护时间都可能不会很长,不建议为文件增加 @author 标识。通过版本控制系统追踪变更,按业务逻辑单元确定模块的维护责任人,通过文档与wiki跟踪和查询,是更好的责任管理方式。

对于业务逻辑无关的技术型基础项目,特别是开源的公共项目,应使用 @author 标识

/** * @file Describe the file * @author * author-name(mail-name@domain.com) * author-name2(mail-name2@domain.com) */ /** * @file Describe the file * @author author-name(mail-name@domain.com) * author-name2(mail-name2@domain.com) */
类注释
[建议] 使用 @class 标记类或构造函数使用 @constructor 来标记构造函数使用 @extends 标记类的继承信息[强制] 类的属性或方法等成员信息使用 @public / @protected / @private 中的任意一个,指明可访问性。 /** * 类描述 * * @class * @extends Developer */ var Fronteer = function() { Developer.call(this); /** * 属性描述 * * @type {string} * @private */ this._level = 'T12'; // constructor body }; util.inherits(Fronteer, Developer); /** * 方法描述 * * @private * @return {string} 返回值描述 */ Fronteer.prototype._getLevel = function() {};
函数/方法注释
[强制] 函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识[强制] 参数和返回值注释必须包含类型信息和说明。[建议] 当函数是内部函数,外部不可访问时,可以使用 @inner 标识。 /** * 函数描述 * * @param {Object} eventList 参数描述 * @return {Function} 返回值描述 */ function addMethods(eventList) { return function(methodName, fnc) { if (fnc instanceof Function) { eventList[methodName] = fnc; } }; }
事件注释
[强制] 必须使用 @event 标识事件,事件参数的标识与方法描述的参数标识相同 /** * 事件描述 - 值变更时触发 * * @event * @param {Object} e e描述 * @param {string} e.before before描述 * @param {string} e.after after描述 */ onchange: function (e) { }
常量注释
[强制] 常量必须使用 @const 标记,并包含说明和类型信息 /** * 常量说明 * * @type {string} */ const REQUEST_URL = 'myurl.do';
细节注释
对于内部实现、不容易理解的逻辑说明、摘要信息等,我们可能需要编写细节注释。[建议] 细节注释遵循单行注释的格式。说明必须换行时,每行是一个单行注释的起始。[强制] 有时我们会使用一些特殊标记进行说明。特殊标记必须使用单行注释的形式。 一些常用标记: TODO: 有功能待实现。此时需要对将要实现的功能进行简单说明。 FIXME: 该处代码运行没问题,但可能由于时间赶或者其他原因,需要修正。此时需要对如何修正进行简单说明。 HACK: 为修正某些问题而写的不太好或者使用了某些诡异手段的代码。此时需要对思路或诡异手段进行描述。 XXX: 该处存在陷阱。此时需要对陷阱进行描述。 function fn() { // 这里是细节说明 // HACK 此处没问题,但是有问题 // FIXME 赶时间写死数 }
多行注

快捷键:shift + options + a

@param @argument 指定参数名和说明来描述一个函数参数 @returns 描述函数的返回值 @author 指示代码的作者 @deprecated 指示一个函数已经废弃,而且在将来的代码版本中将彻底删除。要避免使用这段代码 @see 创建一个HTML链接,指向指定类的描述 @version 指定发布版本 @requires 创建一个HTML链接,指向这个类所需的指定类 @throws @exception 描述函数可能抛出的异常的类型 {@link} 创建一个HTML链接,指向指定的类。这与@see很类似,但{@link}能嵌在注释文本中 @fileoverview 这是一个特殊的标记。如果在文件的第一个文档块中使用这个标记,则指定该文档块的余下部分将用来提供这个文件的概述 @class 提供类的有关信息,用在构造函数的文档中 @constructor 明确一个函数是某个类的构造函数 @type 指定函数的返回类型 @extends 指示一个类派生了另一个类。JSDoc通常自己就可以检测出这种信息,不过,在某些情况下则必须使用这个标记 @private 指示一个类或函数是私有的。私有类和函数不会出现在HTML文档中,除非运行JSDoc时提供了–private命令行选项 @final 指示一个值是常量值。要记住JavaScript无法真正保证一个值是常量 @ignore JSDoc忽略有这个标记的函数

/** * @fileOverview 简单的类对象标注示例 * @author <a href=”llying.javaeye.com”>llying</a> * @version 0.1 */ /** 方法说明 * @author llying * @constructor Person * @description 一个Person类 * @see The <a href=”#”>llying</a >. * @example new Parent(“张三”,15); * @since version 0.1 * @param {String} username 姓名 * @param {Num} age 年龄 */ function Person(username,age) { /** * @description {Sting} 姓名 * @field */ this.username = username; /** * @description {Num} 年龄 * @field */ this.age = age; /** * @description 弹出say内容 * @param {String} content 内容 */ this.say = function(content) { alert(this.username+” say :+content); } /** * @description 返回json格式的对象 * @return {String} json格式 * @see Person#say */ this.getJson = function(){ return{name:+this.username+,age”+this.age+}; } }
最新回复(0)