Configuring aliases in webpack + VS Code + Typescript + Jest

Intro

This post is based on this excellent Gist created by Carlos Hidalgo.

When we use imports, one of the things that hurt is working with relative paths. Can you show me an example? Let's imagine we are working with the following folder structure:

Folder structure

And we are editing the file pods/movies/movies-grid.container.ts . In order to add a reference to an element that is located under the api folder, we would have to add the following import:

import {fetchMovies} from '../../api';

If you are handling one or two levels of relative paths, it could be okayish, but in some scenarios you can find imports like:

import { TrainingSummary } from '../../../../model/trainingSummary';

And what's worse, if we want to refactor a folder, we can end up with an imports mess.

How can we solve this? We can create aliases at root folder level. In this way we can minimize the usage of relative paths, e.g. if I create an alias for the api folder, the previous import could be transformed to:

import {fetchMovies} from '/api';

The point here is to create aliases at root folder level and avoid the hell of relative paths.

Sounds great! Is this something easy to configure? Well... it's easy, but there's a trick! You need to add some tweakings on several entry points:

  • You have to configure webpack mappings (we will edit webpack.config.js).
  • You have to indicate VSCode and Typescript the alias mappings (we will edit tsconfig.json).
  • If we are using JEST (unit testing), we have to add additional configuration as well (dependending on where you place these settings, you will have to edit package.json or jest.json).

Let's get our feet wet!

Configuring webpack

Webpack needs to know physical paths that map to the aliases we want to create. In order to inform that mapping, we need to open the wepback.config.js file and add a new section called resolve. There we will establish the mapping between the aliases and the physical paths.

webpack.config.json

module.exports = {
  resolve: {
    alias: {
      api: path.resolve(__dirname, './src/api/'),
      commonApp: path.resolve(__dirname, './src/common-app/'),
      core: path.resolve(__dirname, './src/core/'),
      layout: path.resolve(__dirname, './src/layout/'),
      pods: path.resolve(__dirname, './src/pods/'),      
      scenes: path.resolve(__dirname, './src/scenes/'),
    },
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
  },

The folders mapped to this example are the ones we are using in our application. In your developments, they may vary (you have to enter your own root folders).

Configuring Typescript + Visual Studio Code

Now it's time for the Typescript + Visual Studio Code configuration. We will indicate our root folder starting point (in this case the src folder) and we will add a paths section where we can add our list of aliases (the baseUrl and paths list must be located under the compilerOptions section).

{
  "compilerOptions": { 
    "moduleResolution": "node",
    "baseUrl": "src",
    "paths": {
      "api": ["api"],
      "common-app": ["common-app"],
      "core": ["core"],
      "layout": ["layout"],
      "pods": ["pods"],
      "scenes": ["scenes"]
    }
  }
}

After making this updated, in some cases you may need to execute restart typescript command, or restart Visual Studio Code.

Configuring Jest

Let's move on to our last step. When using Jest, we can achieve this task in two flavours:

A. If we are just adding aliases related to our root folders, we only need to add the following configuration (Depending on your project configuration, you will have to edit the package.json file or the jest.json file.):

If your Jest configuration is located in your package.json file:

    "moduleDirectories": [
      ".",
      "node_modules"
    ],

If your Jest configuration is located in a separate config file:

    "moduleDirectories": [
      "<rootDir>/src",
      "node_modules"
    ],

B. We can add the list of paths to the Jest config file or section. Depending on your project configuration, you will have to edit the package.json file or the jest.json file. In this example we are covering the jest.json solution.

{
  "moduleNameMapper": {
    "^api/(.*)$": "/src/api/$1",
    "^common-app/(.*)$": "/src/common-app/$1",
    "^core/(.*)$": "/src/core/$1",
    "^layout/(.*)$": "/src/layout/$1",
    "^pods/(.*)$": "/src/pods/$1",
    "^scenes/(.*)$": "/src/scenes/$1"
  }
}

Full sample

If you want to see this configuration in action, you can follow these links:

Acknowledgements

This post is based on this excellent gist created by Carlos Hidalgo who spent a whole lot of precious time breaking his head over it just so he could provide us with this perfect step-by-step guide.

About Basefactor

We are a team of Javascript experts. If you need coaching or consultancy services, don't hesitate to contact us.

Doers/

Location/

C/ Pintor Martínez Cubells 5 Málaga (Spain)

General enquiries/

info@lemoncode.net

+34 693 84 24 54

Copyright 2018 Basefactor. All Rights Reserved.