Improving code reviews. Part 2; utilising lint overrides

Tom Parsons
Jun 10, 2020 · 4 min read

Whilst writing part 1 of this series, I became aware that there wasn’t a huge amount of information or advice on how to utilise the overrides feature within eslint (outside of these docs). This is something I recommend utilising as it will allow you to understand when and why we should ignore certain lint rules, making it easier to fix problems as they arise with permanent solutions, rather than temporary ones.

Simply put; specific rules for specific files.

Photo by Avel Chuklanov on Unsplash — (it’s an “over” “ride” get it?)

What you probably do now

Do these look familiar?

/* eslint-disable max-lines */// eslint-disable-next-line no-console

I bet they do, and it’s likely not a stretch to say your codebase is littered with them, it’s not uncommon. There’s actually nothing wrong with this approach as a whole, however, if you’re just doing this, you’re missing out on useful intended and unintended features.

Let’s look at the rule max-lines — it’s useful, we all use it, it’s a good way to remind engineers to ensure their components and functions are not too large and get them thinking about the separation of concerns etc.

However, it’s a rule that perhaps shouldn’t always be applied; for example, in tests. There shouldn’t be the same limits applied to test files as there would be to a component. One approach would be to have /* eslint-disable max-lines */ on every test file, but that makes searching within your codebase for disabled rules that much harder if you have 100 tests, and that line in every test, this would mean:

  • An extra 100 lines of code in your application (urgh)
  • It has to do be applied every time
  • If you miss it your CI might fail
  • When you search for eslint-disable you can’t tell the signal from the noise, you’ll struggle to find where engineers have been hacking something in, or just being lazy.

Let your disabled rules shine, they indicate an area of your codebase that might be prone to breaking or could benefit from a refactor.

What you should be doing

Some lint rules you may want to apply for TypeScript files, and not for javascript files, enter “overrides”, in the example below we can see that for our .js files, we want to utilise the no-unused-vars rule, but for our .ts files, we need to use the specific rule for TypeScript. So we turn one rule on, and one rule off for one set of files, and vice versa for the other.

overrides: [
{
files: ['*.ts', '*.tsx'],
rules: {
'no-unused-vars': 0,
'@typescript-eslint/no-unused-vars': 2
}
}, {
files: ['*.js', '*.jsx'],
rules: {
'no-unused-vars': 2,
'@typescript-eslint/no-unused-vars': 0
}
}, {
files: ['*.test.*'],
rules: {
'max-lines': 0
}
}
]

You’ll also see here, that I have turned off the max-lines rule for all of the test files.

These are carefully curated choices to aid engineers as much as possible. Generally speaking, if for some reason one rule needed to be turned on, or off, for one particular file, overrides might be overkill, and adding it to the singular file, perhaps with a comment as to why it will be much easier in the long run.

Looking at this as part of the bigger picture:

Essentially, one of the goals here is to not use the disable feature within eslint, as we might argue that if we’re disabling a rule in a specific place, we may need to look at why, and what is happening which means we need to break a rule (though of course there are valid reasons). We also don’t want to necessarily remove rules wholesale.

Some examples of good places to use lint overrides:

  • TypeScript; I mentioned in my previous article, we don’t allow for import PropTypes from prop-types in typescript files as they’re not used (this was a reactive rule to help with upgrading, here is how to action that:
overrides: [
{
files: ['*.ts', '*.tsx],
rules: {
'no-restricted-imports': ['error', {paths: ['prop-types']}]
}
}
]

This allows for a large amount of creativity, for example, maybe you don’t allow for lodash in a certain part of your codebase:

overrides: [
{
files: ['*/newComponents/**'],
rules: {
'no-restricted-imports': ['error', {paths: ['lodash']}]
}
}
]
  • Casing; Enforcing casing is easy, but it doesn’t mean your backend team or your 3rd party API doesn’t conform to your standards!
overrides: [
{
files: ['*.ts', '*.tsx'],
rules: {
'@typescript-eslint/camelcase': ['error', {
allow: ['user_id']
}]
}
}
]

Be careful with this feature, making the overrides more and more complex can lead to lots of problems with the code base, so use it sparingly. Overuse might indicate there are larger problems at hand.

Happy Linting!

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store