Last September 23rd the ESLint team released the new version, 9.11.1.
As we grow as developers and try to take care of good practices and, in my case, trying to follow the recommendations of the Vue Core Team to develop Vue.js projects, we create habits that lead us to do some things automatically.
My routine when creating a new Vue project is to choose the configuration that you can see in the following image:
Once I finish creating the project, I access the directory, run npm install
, run ncu -u
to update all the dependencies to their latest versions, and run npm install
again.
As of today (September 27, 2024), when you create the scaffold of a new project in Vue, the package.json
file looks like this:
{
"name": "new-vue-project",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"test:unit": "vitest",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"dependencies": {
"pinia": "^2.1.7",
"vue": "^3.4.29",
"vue-router": "^4.3.3"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.8.0",
"@tsconfig/node20": "^20.1.4",
"@types/jsdom": "^21.1.7",
"@types/node": "^20.14.5",
"@vitejs/plugin-vue": "^5.0.5",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.5.1",
"eslint": "^8.57.0",
"eslint-plugin-vue": "^9.23.0",
"jsdom": "^24.1.0",
"npm-run-all2": "^6.2.0",
"prettier": "^3.2.5",
"typescript": "~5.4.0",
"vite": "^5.3.1",
"vite-plugin-vue-devtools": "^7.3.1",
"vitest": "^1.6.0",
"vue-tsc": "^2.0.21"
}
}
If you run 'npm-check-updates' (ncu
, without the '-u' flag) it gives you a report similar to the following:
Checking /home/drfcozapata/vue.js/new-vue-project/package.json
[====================] 22/22 100%
@rushstack/eslint-patch ^1.8.0 → ^1.10.4
@types/node ^20.14.5 → ^22.7.3
@vitejs/plugin-vue ^5.0.5 → ^5.1.4
eslint ^8.57.0 → ^9.11.1
eslint-plugin-vue ^9.23.0 → ^9.28.0
jsdom ^24.1.0 → ^25.0.1
npm-run-all2 ^6.2.0 → ^6.2.3
pinia ^2.1.7 → ^2.2.2
prettier ^3.2.5 → ^3.3.3
typescript ~5.4.0 → ~5.6.2
vite ^5.3.1 → ^5.4.8
vite-plugin-vue-devtools ^7.3.1 → ^7.4.6
vitest ^1.6.0 → ^2.1.1
vue ^3.4.29 → ^3.5.9
vue-router ^4.3.3 → ^4.4.5
vue-tsc ^2.0.21 → ^2.1.6
Run ncu -u to upgrade package.json
Where it is clearly seen that you can update Vue.js from version 3.4.29 (default still) to 3.5.9 (the latest at the time of writing this post) and you can update eslint from version 8.57.0 to 9.11.1 (also the latest at the time of writing this post), among other possible updates.
In this opportunity, as is my habit, I ran ncu -u
and this updated everything automatically, not considering the surprise of the radical changes that brings the new version of the powerful ESLint.
But before we get to that point, we have to answer an important question...
Why should you use ESLint in your Vue.js projects?
ESLint is a linter, and a linter is a “static analysis” tool used to identify and point out errors, style issues and possible bugs in source code, among which we can mention:
- Error detection: linters can find common errors in the code, such as unused variables, syntax errors and logic problems, among others.
- Code styling: linters help maintain a consistent coding style by pointing out deviations from established conventions, such as indentation, use of quotation marks and/or semicolons, function formatting, etc.
- Improve code quality: linters help improve overall software quality and facilitate maintenance by identifying potential problems before the code is executed.
- Integrate workflows: linters are often integrated into code editors and build systems, allowing instant feedback while writing code.
What are these radical changes brought by the new version of ESLint?
ESLint version 9.0.0 brings some radical changes compared to previous versions. Two of the most important changes we can mention are the following:
Versions lower than 18.18 and 19 of Node.js are not supported by this new version.
The new version of ESLint supports the following versions of Node.js:
- Node.js v18.18.0 and above.
- Node.js v20.9.0 and higher
- Node.js v21 and higher
So, we must take into consideration the version of Node we are running. I still recommend the use of the NVM (Node Version Manager) tool and the subsequent installation of Node through it if you work with legacy code and you need to run a specific version of Node, as in my case.
New default configuration format
As of ESLint v9.0.0, 'eslint.config.js' is the new default configuration format; the previous format (.eslintrc.js) is no longer used and will not automatically be searched for.
And this was the point that I was unaware of and that had me quite a while trying to fix the problem, which was no problem at all in the end.
In addition, many other important changes were incorporated:
- Several formatters that were used internally by ESLint were removed.
- The require-jsdoc and valid-jsdoc rules were removed.
- Enabled 4 new rules (
no-constant-binary-expression
,no-empty-static-block
,no-new-native-nonconstructor
andno-unused-private-class-members
) and removed 4 others (no-extra-semi
,no-inner-declarations
,no-mixed-spaces-and-tabs
andno-new-symbol
) in eslint:recommended. - When using the
--output-file
flag the file is written to disk, even if the output is empty. - Changed the way of writing rules related to '/*exported */'.
- Made the schemas of some rules stricter.
- And many other changes.
If you remember the package.json file I posted earlier, it contains a line with the following code:
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
Well, surprise! Because of all the changes, that line no longer works if you upgrade to the new version.
Similarly, the '.eslintrc.cjs' file containing the following code doesn't work either!
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest'
}
}
What to do if you want to continue using ESLint in your Vue 3 projects with the latest versions of all dependencies?
The answer is extremely simple, although I had to read quite a bit to get to it:
- Create the new project using
npm create vue@latest
. - Access the project directory and run
npm install
. - Run
ncu -u
to update the dependencies. - Run
npm install
again. - Open your code editor and delete the '.eslintrc.cjs' file.
- Run the following command:
npm init @eslint/config@latest
. This command runs a script that allows you to create the new configuration for ESLint and create the necessary new files. In my case, I select:-
How would you like to use ESLint?
To check syntax and find problems
, -
What type of modules does your project use?
CommonJS (require/exports)
, -
Which framework does your project use?
Vue.js
, -
Does your project use TypeScript?
Yes
, -
Where does your code run?
Browser
, -
The config that you've selected requires the following dependencies: eslint, globals, @eslint/js, typescript-eslint, eslint-plugin-vue. Would you like to install them now?
Yes
, -
Which package manager do you want to use?
npm
-
How would you like to use ESLint?
- Modify the line in the 'package.json' file so that it looks like this:
“lint”: “eslint . --fix"
.
All of the above led to create the new 'eslint.config.js' file with the following code:
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";
export default [
{files: ["**/*.{js,mjs,cjs,ts,vue}"]},
{files: ["**/*.js"], languageOptions: {sourceType: "commonjs"}},
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
...pluginVue.configs["flat/essential"],
{files: ["**/*.vue"], languageOptions: {parserOptions: {parser: tseslint.parser}}},
];
From here you can run npm run lint
with confidence, without getting a bunch of warnings and errors in the console.
I hope the above information will be useful for you and avoid wasting the time I wasted trying to solve this breacking-change.
Much success and blessings from Venezuela.
Top comments (1)
That is a nice article, and not only useable for Vue developer, but anyone who uses ESLint.
I updated some old repositories to the new configuration. A nightmare, as it was also within some monorepos. In the end, it made so much more sense with the flat-file config 😁.