by Paul Matthew Jaworski

The Most Important ESLint Rule for Redux Applications

tl;dr Run yarn add --dev eslint-plugin-import and add "import/named": 2 to your .eslintrc rules to prevent accidentally importing constants that don’t exist to your reducers.

If you’re developing an application using React and Redux, your reducers probably look something like this:

This example is pretty straight-forward. You’re only importing one constant up top.

Your file structure currently looks like this:

.├── actions|   ├── constants.js|   └── index.js...omitted for brevity...├── reducers|   ├── accountReducer.js|   └── index.js...omitted for brevity...├── indes.js└── index.html

But as your codebase grows, your reducers will become more complicated. Organizing your files by type may no longer makes sense. So you decide to start organizing things by feature or route instead:

.├── actions|   ├── constants.js|   └── index.js...omitted for brevity...├── reducers|   └── index.js├── routes|   ├── accounts|   |   ├── components|   |   ├── containers|   |   ├── module|   |   |   ├── actions.js|   |   |   ├── constants.js|   |   |   └── index.js (exports our reducer)|   |   ├── styles|   |   └── index.js|   └── index.js...omitted for brevity...├── indes.js└── index.html

Awesome! Now you don’t have 100 components in our main components folder anymore. Things are a bit neater, and easier to reason about.

There’s a problem with your refactor, though. Suddenly this import in your reducer is now referring to a non-existent path:

import { RECEIVE_ACCOUNT_SUCCESS } from '../actions/constants';

You get an error about that path being unresolved immediately, so you change it:

import { RECEIVE_ACCOUNT_SUCCESS } from './constants';

Cool. But what if you didn’t actually define that constant in your new file?

Now you’re about to experience one of the most frustrating bugs possible in a Redux app — importing an undefined constant into a reducer. Your tests will break, your app will break, and you’ll bash your head into your desk until you figure it out.

The problem is that this type of bug just fails silently. ES6 imports don’t care whether or not the variable you’re importing is defined. You’ll never see an error about it.

ESLint to the Rescue!

The key to avoiding this type of bug is to installing eslint-plugin-import, then set one simple little rule in your .eslintrc:

"import/named": 2

That’s it! Now you’ll get an error anytime you try to import an undefined constant into one of your reducers.

Edit: Unless you’re extending a base config that already includes it, you’ll also need to add "import" to the plugins section of your .eslintrc. Thanks to Dave Mac for pointing that out!

Happy coding!