npm-pre-post

npm script 的 pre、post 钩子及在 pre commit 时进行 lint

pre、post 钩子

介绍

  • npm run为每条命令提供了pre-post-两个钩子(hook)。
  • npm run lint为例,执行这条命令之前,npm会先查看有没有定义prelintpostlint两个钩子,如果有的话,就会先执行npm run prelint,然后执行npm run lint,最后执行npm run postlint
  • 可以在这两个钩子中来完成一些其它事情,如在执行test前先执行lint操作

示例

1
2
3
4
5
6
7
8
9
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"lint": "eslint --ext .js,.vue src",

"test": "karma start --log-leve=error karma.config.js --single-run=true",
"pretest": "npm run lint",
"posttest": "echo 'Finished running tests'"
}
  • 执行npm run test时会先执行npm run pretest再执行npm run test最后执行npm run posttest
  • 中间任意一环节报错,就会中断后续执行
  • 不能在pre脚本之前再加pre,即prepretest脚本不起作用。
  • 即使npm可以自动运行prepost脚本,也可以手动执行它们

缺陷

  • pre、post钩子只能在npm run时生效,没法在其他场景使用;
  • 如需要在git commit时先lint代码

改进

  • 使用husky

husky

介绍

  • husky 可以在git commitgit push时执行自定义脚本
  • 可以利用这个特性在commit时做lint工作

示例

1
2
3
4
5
6
7
8
9
10
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"lint": "eslint --ext .js,.vue src",
},
"husky": {
"hooks": {
"pre-commit": "npm run lint" // 在commit前执行npm run lint
}
}

注意

  • 老版本husky的钩子是直接定义在scripts中的,最新版本将其转移到husky字段下了
  • 老版本husky的钩子名称一般为precommit、prepush,现在统一改成了pre-commit、pre-push

缺点

  • 每次针对所有文件进行lint,我们希望仅针对修改的或者说是staged的文件进行lint -husky配合lint-staged使用

lint-staged

介绍

  • husky可以让我们在git commitgit push时执行一段脚本
  • lint-staged则可以针对addgit 暂存区的文件进行lint操作

使用

  • 首先安装
    • npm i -D lint-staged husky
  • 定义lint-staged相关脚本
    • 可针对不同类型文件执行不同脚本,参考示例

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"lint": "eslint --ext .js,.vue src",
},

"lint-staged": {
"*.{js}": [ // 针对git 暂存区中的文件先执行eslint --fix,没有报错时,再add进暂存区
"eslint --fix",
"git add"
]
}
,
"husky": {
"hooks": {
"pre-commit": "lint-staged" // 在commit前执行lint-staged任务
}
}

参考

http://javascript.ruanyifeng.com/nodejs/npm.html#toc15