提升项目可维护性的一些习惯
软件生命周期中80%的成本消耗在了维护上
在前端编码时,经常遇到多人协作的情况,一些工具可以很好地提升代码维护成本。这里把最近的学习中遇到的几个分享在下面。
EditorConfig
EditorConfig是一套在编辑器间统一代码格式的解决方案。一个EditorConfig项目由.editorconfig
自定义文件格式。相应的编辑器插件会按照配置文件格式化文档。
EditorConfig的语法类似.gitignore
,比较好理解。下面是官网给出了规定Python和JavaScript文件格式的.editorconfig
文件样例
1 | # EditorConfig is awesome: http://EditorConfig.org |
不过通常的项目用不到这么复杂的配置文件。这里是Angular的配置文件,这里是曾经Vue.js的配置文件。官网给出了完整的使用EditorConfig的工程列表。
存放位置
打开一个文件时,EditorConfig插件会去打开文件的目录和其每一级父目录查找.editorconfig
文件,直到有一个配置文件root=true
。
读取顺序从上到下,路径最短的文件最后被读取,优先级最高。
关于文件格式
EditorConfig文件使用INI格式,目的是可以和Python Config Library兼容。每个分段(原文:‘section’)由一个globs开头。斜杠(/
)作为路径分隔符,#
或者;
作为注释。注释应该单独占一行。EditorConfig文件使用UTF-8格式、CRLF或LF作为换行符。
通配符
EditorConfig目前支持下面这些通配符:
*
匹配除/之外的任意字符串**
匹配任意字符串?
匹配任意单个字符[name]
匹配name字符[!name]
匹配非name字符{s1,s3,s3}
匹配任意给定的字符串(0.11.0起支持){num1..num2}
匹配num1和num2间的整数
最后特殊字符可以用\
转义.
属性
目前普遍支持的属性包括下面这些:
- root:表明是最顶层的配置文件,发现设为true时,才会停止查找.editorconfig文件。
- indent_style:可以选择tab或space
- indent_size:设置整数表示规定每级缩进的列数或空格数。如果设定为tab,则会使用tab_width的值(如果已指定)。
- tab_width:设置整数用于指定替代tab的列数。默认值就是indent_size的值,一般无需指定。
- end_of_line:定义换行符,支持lf、cr和crlf。
- charset:编码格式,支持latin1、utf-8、utf-8-bom、utf-16be和utf-16le,不建议使用uft-8-bom。
- trim_trailing_whitespace:设为true表示会除去换行行首的任意空白字符,false反之。
- insert_final_newline:设为true表明使文件以一个空白行结尾,false反之。
支持情况
目前已有大量的IDE或文本编辑器支持EditorConfig配置。有些不需要下载插件,有些则需要。详情可参见官网。
eslint
ESLint是非常流行的一个JavaScript代码检查器。便于在运行前检查出代码中潜在的错误。它的作者是Nicholas Zakas,红宝书的作者。网站也有中译版。
安装
安装eslint前,需要有node.js的环境,之后通过npm安装即可
1 | npm install -g eslint |
当然也可以本地安装
1 | npm install eslint --save-dev |
配置
安装完成后,需要在项目目录下生成.eslintrc
配置文件才可以使用eslint
命令。这一步可以通过eslint --init
按着引导完成,也可以根据自己需要修改。eslint推荐使用了一些规则,可以通过下面这样开启(extends
的属性还可以是all
,即启用所有规则,不推荐使用):
1 | { |
配置项里,还可以通过env
指令代码环境,像下面这样:
1 | { |
同样,具体的规则也是可以配置的,每个规则的配置项都有一个默认值,规则键对应的值为数值时,是下面的意思
- 0 Disable the rule
- 1 Warn about the rule
- 2 Throw error about the rule
对应的值为数组时,则会更改规则配置项的原默认值,如下面例子中的quote
规则:
1 | { |
关于eslint的更多配置项,可参考官网。
若项目中使用到了ES6语法,则还需要安装babel-eslint
包,并指定.eslintrc
中parser
和parseOptions
两项。具体的配置大概是下面这样:
1 | { |
ESLint 支持几种格式的配置文件:
- JavaScript - 使用
.eslintrc.js
然后输出一个配置对象。 - YAML - 使用
.eslintrc.yaml
或.eslintrc.yml
去定义配置的结构。 - JSON - 使用
.eslintrc.json
去定义配置的结构ESLint的JSON文件允许JavaScript风格的注释。 - Deprecated - 使用
.eslintrc
,可以使JSON也可以是YAML。 - package.json - 在
package.json
里创建一个eslintConfig
属性,在那里定义你的配置。
如果同一个目录下有多个配置文件,ESLint只会使用一个,优先级是上面列表从上到下的顺序。
注释
可以在文件中书写注释在运行时更改eslint的配置(实际上几乎所有的配置项都可以在注释中通过eslint-xxx
这样的形式修改)。
当文件中出现已考虑到的规则例外时,可以通过/*eslint quotes: ["error", "double"]*/
或/*eslint eqeqeq: 0, curly: 2*/
这样的形式临时添加例外。
当文件出现不想被检测到的规则例外时,可以通过/*eslint-disable*/
和/*eslint-enable*/
避免警告。单行例外可以使用/*eslint-disable-line*/
更详细的配置可以参见文档。
sublime插件
上面说的这些工作,在配置完成后,需要在命令行中通过eslint xxx.file
这样的形式lint。借助编辑器的插件可以获得可视化的lint结果,妈妈再也不用担心我的找不到错误了(误)。因为个人原因,下面仅以sublime为例。
下载eslint for sublime插件前,需要下载Sublime-Linter。因为前者利用了后者作为lint的平台。在Ctrl+Shift+P
找到Package Controll: Install Packages
后(什么?你没有装Package Control?),搜索Sublime-Linter下载安装即可。完成后,可以在Prefences -> Package Settings
或Tools
选项卡中找到Sublime Linter的身影。
之后同样的方式搜索Sublime-contrib-eslint下载安装即可。建议在安装前去官网看看,避免遇到不必要的问题。
这些工作完成后了,可以选择SublimeLinter的mode为load/save,之后在文件载入和保存时都会对文件进行lint操作,并将违背规则的地方标出。
Commit message规范
git每次修改后需要填写commit message才能提交。这一步可以通过给git commit
添加-m
参数完成,像下面那样,也可以在git commit
打开的vi界面下填写多行文本。
1 | git commit -m 'some commit message' |
git并没有对commit message的风格做出规范,可以用中文,可以用英文,甚至当你不知道该写些什么的时候,还可以去某些网站参考。
但是在团队协作中,还是建议清晰明了地书写此次commit的目的和做的修改。实际上,commit message规范这种事一直在做。比如egg.js, Angular或者更加简洁的规范:这样或这样。其中Angular的规范应用较广,还有commitizen工具帮助生成changelog和检查commit message样式。
格式
根据Angular的规范,commmit message包括三个部分:Header, Body和Footer。其中Header是必需的,Body和Footer则不是。模板像下面这样:
1 | <type>(<scope>): <subject> |
模板中,type为提交commit的类型,只有下面这些选择:
- feat: 新功能
- fix: 修复问题
- docs: 修改文档
- style: 修改代码格式,不影响代码逻辑
- refactor: 重构代码,理论上不影响现有功能
- perf: 提升性能
- test: 增加修改测试用例
- chore: 修改工具相关(包括但不限于文档、代码生成等)
- deps: 升级依赖
其中前两种commit一定会出现在changelog中。
scope为修改文件的范围(包括但不限于doc, middleware, core, config, plugin);subject用一句话清楚的描述这次提交做了什么,首字母小写;body作为subject的补充,增加原因和目的等具体内容,可以不写。
footer部分中,当有非兼容修改(Breaking Change)时必须在这里描述清楚,或者描述关联issue。下面是一个完整的例子:
1 | fix($compile): [BREAKING_CHANGE] couple of unit tests for IE9 |
代码用于撤销此前commit所做修改时,message用revert开头,后面跟着被撤销commit的Header。像下面这样:
1 | revert: feat(pencil): add 'graphiteWidth' option |
如果当前commit与被撤销的commit,在同一个发布(release)里面,那么它们都不会出现在Change log中。
Commitizen
Commitizen就是方便你做出上面提交的工具,可以通过npm安装。
1 | npm install -g commitizen |
安装完成后,使用git cz
代替git commit
命令来提交改动。之后会出现指引帮助你完成一次合格的提交。
commitizen的插件cz-conventional-changelog可以帮助我们完成commit message,首先通过下面的命令安装并配置cz-conventional-changelog。
1 | npm install -g cz-conventional-changelog |
之后运行下面的命令即可
1 | commitizen init cz-conventional-changelog --save-dev --save-exact |