Simplifying Imports with TypeScript Path Aliases in Umbraco v14
Tags: webdev, javascript, umbraco, typescript
Published: 2024-04-02 08:00:00

I recently attended the online Umbraco Manchester meetup where Rick Butterfield talked about [Generating a TypeScript OpenAPI client from Umbraco's Content Delivery API](https://www.meetup.com/manchester-umbraco-meetup/events/299649247/). 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**
```javascript
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**
```javascript
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:

```json
{
  "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:

```javascript
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](https://dev.to/markusjoha) great suggestion in the comments, you can avoid having to duplicate your path declarations by installing [vite-tsconfig-paths](https://www.npmjs.com/package/vite-tsconfig-paths)

```npm
npm install -D vite-tsconfig-paths
```

Then updating your vite configuration accordingly.

```javascript
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!