DEV Community

Cover image for Creating a scalable Monorepo for Vue - Libs vs Apps
Dawid Nitka
Dawid Nitka

Posted on

Creating a scalable Monorepo for Vue - Libs vs Apps

One of the steps in creating a monorepo is splitting apps and libraries. But how to take them apart? What is a library and do you have to publish it somewhere?

The simplest answer is that a library is reusable code. To name a few, it can be your UI library, API files that will be reused, or even some library with useful functions—our well-known: helperThis, helperThat, ... In the case of Vue, it can also include a bunch of compostables (ex. useSomething). There's no need to publish them anywhere. They will be used directly from your libraries.

 

Setting up the consumer (app)

Let's assume you already have a couple of candidates to put them outside your app and reuse them. The next question is how to connect them.

In the previous post I mentioned adding libraries to the package.json (sample below) file, but it's only one side of the story.

{
    "name": "@monorepo/app_1",
    "version": "1.0.0",
    "type": "module",
    "scripts": {
        // ...
    },
    "dependencies": {
        "@monorepo/commons": "*",
        "@monorepo/ui": "*"
    },
    // ...
}
Enter fullscreen mode Exit fullscreen mode

 

Setting up the provider (library)

The other side which is the library has to define all files that should be approachable from outside. Of course, it can be just some index file, but it could be a sub-directory as well - there's no need to set every file independently. All this has to be put in the library's package.json file.

{
    "name": "@monorepo/commons",
    "version": "1.0.0",
    "type": "module",
    "exports": {
        ".": "./src/index.ts",
        "./composables/*": "./src/composables/*"
    },
    "scripts": {
        // ...
    },
    "dependencies": {}
}
Enter fullscreen mode Exit fullscreen mode

 

Typescript and intellisense

The sample above should give you already an idea of how to connect things. To use it you can just:

import someHelper from "@monorepo/commons/composables/analytics"
Enter fullscreen mode Exit fullscreen mode

You will still notice that TypeScript running in the background cannot recognize imported libraries. To solve this add explicit such paths to the project's tsconfig.json file (section paths).

{
    "compilerOptions": {
        "paths": {
            "@monorepo/commons": [
                "../../libs/commons/src/*"
            ],
        },
    },
    // ...
}
Enter fullscreen mode Exit fullscreen mode

The first part is what you want to use during the import and the second is a direct path to the file or directory.

As a bonus it also makes Vue components show you all expected parameters in the form of intellisense as if they were added directly to your project.

 

Setting up custom paths

I explicitly set @monorepo/commons to point to the library's /src directory. If the /src directory is exported in the library's package.json, it's enough to make it work.

You can also define your own, so-to-say, "nicknames". This practice is often used to create paths that are shorter and thus easier to use and remember.

For example instead of using:

import someHelper from "@monorepo/commons/composables/analytics"
Enter fullscreen mode Exit fullscreen mode

you could use

import someHelper from "@monorepo/commons/analytics"
Enter fullscreen mode Exit fullscreen mode

To achieve it you have to define such a shortcut in the library's package.json

{
    "name": "@monorepo/commons",
    // ...
    "exports": {
        "./analytics/*": "./src/composables/analytics/*",
    },
}
Enter fullscreen mode Exit fullscreen mode

as well as add it to the app's tsconfig.json file

{
    "compilerOptions": {
        "paths": {
            "@monorepo/commons": [
                "../../libs/commons/src/*"
            ],
            "@monorepo/commons/analytics": [
                "../../libs/commons/src/composables/analytics/*"
            ],
        },
    },
    // ...
}
Enter fullscreen mode Exit fullscreen mode

If you want to know more about creating a monorepo check out other tutorials in the series. If you prefer testing things on your own - try this template, where I put all of this into work.

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (0)

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay