The Joy of JavaScript Absolute Imports
- 3 minutes read - 555 wordsAbsolute imports are an essential feature for me in any JavaScript application. In this post, I’ll explain what they are and why they’re great.
What Is An Absolute Import?
It’s easier to think of an absolute import in contrast to a relative import, which looks like this:
import { Page } from '../../views/pages/Page';
Translating this code into words, “bring in the named export Page
, which can
be found ‘up’ two directories and then inside the views/pages
directory.”
Here’s that same import via an absolute path:
import { Page } from 'views/pages/Page';
In words, “bring in the named export Page
, which can be found in the
view/pages
directory.” That directory is relative to some place we don’t know
about. Typically it’s the src/
directory, but we can’t say that in this
context.
The difference between these two statements is subtle, just a few characters. It’s easy to enable this option in every kind of JavaScript application I’ve worked on. Google “absolute imports in X framework” for the implementation in your framework.
Why Are They Great?
I love absolute imports; here are a few reasons why.
First, absolute imports auto-complete well. I use Vim’s ctrl-x ctrl-l
to
autocomplete my import statements, which compares what I’ve
typed so far in a line against other lines in my project, suggesting completions
that I can tab through. Our absolute import is the same regardless of where
Page
is imported, which lets our autocomplete give me a correct suggestion if
it’s ever seen a similar line before. Relative imports won’t work this way
reliably, because my text editor is going to suggest a relative path that’s not
necessary valid given my current buffer’s location.
Second, absolute imports let me easily move files around. When all imports are absolute, there’s no friction to moving a file. All of the imports will just boringly work.
Third, absolute imports scale well. A large React component is typically going to have a lot of imports:
import { AboutUs } from '../../../views/pages/AboutUs';
import { Blog } from '../../../views/pages/Blog';
import { Dashboard } from '../../../views/pages/Dashboard';
import { Login } from '../../../views/pages/Login';
import { Navbar } from '../../navbars/Navbar';
import { PasswordReset } from '../../../views/pages/PasswordReset';
import '../../../stylesheets/Dashboard.scss'
What value are these dots and slashes providing? Remove them and readability increases:
import { AboutUs } from 'views/pages/AboutUs';
import { Blog } from 'views/pages/Blog';
import { Dashboard } from 'views/pages/Dashboard';
import { Login } from 'views/pages/Login';
import { Navbar } from 'navbars/Navbar';
import { PasswordReset } from 'views/pages/PasswordReset';
import 'stylesheets/Dashboard.scss'
Most importantly, absolute imports decouple my code from the directory
structure. The location of Page
relative to where it’s imported is not
important enough information to encode. Or spend any time thinking about.
An Exception For Co-located Stylesheets and Tests
Even with absolute imports as a convention, I still use relative imports occasionally. One use case is a React app with co-located stylesheets and tests. In a directory such as this:
$ ls src/components/
Component.jsx
Component.module.scss
Component.test.jsx
Relative imports are arguably a helpful convention for the co-located files:
// Component.jsx importing its stylesheet
import { styles } from './Component.module.scss';
// Component.test.jsx importing its test subject
import { Component } from './Component';
Conclusion
For an exploration of JavaScript imports, check out my post on the subject, How to Organize JavaScript Imports. I recommend absolute imports for a more joyful JavaScript coding experience.