使Prettier一键格式化WXSS(下集)

本文将会结合 ESLint、Prettier、husky、lint-stage、gulp.js 等工具使得项目一键化操做,减小在格式化、代码检查等操做上浪费时间,由于大前端真的太多东西学了,不学会“偷懒”的话,咱们就要落后更多了。css

本系列文章的示例 Demo 在这里 👉 GitHub: wechat_applet_demohtml

分为三篇文章介绍:前端

上一篇文章介绍了如何一键格式化 wxss 文件。git

今天介绍利用 Git Hooks 钩子实现提交代码自动执行此前的 ESLint、Prettier 命令,以保证咱们提交的代码是不丑的。github

1、Git 钩子

Git 提供了一些钩子,能在特定的重要操做发生时触发自定义脚本。npm

当咱们执行 git init 初始化一个 Git 版本库时,Git 会默认在 .git/hooks 目录中放置一些示例脚本(Shell 脚本)。这些示例脚本都是以 .sample 结尾,若是你想启用它们,得先移除这个后缀。json

把一个正确命名(不带扩展名)且可执行的文件放入 .git/hooks 目录下,便可激活该钩子脚本。 这样一来,它就能被 Git 调用。gulp

2、经常使用钩子

  • pre-commit

该钩子在键入提交信息前运行。 它用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 若是该钩子以非零值退出,Git 将放弃这次提交,不过你能够用 git commit --no-verify 来绕过这个环节。 你能够利用该钩子,来检查代码风格是否一致、尾随空白字符是否存在,或新方法的文档是否适当等等。segmentfault

3、husky

husky 是一个为 Git 客户端增长 hook 的工具。当其安装到所在仓库时,它会自动在 .git/hooks 增长相应的钩子实如今 pre-commit 阶段就执行一系列保证每个 commit 的正确性。数组

固然,pre-commit 阶段执行的命令,固然要保证其速度不要太慢,每次 commit 都等好久也不是好的体验。

1. 安装 npm-run-all

它用于同步或者并行执行 npm script 脚本。

$ yarn add --dev npm-run-all@4.1.5

因而乎,结合以前的 npm script,再经过 npm-run-all 来把几个命令串起来。

{
  "scripts": {
    "format:all": "npm-run-all -p prettier:wxss:acss prettier:fix -s eslint:fix"
  }
}

这行命令作了什么:首先并行执行 prettier:wxss:acssprettier:fix 两个命令,等到执行完以后才会执行 eslint:fix 命令。

  • npm-run-all -p 表示并行操做。
  • npm-run-all -s 表示按顺序操做。
  • 它同时提供了上面两条命令的简写版 API,分别对应 run-prun-s

由于 prettier:wxss:acssprettier:fix 匹配的文件没有重合的,因此能够并行操做。至于为何先进行 Prettier 格式化,再进行 ESLint 检查,由于它们两个是存在冲突的。

虽然咱们能够在 .eslintrc.js 引入相关插件进行配置,使其当 Prettier 规则不符合 ESLint 规则时进行报错提醒,但没有解决咱们的痛点,它须要咱们手动去修复。

还有,老是可能会存在先执行 ESLint,再进行 Prettier 的状况。因此我就想着整合这个脚本,使其按照咱们预期方向走:当二者有冲突的状况时,采用 ESLint 的规则。

完整脚本以下:

{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "eslint": "eslint ./ --ext .js",
    "eslint:fix": "eslint --fix ./ --ext .js",
    "prettier:fix": "prettier --config .prettierrc.js --write './**/*.{js,css,less,scss,json}'",
    "prettier:wxss": "gulp wxss",
    "prettier:acss": "gulp acss",
    "prettier:wxss:acss": "gulp all",
    "format:all": "npm-run-all -p prettier:wxss:acss prettier:fix -s eslint:fix"
  }
}
2. 安装 husky
$ yarn add --dev husky@4.3.0

package.json 添加配置,使其在进行 git commit -m 'xxx' 代码提交时,进行格式化操做,以保证咱们提交的代码是不丑的。

若是过程当中出现错误(如 ESLint 校验不经过),将会中止 commit 操做,即 pre-commit 返回非零结果以退出。

