20
Import hierarchy
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.
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:
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:
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 and how this can help you I show you how we can create and configure custom import paths to facilitate the import of our applicationso: the routes of my application"
and lastly: my styles. In this case, files named
.styled.js
// 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?
Getting to know eslint-plugin-import-helpers
The eslint-plugin-import-helpers is a package that was created by Will Honey, and aims to complement eslint-plugin-import. It brings a very important use case that is still missing from eslint-plugin-import: the order of imports.
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.
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:
After installing and configuring ESLint and Prettier, we can proceed with the next steps.
At the root of our react project, let's install puglin:
yarn add -D eslint-plugin-import-helpers
Now, let's configure the import-helpers/order-imports rule in the .eslintrc.js
file:
// .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:
coderamos / template-reactjs
This project contains the basic structure for React projects. It also includes my settings for babel-plugin-root-import, eslint-plugin-import-helpers, prop-types, react-router-dom, styled-components and more...
Comment there what you think about this post :)
20