Home / Blog / Upgrading Eslint from v8 to v9 in Vue.js
Upgrading Eslint from v8 to v9 in Vue.js

Upgrading Eslint from v8 to v9 in Vue.js

Mostafa Said
Mostafa Said
Updated: November 5th 2024

As of ESLint 9.0, the tool has introduced several transformative changes, including a new configuration model called “flat config.” Released in April 2024, ESLint 9.0 departs from traditional .eslintrc configurations, enhancing flexibility, speed, and compatibility across complex JavaScript and Vue.js projects.

This guide covers many aspects of upgrading from v8 to v9, including the breaking changes, code examples, dependency updates, and strategies to help developers stay in sync with the latest ESLint standards.

Why Upgrade to ESLint 9.0?

ESLint 9.0’s flat config is a groundbreaking step, designed to simplify how projects manage rules and configurations. Unlike the .eslintrc files that cascade configuration inheritance, flat config opts for a streamlined array-based structure in eslint.config.js. This change not only provides better visibility over applied rules but also enables faster processing and improves compatibility with modern JavaScript and TypeScript tooling, especially in larger projects or monorepos. Moreover, with the release of ESLint 10.0, .eslintrc support will be entirely removed, making it essential to start the transition early.

Key Changes in ESLint 9.0

  • Introduction of Flat Config: Flat config replaces .eslintrc files with eslint.config.js, enhancing modularity and eliminating deep inheritance chains.
  • Rule Definition Revisions: Configurations now define rules directly in arrays within eslint.config.js, improving project-level customization.
  • Node.js < v18.18, v19 are no longer supported: Any Node.js version below 18.18 or 18 is no longer supported in Eslint.

Step-by-Step Guide: Upgrading ESLint v8 to v9 in Vue.js

This section provides detailed steps to handle each change ESLint 9.0 requires, from installing the necessary dependencies to configuring flat config for your Vue.js project.

Step 1: Install npm-check-updates (NCU)

To avoid dependency conflicts, start by using npm-check-updates (NCU). NCU simplifies major upgrades by checking for the latest compatible versions of each package.

npm install -g npm-check-updates

After ncu is installed, run the below command to update the required dependencies:

ncu --upgrade vue vue-tsc typescript prettier eslint-plugin-vue eslint @vue/eslint-config-typescript @vue/eslint-config-prettier @vitejs/plugin-vue

After running these commands, make sure to delete both the package-lock.json file and the node_modules directory.

As of writing this article, here’s a view on the latest versions for those packages in the above command:

"dependencies": {
    "vue": "^3.5.12",
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.1.4",
    "@vue/eslint-config-prettier": "^10.1.0",
    "@vue/eslint-config-typescript": "^14.1.3",
    "@vue/tsconfig": "^0.5.1",
    "eslint": "^9.13.0",
    "eslint-plugin-vue": "^9.30.0",
    "prettier": "^3.3.3",
    "typescript": "~5.6.3",
    "vue-tsc": "^2.1.10"
  }

Next, reinstall packages using npm install to apply the latest versions.

Step 2: Create the New eslint.config.js

Switch from .eslintrc to the new eslint.config.js setup. The flat config structure combined with the Vue.js official plugin for Eslint requires manual setup of each component, including plugins, files to lint, and ignore settings.

Here’s a template configuration for Vue.js projects in ESLint 9.0:

// ~/eslint.config.js
import pluginVue from 'eslint-plugin-vue';
import vueTsEslintConfig from '@vue/eslint-config-typescript';
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';

export default [
  {
    name: 'app/files-to-lint',
    files: ['**/*.{ts,mts,tsx,vue}'],
  },
  {
    name: 'app/files-to-ignore',
    ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
  },
  ...pluginVue.configs['flat/essential'],
  ...vueTsEslintConfig(),
  skipFormatting,
];

In the code snippet above, vueTsEslintConfig represents the official Vue.js configuration tailored for Eslint and TypeScript in Vue.js applications. It is provided through the @vue/eslint-config-typescript package, which integrates essential TypeScript rules and settings optimized for Vue projects.

Also, we use the Vue.js flat/essential ruleset from pluginVue.configs to apply the essential rules for Vue.js. If we want to override any of the rules, we can add another object after the ruleset with the rules property:

// eslint.config.js
export default [
  // ..
  ...pluginVue.configs["flat/essential"],
  {
    rules: {
      "vue/multi-word-component-names": 0,
    },
  },
  // ..
];

This configuration simplifies rule management and allows centralized rule definitions, making them uniform across your project.

Step 3: Update ESLint Commands

Now that we define the files to lint and to ignore in Eslint’s flat config file, we can update the lint command to be just this:

// package.json
"scripts": {
  "lint": "eslint . --fix"
}

