前言
作为一个开发者或者管理者,团队项目的代码质量管理和控制是非常重要的。
本篇文章,我以一个开发者的视角,来分享了下团队代码规范从0到1的一个过程,目前已实现自动化的检测和平台展示。主要是记录了下个人在开发过程中的一些思考。如果能给到你一些借鉴,那么荣幸之至。
先列个大纲吧:
为什么要写一个,而不用现有开源的,区别是什么,价值是什么,代价是什么?确定了要搞,那么如何下手?可能会遇到哪些难点、阻碍;统一共识,统计技术栈,标准先行关于eslint配置文件的一些key解释,网上很多,但你就别去搜了,在这里我把最可能需要了解的解释下迭代第一版,规则罗列迭代第二版,npm包按照js vue2 vue3 react ts的分类,进行"搭积木"式使用使用github actions,自动发布。推广,团队的脚手架内置 比如 handy
凡事预则立不预则可能废,暂时计划年前更新完此系列,奢望目标是阅读2000,超过之前做的一篇翻译文阅读。也算是对2023年画一个小句号。
上面两段话是我去年写的。。。
时间证明,「凡是预」了的也可能会「废」了, 哈哈哈
团队项目现状和代码规范的必要性
一、有开源的 eslint 方案么
开源的方案有很多,Airbnb Standard Alloy Ali... 像是货架上精美的同类产品,每个产品右上角都标着有多少stars,产品简介(Readme.md)各种各样的理念,真是眼花缭乱。直接用哪个都有着充足的理由,而且每个上榜的产品都有着各自的拥趸。
事实上,我们可以左手交钱(使用成本),右手去选择任何一个产品去应用在团队中。
二、团队规范的现状
我们需要就实际情况做下对比,权衡出一个适合的方案。应用社区优秀的方案并不意味着在你和小伙伴的项目中就是完美的,适合自己的才是最好的。
首先要明确的是,代码质量规范的工作是必须要做的,没有退路可言,也就是说,团队项目应用和统一一套 eslint
规范势在必行。
这第一个问题是,用什么样的 eslint
规范,有哪些考量呢?
如果是独立开发者,或者执行力强、场景技术栈也比较单一,那么弱水三千,任凭君选。
显然,团队比独立开发者的情况要复杂「亿」点点。
站在我们团队实际情况来看:
1. 有比较重的历史包袱:
团队项目时间都比较久,项目比较多,粗略估计应该要到200个了
2. 规范不统一
众多项目中,我们梳理了下代码规范相关的情况:
- 有的是干脆直接用社区现有规范的
- 很多是没有用
eslint
的 - 有的即便用也是规则统统关掉,或者遇到报错就加忽略
eslint
版本区间从 4.x 到 8.x- 项目技术栈比较丰富:
vue2/vue3/react16 18/jquery/monorepo/react-native/taro/vite/ts/js
3. 技术栈各有侧重/业务的潮汐规律
- 团队成员的专业技能各有侧重,有jq一把梭的,有react可以吃遍所有需求的,也有用啥啥都行的万能选手。
- 按照往年来看,进入Q3末到Q4整个季度,业务需求将会有逐渐递增的趋势,代码质量要有基本的保证,但是否在偿还技术栈的时间里有足够的资源支持,也要画一个问号。要开始做,就要在业务需求相对低估的时候做,这样随着时间的累计,对于开发者也是一种规范习惯的培养,在业务高峰期,也不至于将规范完全抛弃。
开发代码规范
一、规范应当是什么样子的
那么要使用的规范,需要基于基本情况,能够覆盖所有的项目,落地要允许开发者逐步地进行。我们不要表面上使用了代码规范,实际都是规则关闭的流于形式的落地,这纯属浪费大家的时间;也不要全部应用的都是 strict
的规范的完美主义,这意味着不从实际出发的指令,意味着落地工作将举步维艰。
- 降低开发者的接入成本,要求规范本身接入方法要足够简单,意味着规范内部要自己消化各种语言的解析。
- 对于统计工作要友好,要求规范本身被项目接入和执行结果的输出格式要统一,意味着规范内部要有定义好的数据结构。
- 数据结果要准确客观,有标准可循 。无论该规范是通过
.eslintrc.*
的方式来配置,还是通过npx @afuteam/eslint-plugin-fe@latest
的形式来输出结果,数据一定是要一致的。意味着规范内部应当对开发者通过两种使用的方式使用的规则要统一,并且规范内部要有能力排除由于项目本身带来的干扰,比如.eslintignore
等文件的存在、行内注释和文件顶部注释的操作对结果的影响。
满足这些条件的规范,应该没几个人会不喜欢吧,哈哈哈哈哈
二、上代码
撸码之前,还是要说几点:
- 我们的规范输出形式是
npm
包,本身也计划是开源出来 (主要是想得到各位的指点); - 该依赖包支持开发者在 项目中下载和配置,也支持通过可执行包的形式使用;
- 支持不同的项目,语言的组合,这个代码里说;
1. 源码开源到哪里
2. 产物输出到哪里
莫慌,当成一个常规的 npm
包来开发即可。在 package.json
中进行 main
和 bin
字段的配置,如下:
3. 开发思路
A. 基本单元
我们将这百十来个项目,按照语言和框架来拆分这几个基本单元:
- JavaScript
- TypeScript
- Vue2/Vue3
- React
实际项目往往不单纯的就是其中一种情况,大多数都是组合的,列举:
- React + JavaScript
- Vue2/Vue3 + JavaScript
- React + TypeScript
- Vue2/Vue3 + TypeScript
如果我们将上面的几种类型,每个都填入对应的规则 (rules),在配置文件中引用这个规则文件,那不就是可以做到 「以不变应万变」了么
您瞧瞧,搁着搭积木呢~~
其中的 base.js
配置一些公共的参数,主要供其他文件需要时候引入使用。至于参数列表,自行去查阅 Eslint: configuration-objects 部分。
B. 代码逻辑
开发者引入我们的lint包后,实际使用的是上面的某个文件,因为常规项目他不可能跳出我们画的这个组合清单的圈圈。
我从结果来反向说吧,诸君先看下面的文件:
三个文件,共性是都有 parser
parserOptions
extends
plugins
rules
。
别着急划走~
这几个参数的含义在这里也列一下:
- parser : 该项用于指定
ESLint
所使用的解析器。ESLint
允许你指定自己的解析器,如"Babel-ESLint"
等,使得ESLint
可以对新型JS语法进行lint
。 - parserOptions : 这个选项用于设置解析器的参数,主要包括
ECMAScript
版本、源代码类型(module
或script
)、启用实验性的objectRest/spread
属性等 - plugins : 用来引入一些
ESLint
未包含的规则。比如react
插件就包含了一些针对React语法的特殊规则。 - extends: 是一个用于引入其他配置文件的字段,它使得你可以基于已有的配置进行扩展或定制。这对于维持大型项目的代码一致性非常实用。配置按照从右到左的顺序合并,也就是说,如果有冲突,靠前的配置项将覆盖后面的配置项。
至此,「以不变应万变」的规则核心思路已解释完毕。
C. 可执行包开发思路和用法
这个包可以在项目中直接使用,我给个预览,更多使用方式在这里 README.md
当然,也支持直接使用包的方式来获取项目的代码质量结果:
sql
npx @afuteam/eslint-plugin-fe@latest --type=react-ts --path=src/
其中,
type
赖包支持的lint
类型,还记得我们上面搭的积木么 :)
path
就是要执行 lint
的目录,是的,不局限于仓库,可以指定目录 :)
bash
npx @afuteam/eslint-plugin-fe@latest --help=type
用法如上,那开发思路呢?
还是贴个图来解释,以下是可执行包的主函数:
根据注释,执行过程就很清晰了:
- 先解析命令行参数,得到
lint
类型和目录 - 根据
lint
类型,生成对应的Eslint
实例 - 遍历目录下的文件,然后使用步骤二的
Eslint
实例来执行lintFiles
,输出结果
D. 亮点
- 支持文件类型配置,目前版本支持的后缀为
js
ts
jsx
tsx
vue
- 支持忽略文件配置、过滤目录
这些在
- 复杂度的自定义:
complexity
,可提供的配置少的可怜,比如排除switch case
,所以插件提供了complexity-without-switchcase
规则,使用方式:
最新消息
@afuteam/eslint-plugin-fe 包已发布,昨天刚更新到 2.0.7 版本。在内部已实现自动化检测和平台展示。