How to configure lint-staged in Vue
Running linters on every file in your Vue project before each commit can slow down your development workflow significantly, especially in large codebases. With 10 years of experience in Vue.js development since 2014 and as the creator of CoreUI, I’ve optimized countless development workflows to balance code quality with developer productivity. From my expertise, the most efficient solution is to use lint-staged to run ESLint and Prettier only on staged files, ensuring fast commits while maintaining code quality. This approach integrates seamlessly with Git hooks and reduces pre-commit time from seconds to milliseconds.
Use lint-staged to run linters only on staged Git files for faster commits.
npm install --save-dev lint-staged
Basic Configuration
Configure lint-staged in your package.json to run ESLint and Prettier on staged Vue files:
{
"lint-staged": {
"*.{js,jsx,vue}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss,vue}": [
"prettier --write"
]
}
}
This configuration runs ESLint with auto-fix and Prettier formatting on all staged JavaScript and Vue files. The --fix flag automatically corrects linting errors that can be fixed programmatically. For style files, only Prettier runs to ensure consistent formatting.
Installing Required Dependencies
Install ESLint and Prettier along with their Vue plugins:
npm install --save-dev eslint prettier eslint-plugin-vue
npm install --save-dev @vue/eslint-config-prettier
Create an .eslintrc.js file in your project root:
module.exports = {
root: true,
env: {
node: true
},
extends: [
'plugin:vue/vue3-recommended',
'@vue/prettier'
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}
Advanced Configuration with File Patterns
Configure different linters for different file types with more specific patterns:
{
"lint-staged": {
"*.vue": [
"eslint --fix",
"prettier --write",
"git add"
],
"*.{js,jsx}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss,less}": [
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
}
}
This configuration separates Vue files from JavaScript files, allowing you to apply different rules. The git add command at the end ensures that the fixed files are added back to the staging area.
Integrating with Husky
Combine lint-staged with Husky to automatically run linters on pre-commit:
npm install --save-dev husky
npx husky-init && npm install
Update the .husky/pre-commit file:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
Now lint-staged runs automatically before each commit, preventing badly formatted or linting-error code from being committed.
Using Separate Config File
For complex configurations, create a dedicated .lintstagedrc.js file:
module.exports = {
'*.{js,jsx,vue}': [
'eslint --fix --max-warnings 0',
'prettier --write'
],
'*.{css,scss,vue}': [
'stylelint --fix',
'prettier --write'
],
'*.{json,md,yml,yaml}': [
'prettier --write'
]
}
This JavaScript configuration file allows you to add comments, use variables, and apply more complex logic. The --max-warnings 0 flag ensures that commits fail if there are any ESLint warnings.
Excluding Files
Add patterns to exclude specific files or directories:
module.exports = {
'*.{js,vue}': [
'eslint --fix --ignore-path .gitignore',
'prettier --write'
],
'!(*test).{js,vue}': [
'eslint --fix'
]
}
The --ignore-path .gitignore flag tells ESLint to respect your .gitignore file. The negation pattern !(*test).{js,vue} excludes test files from certain linters.
Running Type Checking
Add Vue TypeScript type checking to your lint-staged configuration:
{
"lint-staged": {
"*.{ts,tsx,vue}": [
"vue-tsc --noEmit",
"eslint --fix",
"prettier --write"
]
}
}
This runs Vue’s TypeScript compiler in no-emit mode to check for type errors before committing. Type checking catches errors early in the development process.
Performance Optimization
For large projects, optimize lint-staged performance with concurrent execution:
{
"lint-staged": {
"*.{js,vue}": [
"eslint --fix --cache"
],
"*.{css,scss}": [
"prettier --write"
]
}
}
The --cache flag makes ESLint cache its results, significantly speeding up subsequent runs. ESLint only processes files that have changed since the last run.
Testing the Configuration
Test your lint-staged configuration without making a commit:
npx lint-staged --debug
This command shows exactly which commands will run for your staged files. Use this to debug configuration issues or verify that your setup works correctly.
Running lint-staged Manually
Run lint-staged on specific files without a Git hook:
# Run on all staged files
npx lint-staged
# Run on specific files
npx lint-staged --files src/components/Button.vue
# Dry run to see what would happen
npx lint-staged --dry-run
The --files flag allows testing your configuration on specific files. The --dry-run flag shows which commands would run without executing them.
Handling Warnings vs Errors
Configure ESLint to treat warnings differently than errors:
module.exports = {
'*.{js,vue}': [
'eslint --fix --max-warnings 0'
]
}
The --max-warnings 0 flag causes the linting to fail if there are any warnings, ensuring your codebase stays completely clean. Remove this flag if you want to allow warnings.
Adding Stylelint for CSS
Include CSS/SCSS linting with Stylelint:
npm install --save-dev stylelint stylelint-config-standard
Create a .stylelintrc.js file:
module.exports = {
extends: ['stylelint-config-standard'],
rules: {
'selector-class-pattern': null
}
}
Update your lint-staged configuration:
{
"lint-staged": {
"*.{js,vue}": [
"eslint --fix"
],
"*.{css,scss,vue}": [
"stylelint --fix",
"prettier --write"
]
}
}
This runs Stylelint on CSS and SCSS files as well as the style blocks in Vue components.
Common Configuration for Vue 3 Projects
Here’s a complete production-ready configuration for Vue 3 projects:
// .lintstagedrc.js
module.exports = {
'*.{js,jsx,ts,tsx,vue}': [
'eslint --fix --cache --max-warnings 0',
'prettier --write'
],
'*.{css,scss,vue}': [
'stylelint --fix',
'prettier --write'
],
'*.{json,md,yml,yaml,html}': [
'prettier --write'
]
}
With corresponding package.json scripts:
{
"scripts": {
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"lint:fix": "eslint --ext .js,.vue --ignore-path .gitignore --fix .",
"format": "prettier --write 'src/**/*.{js,vue,css,scss,json}'",
"prepare": "husky install"
}
}
Best Practice Note
At CoreUI, we use lint-staged across all our Vue projects to maintain consistent code quality without slowing down our development workflow. This configuration works particularly well with our Vue admin templates where maintaining clean code across large component libraries is essential. If you’re building a Vue application with complex Git workflows, consider setting up Husky with Vue to integrate lint-staged with other pre-commit checks. For optimal results, combine lint-staged with continuous integration to catch any issues that might slip through local checks.



