第一部分:工具
1.1 代码格式化
使用 Eslint + StyleLint + Prettier + husky + lint-staged 提高前端项目质量和统一项目代码风格:
- ESLint 是一款用于查找并报告代码中问题的工具
- Stylelint 是一个强大的现代 CSS 检测器
- Prettier 是一款强大的代码格式化工具,支持多种语言
- lint-staged 是一个在 git 暂存文件上运行 linters 的工具
- husky 是 Git Hook 工具,可以设置在 git 各个阶段触发设定的命令
不同的团队/项目/个人有不同的代码规范,可视情况自行按需求配置。在完整整体配置后,最终执行效果如下,我们在本地提交代码时就能够扫描出潜在的错误,并强制将其修改后才能提交,这样就不会将问题代码携带到线上,就能保证线上代码至少不会存在低级的程序错误,显式收敛差异性,优化可读性与可维护性:
- 待提交的代码 git add 添加到暂存区;
- 执行 git commit;
- husky 中 pre-commit 钩子函数被调用,执行 lint-staged;
- lint-staged 只对当前 add 到 git stage 区的文件进行扫描操作;
- 如果有错误则停止任务,同时打印错误信息,等待修复后再执行 commit;
- 如果没有错误的话,则可完成提交
1.1.2 编辑器扩展
我们期望代码实时保存时就能完成代码格式化,时刻是一个整洁的代码(保持优雅)。为了实现这个效果,可以在 VSCode 中安装 Eslint、Prettier、Stylelint 等插件,并设置文件保存时就进行格式化,参考配置如下:
json
{
"eslint.run": "onSave",
"eslint.format.enable": true,
"eslint.options": {
"extensions": [".js", ".vue", ".ts", ".tsx"]
},
"eslint.validate": ["javascript", "typescript", "vue"],
"stylelint.validate": ["css", "less", "postcss", "scss", "sass", "vue"], // 保存时按照哪个规则进行格式化
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.eslint": true
},
"files.autoSave": "afterDelay", // 文件自动保存
"files.autoSaveDelay": 2000, // 2s 后文件自动保存}
1.1.3 CSS 扩展[CSScomb]
前面提到的 prettier 对于 css 也能进行格式化,但它不能做到对 css 样式进行更加细致地格式化,例如书写顺序就无法通过 prettier 进行格式化。我们一般会以布局定位、自身属性、文本属性等为顺序进行规范要求,但在写的时候可能不太会注意,顺序可能写的都比较主观随意。同时,如果 CSS 代码一写就是几百上千行,很难组织起来,也很难进行阅读和维护。这个时候就需要 CSSComb 的帮助了,其可以对 CSS 进行排序和组织。其安装步骤如下:
- 安装 CSScomb 插件
- 在 VSCode 的文件--->首选项--->设置中加入 "csscomb.preset": {}
- 在根目录下添加名为 .csscomb.json 的文件,可参考官方推荐配置
- Cmd+Shift+P 选择 CSSComb format 即可格式化
除了 CSSComb 之外,还可以通过 stylint 的 stylelint-order 插件和 postcss 的 sorting plugin 等方案来实现相同效果。通过 CSS 排序和组织的优化,阅读 CSS 代码更加直观,快速定位,易于维护;样式属性的书写顺序对网页加载性能也有一定优化
1.2 编辑器设置[EditorConfig for VS Code]
以前遇到过一个情况,通过 git diff 在查看文件变化情况的时候,发现文件的全部内容都被标识了修改,但实际内容并未进行修改,后来经过排查才发现是 Mac 系统和 window 系统下编辑器的换行类型是不一样的,一个 lf,一个 crlf,从而导致了 git 在识别变化的时候认为全部内容都进行了变动,那么这对样的变动提进行交是毫无意义甚至一定程度上是错误的。面对这种场景,我们可以借助 EditorConfig 来维护不同开发人员、不同编辑器的编码风格,在根目录下增加 .editorconfig 文件进行配置即可。参考配置如下:
json
# Editor configuration, see http://editorconfig.org
# 表示是最顶层的 EditorConfig 配置文件root = true
[*] # 表示所有文件适用charset = utf-8
# 设置文件字符集为 utf-8indent_style = space
# 缩进风格(tab | space)indent_size = 2
# 缩进大小end_of_line = lf
# 控制换行类型(lf | cr | crlf)insert_final_newline = true
# 始终在文件末尾插入一个新行trim_trailing_whitespace = true
# 去除行尾的任意空白字符
1.3 commit 提交设置
多人协作开发在提交代码的时候不能保证每个人都对提交的信息进行准确的描述,可能存在偷懒的话就随便写一个 git message 的情况,因此会出现提交信息紊乱、风格不一致的情况,通过查看提交记录很难直观看出当前代码的改动。同样,Git Commit 也是能够整洁优雅的,尽可能准确描述 commit 相关信息,在后期维护、追踪项目进度等各方面都会受益。Conventional Commits 约定式提交规范就是一种用于给提交信息增加人机可读含义的规范。同样,懒是第一生产力,我们依旧能够借助工具来实现约定式提交规范,commitizen + cz-customizable + commitlint.
- commitlint:检查您的提交消息是否符合 conventional commit format
- commitizen:帮助撰写规范 commit message 的工具
- cz-customizable:自定义配置 commitizen 工具的终端操作
- commitlint-config-cz:合并 cz-customizable 的配置和 commitlint 的配置
- 各工具的参考配置可详见《拯救强迫症!前端统一代码规范》,不同的团队/项目/个人有不同的代码规范,可视情况自行按需求配置。在完整整体配置后,最终执行效果如下:
当我们的 git message 具有一定规范的时候,我们可以在 git history 中快速定位关键信息,可以通过 type 过滤出想要查找的信息,理想情况下如果愿意写更加详细的具体描述可以清晰的看出某次提交的目的和影响,也可以根据规范的提交信息快速生成 log 从而方便我们追踪项目和把控进度。
经验
2.1 文档书写习惯
文档对于项目开发、维护、学习、重构、以及知识管理都非常重要,目前感觉大家还是有很大一部分精力需要在 docs 上写文档和看文档。如何写好文档很难直观去说,因为文档的主观性比较强,跟撰写者的逻辑能力啊语言表达能力啊等各方面有关
2.2 命名
我们在各个地方都要命名,给变量、参数、函数名命名,给文件、组件命名......不知道大家有没有为了给变量啊方法啊取个名字而头疼?至少我对命名是比较头疼的。那么为什么会头疼呢?因为命名很重要啊(一句废话)。那么命名又为什么重要呢?命名承载的是最直接的信息,好的命名往往就是最好的注释,命名与功能相匹配能让我们一眼就能够知道他的功能,阅读体验简直不要太好啊,同时维护修改体验也会提高。命名常用的几个策略与技巧:
- min-length && max-information 原则,使用最少的字符表达最多的信息;但是语义完整性要优于名称长度,名字简洁的前提是表达清楚意思了
- 尽量使用开发领域和计算机科学领域常用的词汇和单词缩写,不要用生僻或专业的术语和缩写,可能你知道的别人并不懂(世界的参差请体谅)
- 善用翻译工具,不会写的英文马上谷歌翻译,绝不瞎造!!!
- 多学习参考开源项目的命名,指路 👉 unbug.github.io/codelf/
- 类名应该使用名词或名词短语,函数命名尽量使用动词开头或动名词
- 函数方法常用的动词参考如下
json
add / update / delete / detail / get 增删改查
is / has / contains 等表示逻辑的词语可以代替动词
get 获取/set 设置
add 增加/remove 删除
create 创建/destory 移除
start 启动/stop 停止
open 打开/close 关闭
read 读取/write 写入
load 载入/save 保存
create 创建/destroy 销毁
begin 开始/end 结束
backup 备份/restore 恢复
import 导入/export 导出
split 分割/merge 合并
inject 注入/extract
提取attach 附着/detach
脱离bind 绑定/separate
分离view 查看/browse 浏览
edit 编辑/modify 修改
select 选取/mark 标记
copy 复制/paste 粘贴
undo 撤销/redo 重做
insert 插入/delete 移除
add 加入/append 添加
clean 清理/clear 清除
index 索引/sort 排序
find 查找/search 搜索
increase 增加/decrease 减少
play 播放/pause 暂停
launch 启动/run 运行
compile 编译/execute 执行
debug 调试/trace 跟踪
observe 观察/listen 监听
build 构建/publish 发布
input 输入/output 输出
encode 编码/decode 解码
encrypt 加密/decrypt 解密
compress 压缩/decompress 解压缩
pack 打包/unpack 解包
parse 解析/emit 生成
connect 连接/disconnect 断开
send 发送/receive 接收
download 下载/upload 上传
refresh 刷新/synchronize 同步
update 更新/revert 复原
lock 锁定/unlock 解锁
check out 签出/check in 签入
submit 提交/commit 交付
push 推/pull 拉
expand 展开/collapse 折叠
begin 起始/end 结束
start 开始/finish 完成
enter 进入/exit 退出
abort 放弃/quit 离开
obsolete 废弃/depreciate 废旧
collect 收集/aggregate 聚集
2.3 代码注释
代码注释一直是一个比较有争议的问题,什么时候应该写注释?什么时候不用写注释?注释应该写到什么具体程度?或者有没有什么好的写注释经验方式?欢迎大家评论讨论。个人主要遵循几个原则:
- 任何觉得自己或他人可能看不懂需要写注释的第一步永远是想想能不能改进下变得易懂!
- 反问自己一句:三个月后自己能不能看懂这段代码?觉得可能会看不懂就一定要写注释!
- 反问自己一句:别人能不能看懂这段代码?觉得可能会看不懂了就一定要写注释!
- 能通过命名来表达意思的就不需要再多此一举写注释,包括但不限于方法名和参数名等!
总结
对于自身来说: 强迫自己养成良好的编码习惯,能够高质量输出代码。对于他人/团队来说:1、降低了新成员融入成本,也降低了学习和协作成本,优雅的代码让人阅读起来身心愉悦。2、- 风格统一的代码能够方便做 CR,也提高了代码的可维护性,部分情况也能提高性能。最终的目的都是期望能有一个优雅整洁的代码