What is lint-staged?
The lint-staged npm package is used to run linters on staged git files. It allows you to run specific commands before committing, ensuring that only clean, linted code gets committed to your repository. This helps in maintaining code quality and reducing the chances of committing code with errors or that doesn't adhere to the project's coding standards.
What are lint-staged's main functionalities?
Running linters on staged files
This configuration in package.json will run ESLint on staged JavaScript files and Stylelint on staged CSS files, automatically fixing any fixable issues.
"lint-staged": {
"*.js": "eslint --fix",
"*.css": "stylelint --fix"
}
Running custom scripts
This configuration will run markdownlint-cli2 on staged Markdown files to ensure they meet the project's markdown style requirements.
"lint-staged": {
"*.md": "npx markdownlint-cli2"
}
Using with pre-commit hooks
This configuration sets up Husky to run lint-staged as a pre-commit hook, ensuring that the linters are run automatically before each commit.
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}
Other packages similar to lint-staged
pretty-quick
pretty-quick is an npm package that runs Prettier on your changed files. It is similar to lint-staged but is specifically focused on formatting with Prettier rather than running arbitrary linters or tasks.
husky
Husky can be used to manage Git hooks and can run tasks on commit, push, and more. While it doesn't run linters on staged files by itself, it is often used in conjunction with lint-staged to trigger linters before a commit.
lefthook
Lefthook is a fast and powerful Git hooks manager for Node.js, Ruby, or any other type of projects. It can run linters and custom scripts similar to lint-staged, but it also provides additional features like parallel task execution and support for multiple programming languages.
lint-staged
Run linters against staged git files and don't let :poop: slip into your code base!
Why
Read the Medium post
Linting makes more sense when running before commiting you 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 want to lint only
files that will be committed.
This project contains a script that will run arbitary npm tasks against staged files, filtered by
a spicified glob pattern.
Installation & Setup
npm install --save-dev lint-staged
npm install --save-dev pre-commit
(recommended way of adding a git hook)- Install and setup your linters just like you would do normally. Add appropriate
.eslintrc
and .stylelintrc
etc. configs (see ESLint and Stylelint docs if you need help here). - Add
"lint-staged": { "eslint": "*.js" }
to package.json
(see configuration) - Add
{ "lint-staged": "lint-staged" }
to scripts
section of package.json
- Add
"pre-commit": [ "lint-staged" ]
to package.json
Configuration
You can configure lint-staged by adding a lint-staged
section to your package.json
. It should
be an object where each key is a command to run and value is a glob pattern to use for this
command. This package uses minimatch for glob patterns.
See the documentation for it in case you have question.
{
"scripts": {
"my-cool-linter": "eslint"
},
"lint-staged": {
"my-cool-linter": "*"
}
}
This config will run my-cool-linter
with all staged files passed as argument. Every script that
can be run via npm run-script
or installed via npm
is supported. This package is
using npm-which to locate scripts, so you don't need to
add { "eslint": "eslint" }
to the scripts
section of your pacakge.json
when running with default
parameters. So the above example becomes:
{
"scripts": {
},
"lint-staged": {
"eslint": "*"
}
}
If you want to pass some custom parameters to your linter, you can add it to the
scripts
section and then add it to the lint-staged
configuration. See examples below.
ESLint with default parameters for *.js and *.jsx
{
"name": "My project",
"version": "0.1.0",
"scripts": {
"lint-staged": "lint-staged"
},
"lint-staged": {
"eslint": "*.@(js|jsx)",
},
"pre-commit": [ "lint-staged" ]
}
ESLint + Stylelint with SCSS syntax
{
"name": "My project",
"version": "0.1.0",
"scripts": {
"lint-staged": "lint-staged",
"stylelint-staged": "stylelint --syntax=scss"
},
"lint-staged": {
"eslint": "*.js",
"stylelint-staged": "*.scss"
},
"pre-commit": [ "lint-staged" ]
}