Why Separate ESLint and Prettier for Vue Projects?

Did you notice the skipFormatting config that was added to the eslint.config.js file?

// ~/eslint.config.js
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';

export default [
    // other configs..
  skipFormatting,
];

Prettier and ESLint serve distinct roles: Prettier ensures consistent code formatting, while ESLint enforces code quality and best practices. Though it's possible to combine both tools by embedding Prettier into ESLint, this approach can slow down linting processes, produce unnecessary warnings, and complicate configurations.

Instead, running Prettier separately from ESLint optimizes performance and keeps the responsibilities of each tool clear and streamlined.

Best Practice: Configure Prettier for code formatting only and ESLint for code quality and Vue-specific rules.

This is exactly what skipFormatting is doing. It will disable prettier from working while linting.

Additional Improvements for Project Organization

After upgrading ESLint, further organize your project by installing the EditorConfig VS Code extension and custom VSCode settings. These steps enhance file formatting, nesting, and linting efficiency.

Install EditorConfig and Create a .editorconfig File

EditorConfig standardizes formatting across team members, making it easier to maintain consistent styling across large projects.

Create a .editorconfig file in the project root:

[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
charset = utf-8
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

Configure VSCode for Optimal File Nesting and Formatting

To keep your project’s files organized, take advantage of the Explorer File Nesting feature in VS Code. You can add the following custom settings to your .vscode/settings.json:

{
  "explorer.fileNesting.enabled": true,
  "explorer.fileNesting.patterns": {
    "tsconfig.json": "tsconfig.*.json, env.d.ts",
    "vite.config.*": "jsconfig*, vitest.config.*, cypress.config.*, playwright.config.*",
    "package.json": "package-lock.json, pnpm*, .yarnrc*, yarn*, .eslint*, eslint*, .prettier*, prettier*, .editorconfig"
  },
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit"
  },
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

This will nest most of the related config files under one file to clean up the project a little bit.

It’s worth mentioning that Anthony Fu created a very helpful repository to get the best out of this feature.

Common Errors and Migration Tips

Upgrading to ESLint 9.0 may trigger a few compatibility issues if using older configurations or plugins. To ease this transition, ESLint offers a migration guide that addresses these errors comprehensively, covering aspects like configuration conflicts and rule compatibility adjustments.

Future-proofing for ESLint 10.0 and Beyond

Since ESLint 10.0 will remove .eslintrc support, it’s advisable to start using flat config exclusively. Doing so ensures smoother upgrades and aligns with ESLint’s roadmap for more streamlined, consistent configurations. Developers who start now will not only benefit from reduced project complexity but will also avoid extensive rewrites as flat config becomes the default standard.

For more information and to stay updated on changes in ESLint 9.0, check out their official release notes and Vue.js ESLint guide.

Conclusion

Migrating from ESLint v8 to v9 in Vue.js offers multiple benefits, from enhanced configuration clarity to improved compatibility with modern JavaScript tooling. While the transition to flat config may feel like a significant shift, the resulting code quality, consistency, and maintenance simplicity make it worthwhile for all JavaScript and Vue.js developers. As we look forward to ESLint 10.0, adopting flat config now not only future-proofs your project but also streamlines it for today’s dynamic development landscape.

Whether you’re a plugin author, project maintainer, or Vue.js developer, embracing ESLint’s flat config model will help keep your projects up-to-date and robust for the future.

Finally, special thanks to all open source maintainers ♥️

Related Courses

Start learning Vue.js for free

Mostafa Said
Mostafa Said
With over 7 years of e-learning expertise honed at major companies like Vodafone Intelligent Solutions (_VOIS), Mostafa is full-time instructor at Vue School and a full-stack developer in the wild. He built and maintained dozens of apps using Vue, Nuxt, Laravel, Tailwind, and more. He merges modern teaching methods with coding education to empower aspiring developers of all experience levels. When he's not glued to the code editor, hackathons fuel his competitive spirit, with Deepgram and Appwrite grand prizes under his belt.

Comments

Latest Vue School Articles

Generating Fake Data with Faker.js

Generating Fake Data with Faker.js

Discover the power of Faker.js, the essential JavaScript library for generating realistic fake data, in our new video course created in collaboration with the developers at Vehikl (vehikl.com).
Felipe Flor
Felipe Flor
Database Seeds with the Nuxt Task Runner

Database Seeds with the Nuxt Task Runner

Learn how to integrate Drizzle ORM with Nuxt for type-safe database operations, including database migrations and seeding with Faker.js and Nitro tasks.
Daniel Kelly
Daniel Kelly

Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.

More than 200.000 users have already joined us. You are welcome too!

Follow us on Social

© All rights reserved. Made with ❤️ by BitterBrains, Inc.