How to configure absolute imports in Angular

Last Updated On

If you experienced the following inconvenience:

import { myService } from '../../services/myService';

This article is for you.

Defenetly, there is nothing wrong with this import statement form syntactical point of view. However, this situation might become even worse when you have multiple imports in your class:

import { myService } from '../../services/myService';
import { myModel } from '../../models/myModel';
import * as fromStore from '../../store';
import { myDirective } from '../../directives/myDirective';

The problem here is with relative paths. It's not absolutely clear where our imports are coming from. It would be nice to have straightforward paths to simplify writing of import statements rather than traverse several folders up guessing at which level the proper folder is located.

The Solution

The main goal of this solution is to provide minimal effort to solve this issue avoiding webpack eject.

Here's how we will do it:

Step 1. Add property baseUrl in tsconfig.json. :

"compilerOptions": {
    "baseUrl": "src",
    ...
}

The value should be set to src (will not work otherwise).

Step 2. Add paths object :

{
  "compileOnSave": false,
  "compilerOptions": {
    ...
    "paths": {
      "app/*": [ "app/*" ],
      "environments/*": [ "environments/*" ],
      ...
    }
  }
}

In the paths object we need to specify all folders under src folder in the format mentioned above to be able to use absolute imports. After that, the initial example in this article can be rewritten in the following way:

import { myService } from 'app/services/myService';
import { myService } from 'app/services/myService';
import { myModel } from 'app/models/myModel';
import * as fromStore from 'app/store';
import { myDirective } from 'app/directives/myDirective';

As a result, imports look more organized. The beauty of this approach that it doesn't break existing relative imports and doesn't require webapack configuration at all. The only disadvantage is that it's not possible to use this approach to import something at a root level: for this, you still need to use relative imports traversing to the top.