Import hierarchy
Tags: react, javascript, codequality
Published: 2021-06-28 20:04:16

*making your imports more elegant and organized | part II*

Today we will continue talking about how to make our imports more elegant and organized. For that, we need to talk about **import hierarchy**.

## What is Import Hierarchy?

As the name itself makes clear, import hierarchy is the order of priority of the dependencies imported in our code.

It is very common that our `.js` and `.jsx` files import many libraries, components, pages, controllers, services, helpers, styles, that is, a multitude of different file types and data.

The example below is very common in the daily life of a front end developer:

```jsx
import React, { useState, useEffect } from 'react';
import Button from '~/components/Button';
import { Container } from './styles.js';
import Card from '~/components/Card';
import PropTypes from 'prop-types';
import { combineReducers } from 'redux';
import Main from '~/pages/Main';
import Dashboard from '~/components/Dashboard';
import Home from '~/pages/Home';
import Routes from '~/routes';

function ExampleComponent() { ...
```

Looking at the code above you may wonder: "I don't see any problem with this code".

And in fact, there isn't. The required dependencies have been imported and are ready to be used.

> But if we can make it more organized, **why not**?

Below I show the same example, only more organized:

```jsx
import React, { useState, useEffect } from 'react';
import { combineReducers } from 'redux';

import PropTypes from 'prop-types';

import Home from '~/pages/Home';
import Main from '~/pages/Main';

import Button from '~/components/Button';
import Card from '~/components/Card';
import Dashboard from '~/components/Dashboard';

import Routes from '~/routes';

import { Container } from './styles.js';

function ExampleComponent() { ...
```

In the example above, I ordered the imports as follows:

* **first**: all the dependencies that I consider the most important of my application. For example, all those starting with 'react' and 'redux'

* **then**: all other libraries and modules installed in package.json. For example, Prop Types, Storybook, Unform, among others

* **then**: all internal files, which start with the alias `~/` or `@`. For example, `~/components`, `~/pages`, `~/styles`, `@controllers`, `@models`, and so on. In the post [Import custom paths](https://dev.to/coderamos/custom-import-paths-and-how-it-can-help-you-a1h) and how this can help you I show you how we can create and configure custom import paths to facilitate the import of our application

* **so**: the **routes** of my application"

* **and lastly**: my styles. In this case, files named `.styled.js`

```jsx
// first, everything that starts with 'react' and 'redux'
import React, { useState, useEffect } from 'react';
import { combineReducers } from 'redux';

// then all imported modules and libraries
import PropTypes from 'prop-types';

// then anything that starts with an alias '~/pages' or '@pages'
import Home from '~/pages/Home';
import Main from '~/pages/Main';

// then anything that starts with an alias '~/components' or '@components'
import Button from '~/components/Button';
import Card from '~/components/Card';
import Dashboard from '~/components/Dashboard';

// so my routes
import Routes from '~/routes';

// and finally, my styles
import { Container } from './styles.js';

function ExampleComponent() { ...
```

Of course, maintaining this hierarchy for all our code takes a lot of time, attention, and care.

But it's a good thing we can automate this task, isn't it?

![do you think?](https://media.giphy.com/media/W3a0zO282fuBpsqqyD/giphy.gif)

### Getting to know [eslint-plugin-import-helpers](https://github.com/Tibfib/eslint-plugin-import-helpers)

The **eslint-plugin-import-helpers** is a package that was created by [Will Honey](https://twitter.com/Tibfib), and aims to complement [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import). It brings a very important use case that is still missing from eslint-plugin-import: the **order of imports**.

### About order-imports and how it works

The **eslint-plugin-import-helpers** brings (as of the date of this post) only the order-imports plugin. This plugin allows you to configure an import hierarchy with just a simple `.eslintrc.js` configuration file.

### Making it happen

First of all, you will need to have **ESLint** and **Prettier** configured in your project. If by chance you haven't configured it yet, I suggest you follow this tutorial:

{% youtube TI4v4Y8yRjw %}

After installing and configuring ESLint and Prettier, we can proceed with the next steps.

#### Installing and configuring eslint-plugin-import-helpers

At the root of our **react** project, let's install puglin:

```bash
yarn add -D eslint-plugin-import-helpers
```

Now, let's configure the **import-helpers/order-imports** rule in the `.eslintrc.js` file:

```js
// .eslintrc.js
rules: {
  'import-helpers/order-imports': [
    'warn', // displays an alert in the editor
    {
      newlinesBetween: 'always', // inserts a blank line after each priority group
      groups: [
        ['/^react/', '/^redux/'], // first group: everything that starts with 'react' and 'redux'
        '/styled-components/', // second group: everything that is imported directly from the styled-components library. This is to ensure that the first import in styles.js files is always styled-components.
        'module', // third group: everything that is a module (any library listed in the package.json file)
        '/prop-types/', // fourth group: importing prop-types
        '/^~/pages/', // fifth group: all my pages
        '/^~/components/', // sixth group: all my components
        ['parent', 'sibling', 'index'], // seventh group: any parent, sibling, or child file of the current file
        '/routes/', // eighth group: my routes
        '/^~/', // ninth group: all other files imported by the configured alias
        '/styles/', // last group: my styles
      ],
      alphabetize: { order: 'asc', ignoreCase: true }, // configures imports in alphabetical (ascending) order, ignoring case
    },
  ],
}
```

All ready!

If you have configured prettier to automatically fix ESLint improvement suggestions, whenever this hierarchy is not respected, VSCODE will reorganize the imports automatically as soon as the file is saved.

---

If you want to see this example in practice, you can take a look at the template I created for React projects here:

{% github coderamos/template-reactjs no-readme %}

---

Comment there what you think about this post :)