Guide to ESLint & Prettier with Nuxt 3
Nikita Dmitriev
Posted on January 29, 2024
Introduction
In this article, you will learn:
- How to set up a Nuxt project with ESLint and Prettier
- How to configure ESLint and Prettier together
- How ESLint plugins and configs work
- The difference between
plugins
andextends
in ESLint - How Prettier plugins work
- Other important details
Prerequisites
You should have basic knowledge of Prettier and ESLint. You'll also need VS Code, but if you don't have that, it's not a problem as long as you really know the basics about your particular IDE.
Environment Preparation
If you're using a separate IDE from VSCode, you can skip this part. ESLint and Prettier follow the same script in every IDE. If you are a VSCode user, let's get started.
First of all install these 2 extensions:
- Prettier - Code formatter
- ESLint
Now open VSCode settings using CTRL + ,
hotkey in Windows or using the panel below:
Open settings.json. You can find the button in the top right corner
Then add or change the following parameters:
{
"prettier.configPath": ".prettierrc",
"editor.formatOnPaste": false,
"editor.formatOnType": false,
"scss.lint.unknownAtRules": "ignore",
"editor.defaultFormatter": "esbenp.prettier-vscode",
"eslint.format.enable": true,
"prettier.useEditorConfig": false
}
Useful Note. If you want to see what each of these settings does, then go back to the convenient UI window with settings and enter the keys (from settings.json) into the search one by one, for example:
Project Initialization
Now go to the terminal and select the folder you like to create the project
To initialize the nuxt project you must run the following command:
npx nuxi@latest init my-project
Useful Note. If you want to deploy the nuxt project exactly in the current folder, and not create a new one with the project, then run
npx nuxi@latest init ./
(as in my case)
As you can see, the project is deployed directly in the selected folder. As for me, in some cases this is a way more convenient than nuxt creating a new folder for the project
Now let's install the common dependencies:
npm i -D prettier eslint
Useful Note. The
-D
flag is used to add a package to devDependencies. You can read more here
I think you already know how Prettier and ESLint work without each other, but if not, be sure to check it out before we go any further.
Integrate ESLint module to Nuxt
You can just follow this guide and skip this section, but if you want, let's walk through it together.
In your nuxt application install
npm add -D @nuxtjs/eslint-module
Useful Note.
npm add
is exactly the same command asnpm i
, but it just looks nicer from a naming point of view. That is, it’s like an alias
In essence, this action simply adds a plugin to the nuxt application (in addition to ESLint, you can add any other from here). This setting is purely for nuxt so that it knows which modules you are using, so now you need to edit nuxt.config.ts and add just one line to it
modules: ["@nuxtjs/eslint-module"]
Now your nuxt.config.ts should look something like this
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
modules: ["@nuxtjs/eslint-module"],
})
Plugins and configs in ESLint
Remember one thing - plugins do not configure your ESLint in any way. You just sort of add a module to it, but don't connect it. This can be compared to regular projects. For example, you can add a large jquery folder to the project (I hope you haven’t had this experience), and connect only jquery.min.js to the project from the folder. And here the jquery folder is a plugin, and jquery.min.js is a config. That is, when you specify something in plugins in ESLint, you simply load some rules and you need to configure which ones work.
All plugin names begin with eslint-plugin-
. Having any plugin installed, for example eslint-plugin-react, you can connect it with removed prefix, like here
plugins: [
"react", // the same as "eslint-plugin-react"
]
But you can use a longer way:
plugins: [
"eslint-plugin-react", // the same as "eslint-plugin-react"
]
I also would like to say about plugins starting with @
. Let's introduce the child plugins @foo/eslint-plugin
and @foo/eslint-plugin-bar
. And you can connect these plugins in the following ways:
"plugins": [
"@foo/eslint-plugin-bar", // the same as "@foo/eslint-plugin-bar"
"@foo/bar", // the same as "@foo/eslint-plugin-bar"
"@foo/eslint-plugin", // the same as "@foo/eslint-plugin"
"@foo" // the same as "@foo/eslint-plugin"
]
And here ESLint works quickly, but I wouldn’t say it’s good, because often confusion arises due to such moments. Therefore, carefully study the example above and make sure that everything is clear.
Well, I hope you have mastered the information above and now let's talk about extends
. In extends
we always specify the configuration of our plugins. You can specify the entire configuration yourself in a separate place and add just this one file to extends. But this practice is very inconvenient and generally makes no sense when there are already ready-made configurations. In general, with plugins you simply load a preset, and with configs you connect the necessary settings for this preset. Configs start with eslint-config-
(similar to plugins), but configs can also be inside plugins, and to use them you must set the appropriate plugin:
prefix. I understand that it has become more difficult now, so let’s immediately analyze everything we’ve covered using the example of our application.
In the beginning we just included ESLint in the nuxt project, but ESLint does not have any settings for nuxt at the moment and the most useful plugin for nuxt is eslint-plugin-nuxt. Let's install it:
npm i -D eslint-plugin-nuxt
Now let's create a .eslintrc.json file in the project root
Let's add this plugin to our .eslintrc.json
{
"plugins": ["nuxt"] // the same as "eslint-plugin-nuxt"
}
Now let's add a new script to package.json:
"lint": "eslint .",
Let's try to run this script and we'll get the following error:
ESLint requires us to include a config, so let's do that, but first let's have a look at the open source of this plugin and find the recommended.js file
As you can see, here are the usual ESLint settings (as in any other config), and all because this is essentially a .eslintrc.json file, only encrypted in js format. and it extends base.js, let's look at that too
And here you can see the plugin connection
plugins: [
'nuxt' // the same as "eslint-plugin-nuxt"
],
That is, this config connects the main plugin eslint-plugin-nuxt and configures it by specifying various parameters (for example, connecting rules). You can literally copy this config and paste it into your .eslintrc.json and everything will work for you. Here's a minimalistic example of config, which just control single rule from the plugin
{
"plugins": [
"nuxt"
],
"rules": {
"nuxt/rule-name": 2
}
}
But again, it’s inconvenient to configure everything yourself and each plugin already has ready-made configs, like this recommended.js. So we can simply use them based on the plugin documentation. If you know OOP and programming, then you know the extend
operation from there, and here it works similarly. Well, now let's write the config connection for the plugin
{
"extends": [
"plugin:eslint-plugin-nuxt/recommended"
]
}
Remember what I said about the plugin:
prefix? This is where it is used, since the config is loaded directly from the plugin. In this case, we may not add the plugin connection to plugins "plugins": ["nuxt"]
. As mentioned above, also we can omit eslint-plugin-
and we get
{
"extends": [
"plugin:nuxt/recommended"
]
}
But this config is already deprecated, and we can connect another one that includes its own npm package. Let's install @nuxt/eslint-config and connect in .prettierrc.json
npm add -D @nuxt/eslint-config
And extend it in .eslintrc.json
{
"extends": [
"@nuxt" // The same as @nuxt/eslint-config
]
}
Now let's write the following code in app.vue:
<template>
<div>
<div class="hello"></div>
</div>
</template>
And run the npm run lint
command
As you can see ESLint works now! You can experiment with the name of the extended config
Also let's look at the repository of this config
Here we are using the basic eslint-config, but as you can see there are other options, such as eslint-config-legacy, which works for older versions, etc. But if you try to connect it by simply writing something like this, nothing will work
{
"extends": [
"@nuxtjs/eslint-config-legacy-typescript"
]
}
That's because this config only works for version 2 of nuxt, as you can verify through the code on github:
In general, keep in mind that each plugin has its own internal structure, and you need to delve into open source to connect everything correctly. As a result, you can notice that we installed only one plugin eslint-plugin-nuxt, and we can connect different configs to it (plugin:prettier/recommended
, which comes in the box with the plugin and @nuxt/eslint-config
, which is installed separately). So there are no restrictions here, you can customize any plugins individually and write your own configs. And if you, for example, connected a config and want to override some settings, then simply specify them in the root .eslintrc.json. But consider the order in which you extend your configs! The order of the configurations in the extends array matters. The configurations listed later will override conflicting rules from earlier configurations.
module.exports = {
extends: [
'eslint:recommended', // Base configuration
'plugin:react/recommended', // Extending a specific plugin configuration
'airbnb', // Extending a third-party configuration
'prettier', // Extending a configuration for code formatting
],
rules: {
// Your additional or overridden rules go here
},
};
Prettier & ESlint
There are 2 packages: eslint-plugin-prettier and eslint-config-prettier. They eliminate potential conflicts between ESLint and Prettier for your application and give ESLint the ability to follow the rules in Prettier. Always connect them together, otherwise conflicts will arise. They complement each other. Let's connect them
npm add -D eslint-plugin-prettier eslint-config-prettier
And now we add the corresponding configs to extends
{
"extends": ["@nuxt", "plugin:prettier/recommended", "prettier"] // The same as "@nuxt/eslint-config", "plugin:eslint-plugin-prettier/recommended", "eslint-config-prettier"
}
In general, we are finished, but we still need to add the following parameters to .eslintrc.json for it to work correctly
{
"extends": ["@nuxt", "plugin:prettier/recommended", "prettier"], // The same as "@nuxt/eslint-config", "plugin:eslint-plugin-prettier/recommended", "eslint-config-prettier"
"env": {
"browser": true,
"node": true,
},
}
Configure .prettierc
Now let's create just an empty .prettierrc file
In VSCode go to command palette:
Restart ESLint server. This procedure is needed simply to update ESLint in VS Code
And now if you remove the space, ESLint will start displaying an error related to prettier
Now go back to the command palette and select format document
The document is formatted and there are no errors. Now let's try to add a parameter to the prettier config
Let's go back to app.vue and restart ESLint server
Also if you write npm run lint
in the console, then errors will be displayed there too
Now let's format the document again:
Plugins in prettier
Only ESLint can be configured to adapt to prettier. The opposite is not possible. Keep in mind that prettier plugins are not related to ESLint in any way, and only ESLint can change depending on prettier. Plugins in prettier also start with prettier-plugin-
, but the prefix cannot be omitted! Let's install the plugin - npm add -D prettier-plugin-tailwindcss
. And connect it to prettierrc
For this plugin to work we need to install tailwindcss in the project. Do it according to the guide. I already have another application where all this is connected, so don’t be alarmed that the name of the project has changed. Let's try to write the classes in the following order and run them through the linter
As you can see, an error has arisen that we need to change the order of the classes and let's take advantage of the linter's hint and use the --fix
flag
And everything worked exactly the same as if we formatted using prettier, but it’s just more convenient to use in VSCode, and it will be more correct. But just know that you can format your files this way too. That is, here, using the eslint-plugin-prettier plugin and the eslint-config-prettier config, ESLint adapts to prettier and causes errors that come from it.
About prettier/prettier
prettier/prettier
is exactly the rule that is defined in ESLint through prettier. For example, if you specified tabWidth: 5
in the .prettierrc.json file, then the ESLint configuration will throw a prettier/prettier
error. And the most interesting thing is that it can also be configured, for example, replacing error with warn
Conclusion
Prettier and ESLint are very powerful tools that require at least a basic understanding to perform to their full potential. I also plan to write identical articles about these tools, since there is really very little information and even on native js it is difficult to intuitively deploy them. I hope this article helped you!
Posted on January 29, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.