将CSScomb集成到Git Hook中

在此前文章介绍了如何在微信小程序中使用 CSScomb 来处理我们的小程序样式文件。

文章有两篇:

  1. 将 CSScomb 集成到微信小程序项目中
  2. 将 CSScomb 集成到 Git Hook 中(本文)

项目放在 GitHub 上 csscomb-mini 欢迎 Star 。

但是此前实现有个不足的地方:没有实现在提交代码之前去执行我们的脚步命令。

一、设想

假设我们可以在 pre-commit 阶段做一些类似 ESLint、Prettier 的操作,岂不美哉!

例如,如下配置文件是利用 husky、lint-staged 做了一些处理,在代码 commit 之前对代码进行检查和格式化。

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js}": "eslint --fix --ext .js",
    "*.{css,wxss,acss}": "prettier --config .prettierrc.js --write"
  }
}

那我们使用 CSScomb 也想这么做的话,要怎样实现呢?

二、试图实现

关于前一篇文章的具体思路就不再赘述了(需要的话,请看实现一个CSScomb的Gulp插件并应用于微信小程序 )。

  1. 首先安装 husky、lint-staged。

如果对两者不太了解的话,可以去看我写的另外一篇文章。

# 这里我不安装最新版 husky 的原因是 husky 5.x 在使用上有很大变化
# 我暂时还没时间去了解它,所以先用着已经习惯的 4.x 版本,问题不大
$ yarn add --dev [email protected] lint-staged
  1. package.json 添加配置,如下:
{
  "scripts": {
    "csscomb": "gulp wxssTask",
    "csscomb:mini": "gulp csscombTask --path './**/*.wxss'"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.wxss": "gulp csscombTask"
  }
}
  1. 接着,我们尝试去修改一个样式文件,并提交代码。
frankie@iMac csscomb-mini %  git commit -m 'test'
                                                                                                          
husky > pre-commit (node v14.16.0)
✔ Preparing...
⚠ Running tasks...
  ❯ Running tasks for *.wxss
    ✖ gulp csscombTask [FAILED]
↓ Skipped because of errors from tasks. [SKIPPED]
✔ Reverting to original state because of errors...
✔ Cleaning up...

✖ gulp csscombTask:
[14:30:14] Task never defined: /Users/frankie/Desktop/Web/Git/csscomb-mini/app.wxss
[14:30:14] To list available tasks, try running: gulp --tasks
[14:30:14] Using gulpfile ~/Desktop/Web/Git/csscomb-mini/gulpfile.js
husky > pre-commit hook failed (add --no-verify to bypass)

非常的遗憾,它失败了,并提示:Task never defined: /Users/frankie/Desktop/Web/Git/csscomb-mini/app.wxss

执行如下命令,明明是找得到 csscombTask 任务的啊!

frankie@iMac csscomb-mini %  npx gulp --tasks

[14:35:09] Tasks for ~/Desktop/Web/Git/csscomb-mini/gulpfile.js
[14:35:09] ├── wxssTask
[14:35:09] └── csscombTask

为什么会这样呢?什么原因呢?这也是我的踩坑的地方。

三、寻找失败原因

首先,我先翻阅了 lint-staged 的文档 ,里面有一段话:

{
  "*": "your-cmd"
}

This config will execute your-cmd with the list of currently staged files passed as arguments.

So, considering you did git add file1.ext file2.ext, lint-staged will run the following command: your-cmd file1.ext file2.ext.

假设我们暂存的文件是 /Users/frankie/Desktop/Web/Git/csscomb-mini/app.wxss,那么我们执行:

{
  "*.wxss": "gulp csscombTask"
}

就等于执行了 gulp csscombTask /Users/frankie/Desktop/Web/Git/csscomb-mini/app.wxss 这条指令。

但如果熟悉 Gulp 的话,形式如:gulp 其实是执行了多个任务。 所以,上面实际上执行了两个任务 csscombTask/Users/frankie/Desktop/Web/Git/csscomb-mini/app.wxss,它把后者也当成是一个任务了。

那么我们来验证一下,添加一个 Gulp 任务:

const test = cb => {
  // 需要注意的是:
  // 由于 node 特性,非主进程下执行该命令,无法将 test log 打印出来,
  // 例如在 lint-staged 下执行该 gulp 任务,就无法打印,
  // 如果通过 npx gulp xxx 执行任务,属于主进程,就能打印出来。
  console.log('test log')
  cb()
}

module.exports = {
  csscombTask,
  '/Users/frankie/Desktop/Web/Git/csscomb-mini/app.wxss': test
}

接着重新提交一下代码:

frankie@iMac csscomb-mini %  git commit -m 'test'

husky > pre-commit (node v14.16.0)
✔ Preparing...
✔ Running tasks...
✔ Applying modifications...
✔ Cleaning up...
[master a2ba057] test
 1 file changed, 3 insertions(+), 3 deletions(-)

它成功了,说明我们的猜想是正确的。

既然找到了缘由,那么我们开始着手解决问题吧。

四、解决问题

其实 /Users/frankie/Desktop/Web/Git/csscomb-mini/app.wxss 应该是我们 Gulp 任务的参数才对。

按照此前的约定:

gulp csscombTask --path '' --ext 

所以只要我们执行的命令形式如:gulp csscombTask --path '/Users/frankie/Desktop/Web/Git/csscomb-mini/app.wxss' 即可。

我们来修改一下 lint-staged 的配置文件,此前在 package.json 的配置方式局限性太大了,下面我们使用 JavaScript 形式的配置方式:

Writing the configuration file in JavaScript is the most powerful way to configure lint-staged (lint-staged.config.js, similar, or passed via --config).

其实 lint-staged 提供了很多的配置示例,我们使用 Example: Wrap filenames in single quotes and run once per file 即可。

移除 package.json 的配置项,并在项目根目录下,新建 .lintstagedrc.js 配置文件:

// .lintstagedrc.js
module.exports = {
  '*.wxss': filenames => filenames.map(filename => `gulp csscombTask --path ${filename}`)
}

// 其实这里可配置的方式很多,
// 例如:超过 10 个暂存文件时,我们可以在整个项目下执行一遍 csscombTask 操作:
// module.exports = {
//   '*.wxss': filenames => {
//     if (filenames.length > 10) {
//       return 'gulp csscombTask --path './**/*.wxss''
//     }
//     return `gulp csscombTask --path '${filenames.join(',')'}`
//   }
// }

接下来我们修改两个样式文件,再提交一下:

frankie@iMac csscomb-mini %  git commit -m 'test'

husky > pre-commit (node v14.16.0)
✔ Preparing...
✔ Running tasks...
✔ Applying modifications...
✔ Cleaning up...
[master 7b84b9c] test
 2 files changed, 7 insertions(+), 3 deletions(-)

可以正常运行,而且我们所提交的文件都经过了 CSScomb 格式化了,。

The end.

你可能感兴趣的:(将CSScomb集成到Git Hook中)