当前位置: 首页 > 科技观察

前端架构师神功,统一团队代码风格的三种方法

时间:2023-03-16 00:31:24 科技观察

大家好,我是杨成功。本文从代码标准化、代码检查、代码格式化、编辑器自动化等方向介绍代码标准化在我们团队的实际应用。大纲预览本文介绍的内容包括以下几个方面:理解代码规范制定和统一规范魔术1:ESLint魔术2:Prettier魔术3:VSCode附录:命名和项目结构规范理解代码规范首先,思考两个问题:什么是代码规范?为什么需要代码规范?如果你是有经验的前端开发者,你一定接触过这样的老项目:变量名是abc,fds,随意,或者name1,name2用数字命名,这样的变量不加注释,鬼不要甚至不知道它的作用。这种代码是典型的非标准代码。这样的代码除了让我们的开发人员烦躁之外,最主要的问题就是大大降低了团队协作的效率和程序质量。在团队协作的过程中,当组里的其他人需要使用或者review你的代码时,看到这种情况,除了喷你,还花很多时间去理解你写的东西。同时,极易造成变量冲突、未知隐患、调试困难等问题,甚至一个程序员的编码态度和专业程度可见一斑。当然,代码规范包括很多方面,变量命名规范只是最基本的规范。违规行为越多,节目质量越低,团队合作效率越低。在了解了代码不规范以及代码不规范带来的问题之后,作为前端架构师,我们要思考三个问题:如何制定标准?如何统一团队的规范?如何检测规范?制定和统一规范像上面这样的变量随意命名在早期的前端项目中是很常见的。因为早期项目规模大,团队规模有限,没有命名规范意识。好像随便起个名字也没什么大问题,只要不重复就行。但是随着前端项目越来越大越来越复杂,不规范导致的问题越来越多,这种规范意识也逐渐被重视起来。经过社区的不断发展,命名包括以下规范:下划线命名:user_name破折号命名:user-name小驼峰命名:userName大驼峰命名:UserName有谱。而且,这些规范目前已被大多数开发人员所接受。如果不按规范命名,可能会被同事投诉!当规范成为普遍共识后,大家根据自己的喜好使用不同的规范,逐渐形成了自己的编码习惯。在一个团队中,每个开发人员往往都有自己的编码习惯。然而,这又成了一个问题。以变??量为例:在团队中,有些人习惯用下划线命名变量,比如user_name;有些人习惯用驼峰命名变量,比如userName。这两种命名方式都是正确的,符合规范,但是会造成团队代码风格的混乱,无法统一。那为什么要统一呢?统一的好处很多。比如我们统一规定:命名变量使用下划线,命名方法使用小驼峰命名法。那么在团队工作的时候,大家看到下划线就知道是变量,看到驼峰就是方法。十个人写的代码,写的是一个人的风格,无需了解其他编码风格,实现无障碍协作。十个人的代码能写出一个人的风格,这是理想状态,但靠监督和自觉几乎不可能实现。怎么做?以下是本文的重点:实现代码规范的三招。技能一:上面提到的ESLint,团队合作开发项目,因为每个人的编码习惯不同,会写出各种各样的代码。这样的代码很乱,很难维护。所以我们希望有这样一个工具,可以制定出一套比较完整和全面的规范。如果大家的编码不符合规范,程序就会警告甚至报错。使用这个工具可以强制团队成员遵守统一的代码风格。这个工具是有的,我们都听说过,就是大名鼎鼎的ESLintESLint有两个能力:检查代码质量,比如是否有定义但未使用的变量。检查代码风格、换行、引号、缩进等。这两项能力几乎涵盖了大部分代码规范,具体规范可配置,允许团队自定义自己喜欢的代码风格。自定义规范后,ESLint会在项目运行或热更新时自动检查代码是否符合规范。问:ESLint检查与TypeScript检查有何不同?TypeScript只检查类型错误,而ESLint检查样式错误。尝试先在项目下安装ESLint:$npminstalleslint--save-dev然后运行命令初始化配置:eslint--initeslint是一个交互式命令,可以上下切换选择适合项目的选项;完成后,将生成一个.eslintrc.json文件。.eslintrc.json的基本配置如下:{"env":{"browser":true,"es2021":true,},"extends":["eslint:recommended"],"parserOptions":{"ecmaVersion":12,"sourceType":"模块",},"规则":{},};此基本配置包含一组默认推荐配置,在eslint:recommended扩展中定义。React配置React在默认配置的基础上,还有一套推荐语法配置,定义在plugin:react/recommended。如果你的前端框架是React并且你想定义eslint规范,那么在基础配置中添加如下标记+号的配置就足够了:{"env":{"browser":true,"es2021":true},"extends":["eslint:recommended",+"plugin:react/recommended"],"parserOptions":{+"ecmaFeatures":{+"jsx":true+},"ecmaVersion":12,"sourceType":"module"},+"plugins":[+"react"+],"rules":{}};React+TS配置如果React支持TS,需要额外添加一些配置:{"env":{"browser":true,"es2021":true},"extends":["eslint:recommended","plugin:react/recommended"+"plugin:@typescript-eslint/recommended"],+"parser":"@typescript-eslint/parser","parserOptions":{"ecmaFeatures":{"jsx":true},"ecmaVersion":12,"sourceType":"module"},"plugins";:["反应",+"@typescript-eslint"],"规则":{}};代码检查上面定义好规范后,我们现在写一段代码,执行规范检查,新建一个index.js文件,写入Inputcontent:consta='13'functionadd(){return'1'}透视js的,这两行代码都没有问题。然后我们运行检查命令:$npxeslintindex.js会在控制台看到错误:2:7error'a'isassignedavaluebutneverusedno-unused-vars4:10error'add'isdefinedbutneverusedno-unused-vars2problems(2errors,0warnings)错误的含义就是变量a和函数add已经声明但是没有使用,说明代码不符合约定的规范。这种异常也很常见。在脚手架搭建的项目中使用npmrundev和npmstart时,会执行上面的检查命令。上面ESLint规范中提到,ESLint可以自定义检查规范,定义在.eslintrc.json配置文件的rules对象下。比如定义一个规范,字符串必须使用双引号:{"rules":{"quotes":["error","double"]}}定义后,如果你的代码对字符串使用单引号,ESLint会报错。quotes表示引号规范,它是众多规范中的一种,它的值是一个数组。数组的第一项是错误级别,它是以下3个值之一:“off”或0-关闭规范“warn”或1-警告级别规范“error”或2-错误级别规范第二项该数组为trueSpecifications,具体完整的specifications参考这里打开上面的网页,绿色对勾表示已经配置。需要定制,直接写在规则里面。技能二:Prettier在上一步中,我们使用了ESLint来实现规范的制定和检查。当开发者保存一段代码后,项目会自动执行eslintcheck命令检查代码,检查异常后检查控制台输出,待开发者修复异常后继续开发。如果你配置的编码规范复杂严格,比如字符串必须用单引号,代码末尾必须用分号,换行必须是2个tab不带空格。如此详细的规范,在开发过程中难免会出现不一致的情况。这时候控制台会频繁报错,开发者会频繁修复一个空格和一个标点符号,时间一长就烦死了。正因为如此,虽然在脚手架生成的项目中ESLint是默认开启的,但是很多人在使用之后觉得烦人且效率低下,于是手动关闭了ESLint。那么,有没有更高效的方式,让大家非常快速的写出完全符合规范的代码呢?没错,就是第二招:PrettierPrettier是目前最流行的代码格式化工具,主要功能就是格式化代码。什么是格式化?上面我们使用了ESLint来自定义编码规范。当检测到不规范的代码时,会提示异常,然后我们的开发人员需要按照提示手动修复不规范的地方。格式化的强大之处在于可以根据规范一键自动修复不规范的代码。听起来很刺激,让我们试一试。先在项目下安装:$npminstallprettier--save-dev然后新建一个.prettierrc.json文件:{"singleQuote":true,"semi":true}这个配置文件和上面ESLint下的规则配置是一致的,也就是定义代码Specifications——没错,Prettier也支持定义规范,然后根据规范格式化代码。列举Prettier常见的规范配置:{"singleQuote":true,//是否单引号"semi":false,//语句末尾使用分号(默认true)"printWidth":100,//一行中的字符数,超过则换行(默认80)"tabWidth":2,//每个tab相当于多少个空格(默认2)"useTabs":true,//是否换行usetabsforindentation(defaultfalse)"trailingComma":"all",//多行使用尾随逗号(defaultnone)"bracketSpacing":true,//在对象文字的大括号之间使用空格(defaulttrue)"jsxBracketSameLine":false,//>inmulti-lineJSX放在最后一行的末尾,而不是另起一行(默认false)"arrowParens":"avoid"//箭头函数的参数是否只有一个参数有括号(默认避免)}定义好配置后,我们在索引.js文件中写入内容:consta="13"functionadd(){return"1"}然后在termi中运行格式化命令nal:$npxprettier--writeindex.js格式化后,看index.js文件变成这样:consta='13';functionadd(){return'1';}看变化,双引号自动变成单引号,并且在行尾自动添加分号,正好符合配置文件中定义的规范。超级加享受!终于不用再手动修复不规范的代码了,一条命令搞定!以上是格式化一个文件,当然也支持批量格式化文件。批量格式化通过模糊匹配查找文件。它更常用。建议在script脚本中定义,如下://package.json"scripts":{"format":"prettier--write\"src/**/*.js\"\"src/**/*.ts\"",}Prettier还支持对不同后缀的文件设置不同的代码规范,如下:{"semi":false,"overrides":[{"files":"*.test.js","options":{"semi":true}},{"files":["*.json"],"options":{"parser":"json-stringify"}}]}问:什么是ESLint和Prettier的区别?相同点:两者都可以定义一套代码规范。不同点:ESLint在检查时会提示代码不规范的错误;Prettier会直接按照规范格式化代码。因此,ESLint和Prettier定义的规范必须一致,不能冲突。技巧三:在VSCode上,我们使用ESLint和Prettier,通过一条命令实现代码规范制定、代码规范检查、代码格式化,非常容易统一团队代码风格。然而,突破效率的挑战是无限的。这时又有朋??友说:虽然容易,但是检查代码还是要靠检查命令,格式化代码也要靠格式化命令,不够优雅。嗯,不够优雅,那么有没有优雅的解决方案呢?答案是肯定的。就是我们的第三招——VSCode强大的插件VSCode对于我们前端来说并不陌生,是我们每天陪伴的开发利器。目前VSCode几乎统一了前端圈的编辑,功能强大,深受好评。既然能得到如此广泛的认可,肯定有它的优势。除了重量轻、启动速度快之外,VSCode最强大的地方在于它丰富多样的插件,可以满足不同用户的各种需求。在众多插件中,ESLint是一个非常强大的插件。没错,这个插件就是VSCode上ESLint支持的同名插件。截图如下:安装这个插件后,需要在终端执行eslint命令查出的异常现在直接标注在你的代码上了!即使你输入了错误的符号,插件也会实时跟踪你的错误,然后给出标记和异常提醒。这样大大提高了开发效率,再也不用执行命令检查代码了,谁说不优雅。既然编辑器有ESLint插件,那么它是否也有Prettier插件呢?你猜对了,当然有插件。该插件的全称是Prettier-Codeformatter。截图如下,在VSCode中搜索安装即可。安装Prettier插件后,它将充当编辑器的格式化程序。在要格式化的代码中右击,可以选择Prettier,对当前代码进行格式化。如果想让Prettier自动化,还需要在编辑器中进行配置。编辑器配置VSCode中有一个用户设置setting.json文件,里面保存了用户对编辑器的自定义配置。这个配置非常丰富,具体见官网。首先,我们在此配置中将Prettier设置为默认格式化程序:{"editor.defaultFormatter":"esbenp.prettier-vscode","[javascript]":{"editor.defaultFormatter":"esbenp.prettier-vscode"}}设置完这一步,重点来了!我们来配置保存文件的自动格式化:{"editor.formatOnSave":true}配置后,神奇的事情发生了:当你写完代码保存后,发现你正在编辑的文件立马被格式化了。也就是说,不管你的代码是不是按照规范写的,保存的时候它都会自动给你格式化成规范的代码。这一步其实就是在保存文件的时候自动执行格式化命令。因为我们上面配置了默认的formatter为Prettier,现在配置了formattingonsave,相当于把文件save和prettier命令连接起来了。至此,在三大技能的加持下,我们实现了自动查码和自动格式化。现在您无需在编码时考虑任何格式问题。只要你正常保存,编辑器会自动帮你做好这些事情。共享编辑器配置上面我们对编辑器进行了一段时间的配置,终于实现了自动格式化。现在我们需要将这些设置同步给团队的其他成员,怎么办,是否需要一一配置?不要惊慌,不要打扰。VSCode的设置分为两类:用户设置:应用于整个编辑器工作区设置:应用于当前目录/工作区这两种设置的配置内容是完全一样的,区别只是优先级的不同。如果您打开的项目目录包含工作区设置,则工作区设置将覆盖当前用户设置。所以如果我们要将设置同步给团队的其他成员,我们不需要更改用户设置,只需要在项目目录下新建一个工作区设置即可。添加工作区设置方法:在项目根目录下新建一个.vscode/setting.json文件,在这里写一个统一的编辑器配置。所以我们在这里写上上面的Prettier配置来实现共享。附录:命名和项目结构规范上面介绍了代码规范、代码检查和代码格式化,统一代码风格已经很全面了。在团队开发过程中,我们也积累了一些不会写入配置文件的规范。这些规范在团队中也非常重要。这部分也算是我们团队规范的分享。主要有两部分:命名约定和项目结构规范。命名规范文章开头提到的命名规范是变量的四种命名规范。但是我们也对在哪里使用哪个规范达成了协议。变量命名:下划线user_idCSS-Class命名:中破折号user-id方法函数命名:小驼峰userIdJS-Class命名:大驼峰UserId文件夹命名:中破折号user-id文件夹组件命名:中破折号User-id组件导出命名:bighumpUserId项目结构规范项目结构规范主要是指src文件夹下的结构组织。|--src|--index.tsx#入口文件|--assets#静态资源目录|--components#公共组件目录||--header|||--index.tsx|||--index.less|--stores#状态管理目录,对应页面结构||--admins|||--index.tsx#状态文件|||--types.ts#定义状态类型||--index.tsx|--pages#page目录,对应stores结构||--admins|||--index.tsx|||--index.less|--request||--index.ts#axios实例,全局请求处理|--router||--home.tsx||--index.tsx||--root.tsx|--styles#globalstyle||--common.less||--index.less|--utils#工具目录|--index.ts