Using Husky, I've set up my package.json
with a precommit hook so that my JavaScript code is formatted using Prettier before every commit:
{
"name": "prettier-demo",
"scripts": {
"precommit": "prettier --write **/*.js && git add ."
},
"devDependencies": {
"husky": "^0.14.3",
"prettier": "^1.8.2"
}
}
This works fine, but there are two drawbacks:
If I have a large project with thousands of JavaScript files, I have to wait for Prettier to process all of them, even if only a few have changed; this can take very long and gets on my nerves quickly when it is done with every commit
Sometimes I want to stage just a couple of files for committing, leaving other changes out of the commit; because I do a git add .
after running Prettier, all my changes will always end up in the commit
How can I run Prettier before every commit only on the files that have been staged, ignoring unstaged or unchanged files?
You can do that using lint-staged:
Linting makes more sense when running before committing your code. By doing that you can ensure no errors are going into repository and enforce code style. But running a lint process on a whole project is slow and linting results can be irrelevant. Ultimately you only want to lint files that will be committed.
This project contains a script that will run arbitrary npm and shell tasks with a list of staged files as an argument, filtered by a specified glob pattern.
Install lint-staged and husky, which is required for pre-commit hooks, with this command:
npm install --save-dev lint-staged husky
Change your package.json as follows:
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"*.js": [
"prettier --write",
"git add"
]
}
}