DEV Community

Cover image for Configure aliases once and for all with Yarn's link protocol
drazik
drazik

Posted on • Updated on

Configure aliases once and for all with Yarn's link protocol

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

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

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 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:

// in `.storybook/main.js`

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

    return config
  }
}
Enter fullscreen mode Exit fullscreen mode

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 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 which does exactly that 🎉.

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

{
  "dependencies": {
    "app": "link:./assets/js"
  }
}
Enter fullscreen mode Exit fullscreen mode

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 🎉 🎉 ? Not exactly, Vite is not supporting this feature yet (see this issue). 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 😱.

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 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.

👋

Cover image by John Anvik on Unsplash

Oldest comments (4)

Collapse
 
markerikson profile image
Mark Erikson

There's a neat tool called github.com/davestewart/alias-hq that will use your TS config's paths section as the source of truth for aliases, and can give you those back in the right format for use with Jest, Webpack, Node, etc.

Collapse
 
drazik profile image
drazik

Thanks for sharing!

Collapse
 
ianvs profile image
Ian VanSchooten

Did you try using github.com/eirslett/storybook-buil... to build storybook with vite? Feel free to hop in the storybook discord #vite channel if you want any help setting it up.

Collapse
 
drazik profile image
drazik • Edited

Yes but I had some errors. I saw that a new version has been released. I just tested it and it looks good 🎉
Thanks for offering help anyway