<onWebFocus />

Knowledge is only real when shared.

Absolute Imports

August 2, 2021

Use absolute imports to make develpoment easier.

Relative imports have become a standard in Web Development nowadays. In this article we'll consider the advantages of absolute imports and how these can be used.

Absolute vs. Relative Paths

Absolute paths always specify the full path starting at a certain root independent of where they are used. The root can be configured and is usually the folder of the project you're in. Relative paths on the other hand use the current file where the import is located as the root for the import. To make things more tangible consider the following project structure.

my-app
├── data
└── post.js
├── interface
├── markup
|   ├── header
|   |   └── Header.jsx
└── post
|       ├── Overview.jsx
|       └── Post.jsx
├── configuration
├── index.jsx
└── package.json

Let's imagine we are in the file Overview.jsx where we want to render all available posts.

// Relative imports
import { Post as Store } from '../../data/post.js'
import { Post as PostMarkup } from './Post.js'
// Absolute imports
import { Post as Store } from 'data/post.js'
import { Post as PostMarkup } from 'markup/post/Post.js'

export const Overview = ...

Advantages of Absolute Imports

Absolute imports have the following advantages.

Namespace in Path

Since you can easily see the namespace from the path there is no need to add it to the file. So export names can be shortened.

Copy ✂️ & Paste 📋 Between Folders

If you copy imports from one file to a file inside another folder there is no need to manually adapt the path each time. This is most useful when creating another component by copying another one and modifying the necesssary parts.

No ../.. Hell

Using absolute imports can avoid tons of weirdly looking imports with huge ../../../.. which are hardly readable anymore.

Folder Counting

When you start at the root each time there is no need to count how many folders up you have to go in the file tree. Starting from the root you also get autocomplete which makes typing very quick.

Configuration

Most tools can be configured to use absolute imports pretty easily.

webpack

Absolute imports will be treated like node_modules and can be resolved by adding the root folder of your project to resolve.modules in webpack.config.js.

import { resolve } from 'path'

export default {
  resolve: {
    modules: [resolve(__dirname, '.'), 'node_modules']
  }
}

Depending on whether node_modules is listed first or afterwards paths will be matched against it accordingly. This can sometimes lead to issues when simple filenames collide with package names.

create-react-app

Add a baseUrl pointing to the root in jsconfig.json or tsconfig.json.

{
  "compilerOptions": {
    "baseUrl": "."
  }
}

Check out the official create-react-app Documentation on how to configure the root relative to src in case you don't have any source files in the root.

TypeScript

{
  "compilerOptions": {
    "baseUrl": "."
  }
}

Jest

Jest code is preprocessed with babel. To use absolute imports in tests install babel-plugin-module-resolver and configure it like this.

plugins: [
  [
    'module-resolver',
    {
      root: ['.']
    }
  ]
]

Another Option to Get Absolute References

There is an even simpler way to import directly from the root that does not require any configuration. It's to add a / in front of the absolute path. Paths starting with a dash are always absolute.

import { Post as Store } from '/data/post.js'
import { Post as PostMarkup } from '/markup/post/Post.js'

This will work with webpack and jest out of the box.

Caveats or Disadvantages of Absolute Imports

Absolute imports can be annoying when you use a lot of imports from nearby but few from far away. So the choice also depends on the structure of your project. If there are many self-contained parts relative imports can be simpler. However, with a well structured application where the structure is according to the type of content similar to the Model-View-Controller pattern then it can be very beneficial.

ESLint

Unfortunately, it's not possible anymore to enforce modules be imported before project files with the import/order ESLint rule. This has to be done by hand now as I'm not aware of a way to configure this rule to work with absolute imports.