Leveraging TypeScript path mappings

Our imports already look much better because we have created barrels, which remove the need for knowing the exact filenames. However, our imports still need to indicate the relative paths to the packages that we want to import symbols from.

This is far from ideal because as your applications grow in complexity, your paths will be longer and longer and you might end up with imports like this: import { foo } from '../../../../../services';.

A good IDE will go a long way to diminish the annoyance, but it will still have an impact on readability and refactoring. Fortunately, we can improve the situation by adapting the compiler's configuration.

In tsconfig.json, we can configure the paths option in order to define mappings. Those mappings will let us use non-relative imports (for example, services).

The paths mapping values are relative to the baseUrl property.

Here's an example:

"paths": { 
    "services": ["services"] 
} 

With this defined in tsconfig.json, we could adapt our imports for the service layer elements like this:

import {PopulationService} from "services"; 

However, if you try this out right away, you'll get errors from Parcel (the bundler that we used to build WorldExplorer). The thing is that Parcel includes its own module resolution mechanism (https://parceljs.org/module_resolution.html), which we need to configure for it to be able to find our modules.

To configure Parcel's module resolution scheme, you need to add an alias property to the package.json file. For example, here's what you could add for the services package:

"alias": { 
    "services": "./src/services" 
} 

With this defined, both the TypeScript compiler and Parcel will happily resolve your modules using friendlier names.

Why don't you go ahead and adapt all the imports in WorldExplorer?

One caveat of the IDEs is that when you use them to add your imports, you might still end up with relative imports, depending on their level of support for TypeScript. In IntelliJ, for example, paths will be taken into account, which is nice, but not all IDEs do that.