How aliases could simplify your monorepo environment (Vue3 + TS + Jest + Cypress)
✈️ Outlining the p̶r̶o̶b̶l̶e̶m̶ challenge
A few months ago at Evionica we faced a difficult — but very popular — decision: to make mono or poly-repo for our weight & balance app?
Before that time we were handling narrow body pax aircraft only. Then we encountered the need of extending our app functionality to support wide body freighter ones as well. That meant a completely new project, but we aimed to keep both w&b paths as one application.
As usual, there were a lot of tradeoffs to consider but finally, we decided to keep monorepo structure.
🔥A troublesome division
What’s effectively changed since then (at least from our front-end team perspective) was that our codebase has been divided into three parts:
- the narrow body pax one
- the wide body freighter one
- the common one
It concerned:
- The project itself (views, components, stores, services, etc)
- Unit & Integration tests (Jest)
- E2E tests (Cypress)
So, for instance, at our src directory (we use Vue CLI with Vue3 and TS) appeared another folder called modes:
The same “modes” catalogs appeared in each type of test’s directories.
Hence, it followed that from now we had to assign each piece of code to one of three sets. Some elements belong to narrow pax mode, another to wide freighter one, and the other was common.
It is a piece of cake as long as we don’t touch the “imports” subject. We strongly avoid relative imports not to make unnecessary dependencies in our code structure. But it doesn’t make it easier if your catalog tree looks like this:
I don’t think anyone needs convincing that statement like this:
doesn’t look great. Does it? ;)
💡Shortcuts that matter
What I enjoyed during my first experience with Nuxt was their great alias system. Also, Vue CLI provides predefined webpack configuration with @
alias to src
directory (more about Vue CLI webpack configuration here)
So we decided to adopt the idea to our needs.
Because of the different engines (Vue, Jest, Cypress, TypeScript) that manage different parts of our code, it was necessary to configure aliases separately in multiple places.
- tsconfig.json — to support navigation over the aliases imports in dev environment (WebStorm, VSCode, etc.) and correct TS compilation
- vue.config.js — to handle provided aliases in the Vue app
- jest.config.js — to use aliases in unit and integration tests
- e2e/webpack.config.js — to make them available inside e2e tests
Please notice, that every place needed a separate approach:
After that changes we don’t experience hell complicated absolute imports anymore:
✔️ Conclusion
Some solutions look trivial when you’re reading about them, but they are quite complicated during implementation. But it doesn’t matter if they can efficiently improve your team's everyday work for months or years.
Using path aliases was one of these valuable ideas in our case. It could be especially helpful in quite complex monorepos.
So feel free to use the configuration cheatsheet attached above to save a day during setup and countless amounts of time in everyday work later!
~ Maciej Kubiak @ Evionica — 2021