Configure ESLint and Prettier for Vue.js 3 in VS Code

January 3rd, 2022 by Philip Iezzi 4 min read
cover image

I'd like to share my recommended ESLint and Prettier configuration for a Vue.js 3 project. The two are not mutually exclusive – ESLint is for linting and Prettier handles code formatting. Believe me, you're going to use both! As preferred IDE, I am using VS Code. This article is just considered as simple dev notes without digging any deeper, and it's based on my current "best practices".

We're going to install Prettier first and ensure it's running fine. After that, we're going to install ESLint which is a bit trickier and needs some fine-tuning so that it won't conflict with any rules that Prettier already handles.

This is an update of my previous article Configure ESLint and Prettier for Vue/Nuxt.js, adapted to a plain Vue 3 project with recommended setup for a fresh 2022 start. It is mainly based on the following in-depth tutorial: ESLint and Prettier with Vite and Vue.js 3

Prettier

Configure Prettier

Install Prettier into devDependencies using npm (or use yarn add --dev instead):

$ npm install --save-dev prettier

If you also want Prettier to handle PHP files (this is a frontend dev article only, but since Inertia.js is such a great project and motivates us to build single-page apps in the same repo, you might also have such a mix of Vue/PHP files...):

$ npm install --save-dev @prettier/plugin-php

Configure Prettier in .prettierrc (again in your project root):

.prettierrc
{
    "semi": false,
    "singleQuote": true,
    "tabWidth": 4,
    "printWidth": 120
}

Also create .prettierignore (optional):

.prettierignore
# Ignore artifacts:
build
coverage

VS Code formatOnSave

Configure VS Code Editor: Format on Save to apply auto formatting upon saving, which you can also restrict to specific languages. I recommend only changing your workspace settings for the current project, which are stored in .vscode/settings.json:

.vscode/settings.json
{
    "vetur.validation.template": false,
    "vetur.format.defaultFormatter.html": "none",
    // Set the default
    "editor.formatOnSave": false,
    // Enable per-language
    "[javascript]": {
        "editor.formatOnSave": true
    },
    "[vue]": {
        "editor.formatOnSave": true
    },
    "[php]": {
        "editor.formatOnSave": true
    }
}

Now, open any .vue or .js (or .php) file, remove some spacing to make it look ugly, fire Cmd-S to save the file, and see the magic. If it won't yet work for you, consider restarting VSCode.

Don't worry, a file only gets formatted if you explicitely hit Cmd-S. You can still use autoSave for regular saving, which would not invoke auto-formatting of the whole file. That's the relevant global VS Code user settings (can be found in $HOME/Library/Application Support/Code/User/settings.json on macOS):

settings.json
{
    "files.autoSave": "afterDelay",
    "prettier.printWidth": 81,
}

Configure ESLint

Install ESLint with all recommended plugins into devDependencies using npm:

$ npm install --save-dev eslint eslint-plugin-vue eslint-config-prettier
$ npm install --save-dev eslint-plugin-prettier

Next, configure ESLint by creating an .eslintrc.js file with the following configuration so that it's configured to use the ESLint recommend rules as well as the recommended rules for Vue 3. Minimal setup:

module.exports = {
  env: {
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-recommended',
    'prettier',
  ],
  rules: {
    // override/add rules settings here, such as:
    // 'vue/no-unused-vars': 'error'
  }
}

NOTE: The really important part here is, that you don't forget to register eslint-config-prettier which turns off all rules that are unnecessary or might conflict with Prettier. Make sure it's the last config defined in the extends array as the order of the configs determine duplicate rules (later rules override previous ones and eslint-config-prettier only turns rules off)!

Visit the eslint-plugin-vue docs to see the other configurations available for use with Vue 3 for less strict options if desired. The different configurations correspond to the 3 different priorities in the Vue.js 3 style guide.

This is my recommended setup which makes use of eslint-plugin-prettier and defines some extra rules:

module.exports = {
    root: true,
    env: {
        browser: true,
        node: true,
    },
    extends: [
        'eslint:recommended',
        'plugin:vue/vue3-recommended',
        'prettier'
    ],
    plugins: ['prettier'],
    rules: {
        'prettier/prettier': ['error'],
        'vue/require-default-prop': 'off',
        'vue/html-indent': ['error', 4],
        'vue/singleline-html-element-content-newline': 0,
        'vue/component-name-in-template-casing': ['error', 'PascalCase'],
    },
    globals: {
        _: true,
    },
}

Feel free to disable some of my rules, e.g. not everybody likes to have component names inside <template> tag in PascalCase.

Happy clean coding!

Review

Above configuration is based on the following versions, added lines to package.json:

{
    "devDependencies": {
        "@prettier/plugin-php": "^0.17.6",
        "eslint": "^8.6.0",
        "eslint-config-prettier": "^8.3.0",
        "eslint-plugin-prettier": "^4.0.0",
        "eslint-plugin-vue": "^8.2.0",
        "prettier": "^2.5.1"
    }
}

Be ready for your configuration to break on the next major release of ESLint! It can be a pain, sometimes.