Reputation: 213
I am creating a monorepo using Turborepo consisting of multiple Nestjs microservices, and an API gateway to act as the request distributer. In each microservice, Postgres is used as a database and Prisma as the ORM. Each microservice has its own schema + Prisma client, so it's not a shared schema/client.
We are looking to create a shared package for things like DTOs, as well as prisma generated types and entities. The package would be shared among all microservices so if I would export the prisma generated from the microservices to the package, a cyclic dependency occurs.
I am new to monorepos so this is a complex topic for me to begin with, but I am hoping someone here on Stackoverflow may have some input on the matter. Appreciate it!
Upvotes: 5
Views: 3734
Reputation: 1
Another solution i Came across is to using build version of the repo/db. first transpiling ts to js with tsc then exporting the js file from package.json instead of ts file.
I belive this approach is better as this won't require to changing any build or dev script of nest.
Upvotes: 0
Reputation: 1
Solution i have found is to change the default dev script from nest to ts-node.
What i have done for constant monitoring and restarting is to use devscript as nodemon to constant tracking of file changes.
then in nodemon.json (nodemon config file) using ts-node command to run the script.
//package.json file
"dev": "nodemon"
//nodemon.json file
{
"watch": ["src"],
"ext": "js,ts,json",
"exec": "ts-node src/main.ts"
}
Upvotes: 0
Reputation: 241
We have a similar monorepo regarding Prisma and Turborepo. From our point of view there are two solutions how to avoid cyclic dependencies in a monorepo:
Instead of creating a a shared package for all DTOs, types, etc. that should be used by all packages, leave the DTOs, types etc. inside the packages they come from.
Sometimes it helps to rethink the sizing of the packages. The solution could be to merge some packages to one if they use the same shared code. Or to divide a package into smaller ones, if you only need a small portion of the package to be shared.
If solution 1 is not possible you can add an extra build script that copies the shared content from the packages into the shared one.
In Turborepo you can either have a global script prefixed with //#
that does the job, or you can add the script to each packages, or even both:
// turbo.json
{
"$schema": "https://turborepo.org/schema.json",
"pipeline": {
"build": {
"dependsOn": [
"^build",
"extraBuildScriptFromPackages",
"//#extraGlobalBuildScript"
],
// ...
}
}
}
We use solution 2 to collect all metadata from our packages and create a shared metadata package for the whole monorepo.
For Prisma types we use a mix of solution 1 (for the prisma types) and solution 2 (for the resulting graphql types).
Upvotes: 2