Simplifying Imports with TypeScript Path Aliases in Umbraco v14

2 min read

I recently attended the online Umbraco Manchester meetup where Rick Butterfield talked about Generating a TypeScript OpenAPI client from Umbraco’s Content Delivery API. One really useful tip he suggested was using typescript path aliases to simplify your import paths, but on implementing his suggestion there was one tiny piece of missing information I needed so I thought I’d write this blog post to give a complete picture for any Umbraco package devs building in v14 that are using the recommended tooling (TypeScript + Vite).

Why Use Path Aliases?

In large TypeScript projects, managing imports can become a tedious task. You might find yourself navigating through multiple directories to import a single module. This is where path aliases come into play. They allow you to create shortcuts for directories, simplifying your import statements and making your code cleaner and easier to manage.

Let’s take a look at a before and after example.

Before

import { Order } from '../../models/order.model.ts';
import { OrderLine } from '../../models/order-line.model.ts';
import { SomeComponent } from '../../../core/components/some-component.element.ts';

After

import { Order } from '@uc-models/order.model.ts';
import { OrderLine } from '@uc-models/order-line.model.ts';
import { SomeComponent } from '@uc-components/some-component.element.ts';

Here, @uc-models and @uc-components are path aliases that map to the directories ./src/models and ./src/core/components respectively.

##Setting Up Path Aliases in TypeScript

To set up path aliases in TypeScript, you need to modify your tsconfig.json file. Here’s how you can do it:

{
  "compilerOptions": {
    ...
    "baseUrl": "./src",
    "paths": {
      "@uc-models/*": ["models/*"],
      "@uc-components/*": ["core/components/*"]
    },
    ...
  }
}

In the compilerOptions object, we set the baseUrl to ./src. This is the directory that our path aliases will be relative to. Then, in the paths object, we define our path aliases. Each key is a path alias, and the corresponding value is an array of paths that the alias should map to.

Integrating Path Aliases with Vite

If you’re using Vite as your build tool (which we are at Umbraco), there’s one more step you need to take. You need to define the same path aliases in your vite.config.ts file. Here’s how you can do it:

export default defineConfig({
    ...
    resolve: {
        alias: {
            '@uc-models': path.resolve(__dirname, './src/models'),
            '@uc-components': path.resolve(__dirname, './src/core/components'),
        },
    },
    ...
});

In the resolve object, we define an alias object. This object should have the same keys and values as the paths object in our tsconfig.json file.

UPDATE 2024-04-08 Thanks to Markus Johansson great suggestion in the comments, you can avoid having to duplicate your path declarations by installing vite-tsconfig-paths

npm install -D vite-tsconfig-paths

Then updating your vite configuration accordingly.

import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
  plugins: [tsconfigPaths()],
})

And that’s it! You’ve now set up path aliases in your TypeScript project. This will make your import statements much cleaner and easier to manage. Happy coding!