How to use and customize ESLint with Gatsby
Posted
Updated
Europe’s developer-focused job platform
Let companies apply to you
Developer-focused, salary and tech stack upfront.
Just one profile, no job applications!
I have great news for you, my linting friend. Gatsby ships with built-in ESLint setup. According to the Gatsby docs, the provided eslint config is suitable for most of its users.
So why customize then? Well, there could be several reasons for customization of the "standard" ESLint setup, for example:
💰 The Pragmatic Programmer: journey to mastery. 💰 One of the best books in software development, sold over 200,000 times.
If you want to know more about Linting and if ESLint is the right choice, have a look at this article What is Linting.
I assume, you’ll start with customizing from the ESLint config Gatsby ships with, so you can then add additional presets, plugins, and rules.
See below the ESLint provided by the Gatsby starter or on github.
module.exports = {
extends: [
require.resolve(`eslint-config-react-app`),
],
plugins: [`graphql`],
rules: {
// New versions of react use a special jsx runtime that remove the requirement
// for having react in scope for jsx. Once the jsx runtime is backported to all
// versions of react we can make this always be `off`.
// I would also assume that eslint-config-react-app will switch their flag to `off`
// when jsx runtime is stable in all common versions of React.
'react/react-in-jsx-scope': usingJsxRuntime
? `off`
: `error`, // Conditionally apply for reactRuntime?
'import/no-webpack-loader-syntax': [0],
'graphql/template-strings': [
`error`,
{
env: `relay`,
schemaString: printSchema(schema, {
commentDescriptions: true,
}),
tagName: `graphql`,
},
],
'react/jsx-pascal-case': `off`, // Prevents errors with Theme-UI and Styled component
// https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/master/docs/rules
'jsx-a11y/accessible-emoji': `warn`,
'jsx-a11y/alt-text': `warn`,
'jsx-a11y/anchor-has-content': `warn`,
'jsx-a11y/anchor-is-valid': `warn`,
'jsx-a11y/aria-activedescendant-has-tabindex': `warn`,
'jsx-a11y/aria-props': `warn`,
'jsx-a11y/aria-proptypes': `warn`,
'jsx-a11y/aria-role': `warn`,
'jsx-a11y/aria-unsupported-elements': `warn`,
// TODO: It looks like the `autocomplete-valid` rule hasn't been published yet
// "jsx-a11y/autocomplete-valid": [
// "warn",
// {
// inputComponents: [],
// },
// ],
'jsx-a11y/click-events-have-key-events': `warn`,
'jsx-a11y/control-has-associated-label': [
`warn`,
{
ignoreElements: [
`audio`,
`canvas`,
`embed`,
`input`,
`textarea`,
`tr`,
`video`,
],
ignoreRoles: [
`grid`,
`listbox`,
`menu`,
`menubar`,
`radiogroup`,
`row`,
`tablist`,
`toolbar`,
`tree`,
`treegrid`,
],
includeRoles: [`alert`, `dialog`],
},
],
'jsx-a11y/heading-has-content': `warn`,
'jsx-a11y/html-has-lang': `warn`,
'jsx-a11y/iframe-has-title': `warn`,
'jsx-a11y/img-redundant-alt': `warn`,
'jsx-a11y/interactive-supports-focus': [
`warn`,
{
tabbable: [
`button`,
`checkbox`,
`link`,
`progressbar`,
`searchbox`,
`slider`,
`spinbutton`,
`switch`,
`textbox`,
],
},
],
//"jsx-a11y/label-has-for": `warn`, was deprecated and replaced with jsx-a11y/has-associated-control in v6.1.0
'jsx-a11y/label-has-associated-control': `warn`,
'jsx-a11y/lang': `warn`,
'jsx-a11y/media-has-caption': `warn`,
'jsx-a11y/mouse-events-have-key-events': `warn`,
'jsx-a11y/no-access-key': `warn`,
'jsx-a11y/no-autofocus': `warn`,
'jsx-a11y/no-distracting-elements': `warn`,
'jsx-a11y/no-interactive-element-to-noninteractive-role': `warn`,
'jsx-a11y/no-noninteractive-element-interactions': [
`warn`,
{
body: [`onError`, `onLoad`],
iframe: [`onError`, `onLoad`],
img: [`onError`, `onLoad`],
},
],
'jsx-a11y/no-noninteractive-element-to-interactive-role': `warn`,
'jsx-a11y/no-noninteractive-tabindex': `warn`,
'jsx-a11y/no-onchange': `warn`,
'jsx-a11y/no-redundant-roles': `warn`,
'jsx-a11y/no-static-element-interactions': `warn`,
'jsx-a11y/role-has-required-aria-props': `warn`,
'jsx-a11y/role-supports-aria-props': `warn`,
'jsx-a11y/scope': `warn`,
'jsx-a11y/tabindex-no-positive': `warn`,
},
};
First we need the necessary ESLint dependencies.
npm install --save-dev eslint-config-react-app
Then create a file .eslintrc.js
through your editor/IDE or in the terminal touch .eslintrc.js
and copy the code snippet below in the file.
module.exports = {
globals: {
__PATH_PREFIX__: true,
},
extends: `react-app`,
};
That's it. Now you are ready to add all the additional presets, plugins and rules your project requires.
ESLint file
: Gatsby adds by default a ESLint loader, which pipes all the feedback from ESLint into your terminal/browser console.ESLint-file
: When you add a custom .eslintrc
file, Gatsby gives you full control over the ESLint configuration.
This means also it overrides the built-in eslint-loader and no default rules will be loaded.You have now several options:
.eslintrc
and that's it.I recommend this plugin, have a look at the plugin page or github.
npm install --save-dev gatsby-plugin-eslint
npm install --save-dev eslint eslint-loader
gatsby-config.js
.module.exports = {
plugins: ['gatsby-plugin-eslint'],
};
The default options are:
node_modules
, .cache
, and public
folders from linting.Customize the linting filetypes, exclusions, and ESLint-Loader options:
{
resolve: 'gatsby-plugin-eslint',
options: {
test: /\.js$|\.jsx$/,
exclude: /(node_modules|.cache|public)/,
stages: ['develop'],
options: {
emitWarning: true,
failOnError: false
}
}
}
An easy way to start linting is with these two linting plugins.
React specific linting rules for ESLint.
npm install --save-dev babel-eslint eslint-plugin-import eslint-plugin-react
.eslintrc
file:{
"parser": "babel-eslint",
"rules": {
"strict": 0
},
"extends": [
"eslint:recommended",
"plugin:react/recommended"
]
}
This package provides the eslint-config .eslintrc
as an extensible shared config from Airbnb.
npm install --save-dev eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react
.eslintrc
:{
"extends": "airbnb"
}
Just to be feature-complete
with this blogpost, and I don't recommend this, but you can do it, if you really want to disable ESLint.
Just create an empty .eslintrc
file, and it will disable the eslint-loader
and with it all the imported lint rules.
Thanks for reading and if you have any questions, use the comment function or send me a message @mariokandut.
References (and Big thanks): Gatsby docs, Gatsby ESLint community plugin, SPeshov, ESLint
Never miss an article.