Pre-commit setup in monorepo structure for Vue and Nuxt projects
About pre-commit
Pre-commit is a useful framework for managing and maintaining multi-language pre-commit hooks. It helps ensure that code quality checks and other automated tasks are run before code is committed to a repository. This can help catch issues early and enforce coding standards consistently across a team. Recently I've been using it to setup a monorepo for code quality checks of my Python and Vue/Nuxt projects. Everything works well except that I found it very difficult to setup eslint
checks and linting for my frontend project that is located in a subfolder like ui
. For example, I encountered an error like the following:
No files matching the pattern "ui/components/**.vue" were found.
The problem occurs because pre-commit by default pass matched file path to the command while the path doesn't exist if the current directory context is ./ui
already.
After spent hours reading documentation, I could not find much useful related information to address the problem I'm facing. Eventually I took the following approach to resolve the issue.
Pre-commit hook
Setup pre-commit to skip passing file names to command:
- repo: local
hooks:
- id: eslint
name: eslint:lintfix
verbose: true
entry: npm --prefix ./ui run-script lintfix
language: system
pass_filenames: false
files: \.(vue|js|jsx|ts|tsx)$
pass_filenames
is set to false to avoid the issue mentioned at the beginning.
package.json
Make sure the referenced script exists in package.json file:
"scripts": {
"lint": "npm run lint:eslint && npm run lint:prettier",
"lint:eslint": "eslint .",
"lint:prettier": "prettier . --check",
"lintfix": "eslint --fix --cache . && prettier --write --list-different ."
},
The lintfix
script will run eslint and prettier to fix the problems.
The following packages were referenced too for my linter setup:
"devDependencies": {
...
"@nuxt/eslint": "^0.4.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"prettier": "^3.3.3",
"typescript": "^5.5.4"
}
eslint.config.mjs
I was following official documentation to setup eslint with Nuxt:
// @ts-check
import withNuxt from "./.nuxt/eslint.config.mjs"
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"
export default withNuxt(eslintPluginPrettierRecommended).append({
languageOptions: {
ecmaVersion: "latest",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
ecmaFeatures: {
experimentalObjectRestSpread: true
}
}
}
})
The above code includes rules from prettier
.
Constraints
The above setup will scan all the files of the frontend project instead of just the changed files in your commit each time. However since cache is used so hopefully it will not slowdown your speed of submitting commits.
You can also consider using customized scripts to setup the hook. In the script, you can take input of file names. In this way you can set parameter pass_filenames
to true
.