Configure aliases once and for all with Yarn's link protocol
Tags: howto, javascript, yarn, npm
Published: 2021-10-24 09:18:04

---
title: Configure aliases once and for all with Yarn's link protocol
published: true
description: A journey from configuring aliases in multiple times for multiple tools to one time at the package manager level.
tags: howto,javascript,yarn,npm
cover_image: https://images.unsplash.com/photo-1617063033111-74cf600531d8?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1176&q=80
---

Lately, I started a front-end project. I picked up a bundler ([Vite](https://vitejs.dev/) because it looks awesome, but the problem is not tied to it) and configured it. In the configuration process, I added an alias:

```js
export default {
  // ... ommitted for simplicity
  resolve: {
    alias: {
      "app": resolve(__dirname, "assets/js")
    }
  }
}
```

The goal of this alias is that when I'm in a deep module and I want to import a file that's far away in the directory structure, instead of importing from `"../../../../models/user"` I can import from `"app/models/user"`. It works like a charm. Neat.

But then I added [Storybook](https://storybook.js.org/) to the project. For some reason, I couldn't use Vite as a bundler in place of the default Webpack, so I couldn't reuse my configuration and get my alias for free in it. But still, the problem would have been the same : new tool means I need to take care of configuring my alias in it. In this case, I had to configure the alias in the Storybook's Webpack configuration:
 
```js
// in `.storybook/main.js`

module.exports = {
  webpackFinal: (config) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      "app": path.resolve(__dirname, "../assets/js"),
    }

    return config
  }
}
```

Doing the same thing twice is annoying but it works and there's very little chance that this will be touched later so I leaved it as is.

Then I added [Jest](https://jestjs.io/) to the project. And... guess what? It also needs this alias in its configuration to resolve it correctly and find my modules. And where Vite and Webpack used a fairly similar syntax, Jest uses a different.

This is the moment I took a step back and asked myself : "isn't it possible to configure it only once?". The package manager (Yarn in my case) seemed to be the perfect place to manage it. It knows about all the modules I use, so it should be able to treat one of my project directories like a module.

I opened Yarn's documentation, looking for a solution to this. And quickly found the [link protocol](https://yarnpkg.com/features/protocols#why-is-the-link-protocol-recommended-over-aliases-for-path-mapping) which does exactly that :tada:.

So, let's configure the alias in `package.json`:

```json
{
  "dependencies": {
    "app": "link:./assets/js"
  }
}
```

Then run `yarn install` and remove the alias configured in each tools, then try to build my app, open storybook and run my tests...

Everything works :tada: :tada: ? Not exactly, Vite is not supporting this feature yet (see [this issue](https://github.com/vitejs/vite/issues/2825)). I hope it will be the case in a near future.

Anyway, thanks Yarn for implementing such a feature, thus making my alias configuration DRY and totally independant of what tools I use!

It's worth noting that it works with TypeScript. I added a `tsconfig.json` file to my project and didn't have to configure the `paths` property, which would have been a fourth way to configure the same thing :scream:.

## Bonus: "but I don't use Yarn, how can I get it?"

I didn't try it, but a little research led me to [`link-module-alias`](https://github.com/Rush/link-module-alias) that seems to enable this feature no matter what package manager you use. Would love to hear your feedbacks in the comments if you are going to try it or already used it in a project.

:wave:

Cover image by [John Anvik on Unsplash](https://unsplash.com/photos/tZIrJ3CgK_Y)