Dealing with TypeScript configs for the mono-repo application.

lukasborawski

Lukas Borawski

Posted on October 22, 2021

Dealing with TypeScript configs for the mono-repo application.

Let’s say that you’re building a mono-repo app. The structure is dividing some services like fronted, backend and docs. This application and the structure can be handled by Lerna — a tool for managing JavaScript projects with multiple packages. What Lerna does (as a part of many features) is the ability to resolve local and global package.json files to use one and correct packages list and representation of dependencies. This means that you can use global packages in all of your services but if you use some package in the frontend app you don’t need to install it for the backend one. And with the Lerna boostrap feature, you can install and manage dependencies for all of your services with one command and process.

OK, take a look at the repo structure.

|root
|--- frontend
|--- backend
|--- docs
Enter fullscreen mode Exit fullscreen mode

Now, let’s say that you want to set some global TypeScript config but use it just for the one service. For example, you’re building some frontend app with TypeScript but the backend one is in plain JavaScript. However, in the future, you might want to use TS for the backend as well. What can we do?

Put your TypeScript config (tsconfig.json) into the root folder. Then define rootDir and place there the frontend app folder name, like this.

{
  "compilerOptions": {
    "rootDir": "frontend",
    "types": [
      "@types",
    ]
  },
}
Enter fullscreen mode Exit fullscreen mode

Now. For sure you’ll need some additional types definitions. Usually, you can define them by adding package names into the types object. Here is the moment when you will get some problems. As the TypeScript config uses the root directory for your frontend services there’s no notation that your types are installed globally and TypeScript is looking for them in your frontend services node_modules.

TS2688: Cannot find type definition file for '@types'. The file is in the program because: Entry point of type library '@types' specified in compilerOptions.
Enter fullscreen mode Exit fullscreen mode

How to deal with this issue? It’s super simple. Just define — in your tsconfig.json file — the typeRoots property and pass there your local node_modules path. You can set it also for the aliases. Like that.

{
  "compilerOptions": {
    "rootDir": "frontend"
    "paths": {
      "~/*": ["./frontend/*"]
    },
    "typeRoots": ["./frontend/node_modules/"],
    "types": [
      "@types",
    ]
    "exclude": ["./*.config.js"]  },
}
Enter fullscreen mode Exit fullscreen mode

One thing, worth mentioning here is that TypeScript probably will look for some globally defined configs like commitlint or stylelint. As they’re in most cases .js files you can exclude them in the tsconfig.json file.

Finally, you need to define some dummy tsconfig.json for your services. So to do that create it and add this simple configuration — in the frontend folder/service.

{
  "extends": "../tsconfig.json",
  "compilerOptions": {}
}
Enter fullscreen mode Exit fullscreen mode

You can also create one TypeScript config file for all of your services and use it across the whole mono-repo. This way you can feel confident that your whole codebase follows one standard.

And that’s it. Simple and very helpful. Enjoy.

Buy Me A Coffee

💖 💪 🙅 🚩
lukasborawski
Lukas Borawski

Posted on October 22, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related