If you’re reading this, I’m assuming that you already have some sort of passing familiarity with eslint and some kind of pre-commit git hooks framework.
If not, here’s a super quick overview.
Lint is the computer science term for a static code analysis tool used to flag programming errors, bugs, stylistic errors and suspicious constructs.
— Wikipedia
A linter is a program that runs through our code and checks for any errors or formatting issues. eslint is a package specifically for linting JavaScript code. When you run it with a framework like pre-commit, you can ensure that any new code adheres to your linting rules whenever you git commit
.
However, there’s a little bit of tinkering to do to get eslint to work for both TypeScript and Vue.
There’s good documentation about using eslint with Vue. And there’s good documentation about using eslint with TypeScript. But there’s less documentation about using both of them together. That’s what this article is going to address.
Table of Contents:
The Answer
These are the 2 things I set up in my projects to get eslint to work with Vue and TypeScript:
- Set up this eslintConfig in your
package.json
:
- Set up this eslint hook in
.pre-commit-config.yml
.
But what does it all mean?
Rather than just copy/pasting and hoping for the best, I think it’s important for us to understand what’s really going on in all of the config files that we use. So let’s go through these two configs line by line and see how they work.
We’ll start with pre-commit-config.yml
.
pre-commit-config.yml, line by line
For the package we want to install (eslint) we specify a mirrored repo that’s designed to work with pre-commit. Pre-commit itself hosts a lot of the mirrors you’ll need, but not all of them. For instance, the pre-commit stylelint
mirror is hosted by Thibaud from Wagtail.
I’m telling it to use version 8.34.0 which, as of publication time, is already out of date. You’ll probably want to update this.
This is telling pre-commit to run this hook on any changed file that ends with any of these extensions. Feel free to adjust to whatever’s appropriate for your own personal project.
Passing an optional --fix
argument to eslint to tell it to automatically fix whatever it can.
The recommended way to use pre-commit is to have it manage all of its dependencies in its own virtual environment. Which works for me if it means less clutter in my package.json
devDependencies.
But it also means that any plugins that we’ve specified in our eslintConfig
must be included in our pre-commit hook additional_dependencies
. Again, you do not install these yourself with npm install -D
; when you add them to additional_dependencies
pre-commit itself will install them.
Every dependency that we list is one that we’re using in our eslintConfig
. Let’s take a look at that now.
eslintConfig, line by line
For the "parser"
settings, I’m just following the minimal recommendations of vue-eslint-parser.
I add the “@typescript-eslint” plugin, following the typescript-eslint minimal configuration.
We can “extend” other eslint configurations rather than writing out all of our own rules from scratch.
- “eslint:recommended”
We start with eslint’s recommended configs.
- “plugin:@typescript-eslint/eslint-recommended”
- “plugin:@typescript-eslint/recommended”
Add the recommended configs from typescript-eslint.
- “plugin:vue/vue3-recommended”
Add vue’s recommended configs. There are other configs from this plugin that you could use in addition.
- “eslint-config-prettier”
This turns off all the rules that would otherwise be taken care of by my prettier
rules. This prevents the two hooks from forever writing over each other. It was a lifesaver when I discovered this. You can read the docs here.
- “prettier”
Runs prettier. Which handles slightly different concerns than eslint. Maybe there’ll be an article about that someday.
The env section tells eslint which environments my files should be allowed to run in. Adding "browser"
allows my files to use global vairables like window
. "node"
allows node global variables.
"es2017"
allows us to use any JavaScript features up to version ECMAScript 2017. This will also set the eslintConfig’s parserOptions.ecmaVersion
to 8
. If you want to use even newer JavaScript features, you can set a later version.
To other way to do this instead of specifying an "env"
here, is to instead set the parserOptions.ecmaVersion
. You could even set it to the "latest"
version, but I prefer to set my version explicitly. That way I can keep it aligned with my tsconfig.json
compilerOptions.lib
target.
Note: the "ecmaVersion"
or "env"
you specify is only for linting. It doesn’t impact what version of JavaScript that your built code eventually compiles to. That’s something you’ll set with a build tool like vite or webpack.
Congratulations! You now know as much as I do about using eslint with Vue and TypeScript. Good luck with everything.
🔆
Further Reading
- pre-commit docs: This covers all the basics of setting up pre-commit that aren’t specific to this usecase.