0
点赞
收藏
分享

微信扫一扫

前端代码规范、校验、测试框架、git规范

hwwjian 2022-04-26 阅读 85
前端

前端规范及校验

前端规范及校验:

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 log:
      • –oneline:简洁版本,一行展示;
      • –graph:开启拓扑图,查看分支分叉、归并情况;
      • –reverse:反向顺序展示日志;
      • –author=***:查看指定用户的提交记录;
    • git blame :查看指定文件的修改记录;
  • 远程操作:
    • 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值;
  • 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"}
  • 强制校验提交信息,配合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 来获得最后一次的提交信息。
      • 一般用于通知之类的事情。
  • 电子邮件工作流钩子:由 git am 命令调用
    • applypatch-msg:接收单个参数:包含请求合并信息的临时文件的名字。
      • 如果脚本返回非零值,Git 将放弃该补丁。
      • 可用于确保提交信息符合格式,或直接用脚本修正格式错误。
    • pre-applypatch:产生提交之前, git am 运行期间被调用;
      • 以非零值退出,中断 git am 的运行
      • 用它在提交前检查快照,测试或检查工作区。
    • post-applypatch :运行于提交产生之后,是在 git am 运行期间最后被调用的钩子;
      • 一般用于通知之类的事情;
  • 其它客户端钩子:
    • 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 进行垃圾回收开始之前被调用;
      • 一个非零的退出码中断回收。

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)
}
举报

相关推荐

0 条评论