前端规范及校验
前端规范及校验:
1、代码规范及校验
1.1、eslint:
是一个开源的 JavaScript 代码检查工具,它是用来进行代码的校验,检测代码中潜在的问题,比如:
- 某个变量定义了未使用;
- 函数定义的参数重复;
- 变量名没有按规范命名等等。
在项目运行编译时 起作用,本身可支持280多个规范,还存在一些额外的自定义规范,但实际应用中一般不会全部用到,具体规则可通过.eslinntrc.js文件进行配置。
.eslinntrc.js配置文件:
-
配置文件读取的规则:
- 首先在项目中去找是否有.eslinntrc.js文件;
- 如果没找到,会去当前目录中去找;
- 还是没有的话,会去全局找。
-
配置文件的配置项:
- 配置当前目录为 root;
- 全局变量 globals;
- 扩展 extends:可扩展采用的校验规则标准,比如常见的有以下几种:
- eslint:recommended:ESLint 内置的推荐规则,即 ESLint Rules 列表中打了钩的那些规则;
- @vue/standard standard 的 JS 规范,字符串使用单引号,关键字、函数名后加空格,坚持使用全等 === 摒弃 ==等;
- airbnb rules:js、React/JSX、CSS、HTML编码规范;
- Google rules;
- 插件 plugins
- 规则 rules:off 或 0,warn 或 1,error 或 2;
-
规则的优先级:
- 如果 extends 配置的是一个数组,那么最终会将所有规则项进行合并,出现冲突的时候,后面的会覆盖前面的;
- 通过 rules 单独配置的规则优先级比 extends 高;
.eslintignore 文件
可以配置 ESLint 校验的时候忽略的目录/文件。
1.2、prettier:
是代码格式化工具,用来做代码格式化:
-
没有 prettier 之前,是用 eslint —fix和 编辑器自带代码格式来进行代码格式化的。每种编辑器会有不一样的代码格式,而且配置会比较麻烦。
-
有了Prettier之后,它能去掉原始的代码风格,确保团队的代码使用统一相同的格式,修复规则可自定义。
-
配置项可以通过 .prettierrc 文件修改。
Prettier 和 ESLint 一起使用的时候会冲突解决方式:
-
所以使用 eslint-config-prettier 来关掉 (disable) 所有和 Prettier 冲突的 ESLint 的配置:在 .eslintrc 里面将 prettier 设为最后一个 extends:
"extends": ["prettier"] // prettier 一定要是最后一个,才能确保覆盖
-
再启用 eslint-plugin-prettier ,将 prettier 的 rules 以插件的形式加入到 ESLint 里面:
"plugins": ["prettier"], "rules": { "prettier/prettier": "error" }
-
上述两步合并之后(也是官方推荐配置)即:
"extends": ["plugin:prettier/recommended"]
1.3、配合vscode工具
-
eslint扩展插件:
- 自动检测代码中的不规范,在编写保存的时候就可以直接通过设定的规范来提示出现的错误;
- 下载eslint扩展,在setting.json中添加配置;若项目中有.eslinntrc.js文件配置,则优先采用项目配置;
"eslint.autoFixOnSave": true, // 每次保存的时候将代码按eslint格式进行修复
-
prettier扩展插件:
- 用来格式化代码的插件,不仅仅可用于vue,还可以用于前端大部分场景:如js,html,css,scss,json,reactjs等等。
- 这些类型的文件都可以用prettier插件来格式化。若项目中有 .prettierrc 配置文件,则优先采用项目配置;
-
vetur扩展插件:
- 是开发vue项目基本必装的一个插件,主要的功能是:语法高亮、格式化(可选择对应文件格式化选项,比如prettier)、调试,以及错误检查、全局组件的定义提示等等;
2、代码自动化测试
2.1. 测试分类:
- 单元测试:关注应用中每个零部件的正常运转,防止后续修改影响之前的组件。
- 大大提高后续测试且软件整体正常运行的概率;
- 测试问题定位到细节,容易修改,节省时间;
- 追踪问题变得更加方便。
- 功能测试:确保其整体表现符合预期,关注能否让用户正常使用。
- 整合测试:确保单独运行正常的零部件整合到一起之后依然能正常运行。
2.2. 单元测试:
2.2.1 如何选择框架?
首先要简单,快速执行,清晰的错误报告;需要考虑一下几点:
- 断言(Assertions):用于判断结果是否符合预期。有些框架需要单独的断言库。
- 适合 TDD / BDD:是否适合 测试驱动型 / 行为驱动型 的测试风格。
- 异步测试:有些框架对异步测试支持良好。
- 使用的语言:大部分 js 测试框架使用 js。
- 用于特定目的:每个框架可能会擅长处理不同的问题。
- 社区是否活跃。
2.2.2 测试框架
框架 | 描述 | 优点 | 缺点 |
---|---|---|---|
Jasmine | 是一个行为驱动的开发框架,可被用于测试各种JavaScript代码。 | 开箱即用,支持断言和仿真、全局环境 | 比较老 |
Jest | 基于 Jasmine 至今已经做了大量修改添加了很多特性;易用性和无需配置,高效的加载性能 | 开箱即用配置少,API简单,支持断言和仿真、快照、环境隔离 | 较新,社区不十分成熟 |
Mocha | 能够与多种扩展程序协同使用,因此Mocha具有较高的兼容性与灵活性。 | 灵活,自己选择断言仿真工具,社区成熟,支持快照测试 | 配置多 |
测试框架的功能:
- 提供测试框架:(Mocha, Jasmine, Jest, Cucumber)
- 提供断言:(Chai, Jasmine, Jest, Unexpected)
- 生成,展示测试结果:(Mocha, Jasmine, Jest, Karma)
- 快照测试:(Jest, Ava)
- 提供仿真:(Sinon, Jasmine, enzyme, Jest, testdouble)
- 生成测试覆盖率报告:(Istanbul, Jest, Blanket)
- 提供类浏览器环境:(Protractor, Nightwatch, Phantom, Casper)
总结:
-
Mocha:用的人最多,社区最成熟,灵活,可配置性强易拓展;
-
Jest:容易上手,开箱即用,功能全面;
3、git-代码提交规范
3.1. 基本介绍&常用命令:
3.1.1 工作区介绍
- 工作区:coding的区域;git merge/rebase后在此区域;
- 暂存区:git add 之后代码所存储的区域;
- 本地仓库:git commit之后代码所存储的区域;
- 本地远程仓库:git fetch之后,将远程分支copy到本地保存一份,此其余不可修改;
- 远程仓库:git push到的在线远程仓库;
3.1.2 常用命令
- 创建仓库:
- git init:在目录中创建新的 Git 仓库。
- git clone [url]:
- -b branchname;
- “指定目录”;
- 修改提交:
- git add [file1] [file2] … / [dir] / .:添加文件到暂存区
- git status:-s:获得简短的提交之后是否有对文件进行再次修改;
- git diff [file]:尚未缓存的改动;
- –cached:查看已缓存的改动;
- HEAD:查看已缓存的与未缓存的所有改动;
- –stat:显示摘要而非整个 diff;
- git commmit -m [message]:
- -a:不需要执行 git add 命令,直接来提交,但对新增文件无效;
- git reset [HEAD]:本地执行,直接HEAD 指向回退的commit;该commit后的所有commit都将被清除,包括提交历史记录;
- –mixed:默认,回退时保留源码,修改的文件会置于工作区;再次提交需要git add;
- –soft:回退时保留源码,修改的文件仍然保存在暂存区;再次提交直接git commit;
- –hard:退时清除提交的源码(危险操作),源码和commit 都会回滚到某个版本;
- git revert:使用一个新的commit 来回滚你希望回滚的commit,只针对撤销的commit,其他的提交无影响,但后续提交同时修改了同一地方会造成冲突;已经push了,使用revert;
- git rm :从暂存区和工作区中删除;
- -f:修改过并且已经放到暂存区域的话,则必须要用强制删除;
- –cached:把文件从暂存区域移除,但仍然希望保留在当前工作目录中;
- -r:递归删除;
- git mv [file] [newfile]:移动或重命名一个文件、目录或软连接。
- 分支操作:
- git branch:查看本地所有的分支;
- -a 查看远程所有的分支
- name 创建分支
- -m dev develop 重命名分支
- –d dev 删除dev分支
- git checkout:
- –b dev [origin/***] 创建dev分支 并切换到dev分支上;
- — * 把XX文件在工作区的修改全部撤销。
- master 切换回master分支
- git merge dev 在当前分支上合并dev分支代
- git rebase
- git branch:查看本地所有的分支;
- 提交日志:
- git log:
- –oneline:简洁版本,一行展示;
- –graph:开启拓扑图,查看分支分叉、归并情况;
- –reverse:反向顺序展示日志;
- –author=***:查看指定用户的提交记录;
- git blame :查看指定文件的修改记录;
- git log:
- 远程操作:
- git remote:add [name] [url]:添加远程仓库;rm name:删除远程仓库;rename old_name new_name:修改仓库名;
- git fetch [alias]:本地远程仓库名;
- git pull <远程主机名> <远程分支>:<本地分支>;git fetch + git merge
- –rebase:git fetch + git rebase;
- git push <远程主机名> <本地分支>:<远程分支>:把当前新增的dev分支推送到远程库(远程仓库没有给分支则会新建立该分支);
- –set-upstream:建立追踪关系;
- –delete:删除远程分支;
- tag相关:
- git tag 列出所有的tag
- git tag name 打轻量标签 name
- git tag -d name 删除本地的tag
- git push origin --delete tag name 删除远程的tag
- git show name 查看tag信息
- git push origin name 将tag提交到远程
3.2. 提交规范:
- 统一团队git commit标准,便于后续代码review、版本发布、自动化生成changelog;
- 可以提供更多更有效的历史信息,方便快速预览以及配合cherry-pick快速合并代码;
- 团队其他成员进行类git blame时可以快速明白代码用意;
3.2.1 版本规范
- 分支规范:
- master分支,主干分支,不可直接修改;
- tag规范:
- v1.0.0:大版本迭代第一位,小版本迭代第二位,hotfix等第三位;
- changelog:
- 每次上线,生成changelog日志,方便后续维护;
3.2.2 git commit规范
3.2.2.1 commit信息提交可分为以下几部分:
- header:type(feat/fix/docs/refactor/build/style/pref/chore/test/ci/revert)、scoped:影响范围,可选、subject:简要说明;
- body:详细描述;
- footer:不兼容变动、关闭指定issue
3.2.2.2 git commit 工具:
-
commitlint:
- 用于规范 git commit -m “xxx” 中的xxx部分的描述信息,对其进行格式校验,可自定义校验的配置文件,在commit-msg钩子触发
commitlint -E HUSKY_GIT_PARAMS
; - 它将读取commitlint.config.js配置规则并对我们刚刚提交的测试提交这串文字进行校验,若校验不通过,则在终端输出错误,commit终止。
- xxx规则: [optional scope]: ,type部分常用可选值见上述header中的type值;
- 用于规范 git commit -m “xxx” 中的xxx部分的描述信息,对其进行格式校验,可自定义校验的配置文件,在commit-msg钩子触发
-
commitizen
- 安装Commitizen:是一个主流的 Commit message 的生成工具;
npm install -g commitizen
; - 项目目录下进行初始化:
commitizen init cz-conventional-changelog --save --save-exact
;- 安装了cz-conventional-changelog;
- 保存其依赖到package.json中;
- 添加config.commitizen key到package.json中,如下:
"config": {"commitizen": {"path": "./node_modules/cz-conventional-changelog"}}
- package.json添加脚本:
"script": {"commit": "git-cz"}
;提交时使用npm run commit
即可; - 生成changelog文件:
- cz-conventional-changelog 可以自动根据提交信息生成change log:
npm install -g conventional-changelog-cli
; - 添加执行脚本:
"scripts": { "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md"}
;
- cz-conventional-changelog 可以自动根据提交信息生成change log:
- 安装Commitizen:是一个主流的 Commit message 的生成工具;
-
强制校验提交信息,配合git hooks,具体见下节;
3.3. git hooks
Git 能在特定的重要动作发生时触发自定义脚本。 有客户端、服务端两组钩子。
3.3.1. 客户端钩子:
由诸如提交和合并这样的操作所调用;
- 提交工作流钩子:
- pre-commit 钩子:在键入提交信息前运行,用于检查即将提交的快照。
- 例如,检查是否有所遗漏,确保测试运行,以及核查代码(lint等)。
- 如果该钩子以非零值退出,Git 将放弃此次提交,但 git commit --no-verify 可绕过此环节。
- prepare-commit-msg 钩子:在启动提交信息编辑器之前,默认信息被创建之后运行。
- 可编辑提交者所看到的默认信息,可接收:存有当前提交信息的文件的路径、提交类型和修补提交的提交的 SHA-1 校验的信息;
- 可用于自动产生默认信息的提交,如提交信息模板、合并提交、压缩提交和修订提交等。
- commit-msg 钩子:
- 接收一个参数:存有当前提交信息的临时文件的路径。
- 如果该钩子脚本以非零值退出,Git 将放弃提交。
- 可用来在提交通过前验证项目状态或提交信息。
- post-commit 钩子:在整个提交过程完成后运行:
- 它不接收任何参数,但你可以很容易地通过运行 git log -1 HEAD 来获得最后一次的提交信息。
- 一般用于通知之类的事情。
- pre-commit 钩子:在键入提交信息前运行,用于检查即将提交的快照。
- 电子邮件工作流钩子:由 git am 命令调用
- applypatch-msg:接收单个参数:包含请求合并信息的临时文件的名字。
- 如果脚本返回非零值,Git 将放弃该补丁。
- 可用于确保提交信息符合格式,或直接用脚本修正格式错误。
- pre-applypatch:产生提交之前, git am 运行期间被调用;
- 以非零值退出,中断 git am 的运行
- 用它在提交前检查快照,测试或检查工作区。
- post-applypatch :运行于提交产生之后,是在 git am 运行期间最后被调用的钩子;
- 一般用于通知之类的事情;
- applypatch-msg:接收单个参数:包含请求合并信息的临时文件的名字。
- 其它客户端钩子:
- pre-rebase 钩子:运行于变基之前,以非零值退出可以中止变基的过程。
- 可用来禁止对已经推送的提交变基。
- post-rewrite 钩子:被那些会替换提交记录的命令(git commit --amend 和 git rebase)调用;
- 参数是触发重写的命令名,同时从标准输入中接受一系列重写的提交记录。
- 用途很大程度上跟 post-checkout 和 post-merge 差不多。
- post-checkout 钩子: git checkout 成功运行后,会被调用;
- 可以根据你的项目环境用它调整你的工作目录。
- post-merge 钩子:git merge 成功运行后,会被调用。
- 用它恢复 Git 无法跟踪的工作区数据,比如权限数据,验证某些在 Git 控制之外的文件是否存在;
- pre-push 钩子:会在 git push 运行期间, 更新了远程引用但尚未传送对象时被调用。
- 接受远程分支的名字和位置作为参数,同时从标准输入中读取一系列待更新的引用。
- 可以在推送开始之前,用它验证对引用的更新操作(一个非零的退出码将终止推送过程)。
- pre-auto-gc 钩子:git gc --auto 进行垃圾回收开始之前被调用;
- 一个非零的退出码中断回收。
- pre-rebase 钩子:运行于变基之前,以非零值退出可以中止变基的过程。
3.3.2. 服务器端钩子:
作用于诸如接收被推送的提交这样的联网操作, 可以在任何时候以非零值退出,拒绝推送并给客户端返回错误消息。
- pre-receive:处理来自客户端的推送操作时,最先被调用;
- 从标准输入获取一系列被推送的引用。
- 如果它以非零值退出,所有的推送内容都不会被接受。
- 可用于阻止对引用进行非快进(non-fast-forward)的更新,或者对该推送所修改的所有引用和文件进行访问控制。
- update:推送者同时向多个分支推送内容,pre-receive 只运行一次,相比之下 update 则会为每一个被推送的分支各运行一次。
- 不会从标准输入读取内容,而是接受三个参数:引用的名字(分支),推送前的引用指向的内容的 SHA-1 值,以及用户准备推送的内容的 SHA-1 值。
- 以非零值退出,只有相应的那一个引用会被拒绝;其余的依然会被更新。
- post-receive:整个过程完结以后运行,可以用来更新其他系统服务或者通知用户。
- 接受与 pre-receive 相同的标准输入数据;
- 该脚本无法终止推送进程,不过客户端在它结束运行之前将保持连接状态。
- 一般用于通知之类的事情;
3.3.3. 客户端钩子的使用:
钩子都被存储在 Git 目录下的 hooks 子目录中。 也即绝大部分项目中的 .git/hooks 。 当你用 git init 初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。
所有的示例都是 shell 脚本,其中一些还混杂了 Perl 代码,不过,任何正确命名的可执行脚本都可以正常使用 —— 你可以用 Ruby 或 Python,或任何你熟悉的语言编写它们。
这些示例的名字都是以 .sample 结尾,如果你想启用它们,得先移除这个后缀。
在git项目中,可通过引入工具使得操作hooks变得更加简单:
husky:
原理是让我们在项目根目录中写一个配置文件,然后在安装 Husky的时候把配置文件和 Git Hook 关联起来,这样我们就能在团队中使用 Git Hook 了。不支持服务端 Git 的钩子。
- 安装 Husky
npm install husky -D
- package.json添加配置:此处以pre-commit钩子举例;
"husky": {
"hooks": {
"pre-commit": "git restore -W -S dist examples/dist && eslint"
}
}
- 不想运行钩子,不想 Husky 为你自动安装钩子,可以这样做:
HUSKY_SKIP_HOOKS=1 命令行...
yorkie:
是尤雨溪fork自husky,内置到了@vue/cli中;
- 安装:
npm i --D yorkie
- package.json添加配置:此处以commit-msg钩子举例;
"gitHooks": {
"commit-msg": "node git-hooks/verify-commit-msg.js"
}
- git-hooks/verify-commit-msg.js文件校验:
- 该钩子接收一个参数(存有当前提交信息的临时文件的路径)。
- 如果该钩子脚本以非0退出,Git将放弃提交。
const gitParams = process.env.GIT_PARAMS
const msg = require('fs').readFileSync(gitParams, 'utf-8').trim()
const commitReg = /^(revert: )?(feat|fix|polish|docs|style|refactor|perf|test|workflow|ci|chore|types|build)((.+))?: .{1,50}/
if (!commitReg.test(msg)) {
console.error('invalid commit message format.')
process.exit(1)
}