它能够经过 git commit --no-verify 命令进行忽略。

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "yarn run format:all"
    }
  }
}
3. 看效果

咱们随便修改一个文件,而后进行提交。如图,能够看到是按照预期执行的,好了。
🎉

4、lint-staged

看到上面的结果,彷佛一切顺利。但没有完...

从上图咱们看出来,咱们只提交了一个文件的变更,可是它对全部文件进行了扫描,这里是存在体验性问题的。

假如咱们有 N 多个暂存文件,那么每当咱们 git commit 一次就全部检查全部文件一遍,这致使咱们的体验很是很差,过程很慢,显然不是咱们想要的。

那么如何解决呢?咱们须要用到它 👉 lint-staged

$ yarn add --dev lint-staged@10.3.0

自 v3.1 版本开始,能够有多种不一样的方式进行配置,这里很少说。

在项目根目录建立一个 .lintstagedrc.js 的配置文件,而后经过 --config 或者 -c 指定。

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged --config .lintstagedrc.js"
    }
  }
}
// .lintstagedrc.js
const path = require('path')

module.exports = {
  '*.js': ['prettier --config .prettierrc.js --write', 'eslint --fix --ext .js'],
  '*.json': 'prettier --config .prettierrc.js --write',
  '*.wxss': absolutePaths => {
    // 获取相对路径
    // const cwd = process.cwd()
    // const relativePaths = absolutePaths.map(file => path.relative(cwd, file))
    // return `gulp wxss --path ${relativePaths.join(' ')}`

    return 'gulp wxss'
  },
  '*.acss': 'gulp acss'
}
注意,咱们不将路径做为命令调用时的参数传递。这一点很重要,由于 lint-staged 将为咱们完成这一点。

lint-staged 采用的是 glob 匹配模式。从上面的配置中,经过匹配不一样的文件类型执行相应的操做。

*关于 lint-staged 相关使用说明,建议查看官方文档或者较瘦的这篇文章,我就再也不详说。

不知道有没有人好奇,上面 lint-staged 配置文件中,我在匹配 .wxss 文件时采用的是函数形式。

其实这里是存在一个问题没解决的,就是在提交 .wxss 暂存文件时,不是只处理该 .wxss 文件,而是将项目全部的 .wxss 文件(包含未提交至暂存区的 .wxss 文件)。

缘由大概以下:
1️⃣ 在前面我介绍了,因为 Prettier 没有解析器去处理 .wxss 扩展名的文件,因此咱们使用了 Gulp.js 经过转换文件类型的方式去处理。而对应 Gulp 任务是匹配当前项目下全部 .wxss 文件的,使用 gulp.dest(__dirname) 是正常导出到源文件路径下。

2️⃣ 按照 lint-staged 的思想,只处理提交的暂存文件。意味着咱们在执行 gulp wxss 任务时应该要传递一个文件路径,而后再修改 wxssPrettier 任务,使其既能匹配全部的,也能够匹配个别或多个的(而非全部).wxss 文件。而后我尝试了不少几种方法,都没能获得预期效果。

3️⃣ 我踩坑思路大体是:在执行 gulp wxss 时传递一个或者多个路径参数(如上配置文件注释部分),经过 process.argv 获取 NPM 脚本参数,接着在 wxssPrettier 任务中对获取的参数作处理,往 gulp.src() 传递一个数组,到这来我以为思路应该是没错的。可是现实是残酷的,在 gulp.dest() 时导出的路径老是不对,全部的 .wxss 文件都被导出到项目根目录下了,这显然不是咱们想要的结果。

4️⃣ 目前我还没找到更好的解决方案,欢迎大佬们赐教。

就是由于这个问题,我以为我这个 wechat_applet_demo 还不是很完美(我有强迫症),若后续有解决方案了,会回来更新的。

有解决方案了,快去看 结局篇

至此

到这里基本就结束了,但可能还会加入 Commit Message 提交说明的规范,由于一个清晰明了的提交说明,可让人很清楚本次代码提交的目的或者解决了什么具体问题。目前使用最广的应该是 Angular 规范了,比较合理和系统化,并且有配套的工具。能够看下这篇文章 git commit 规范指南

如有不足之处,欢迎留言指正。

The end.

相关文章
相关标签/搜索