Exploring the Monorepo #2: Workspaces (npm, pnpm)
Jon Lauridsen
Posted on June 27, 2021
Table Of Contents
Okay so attempt #1 didn't quite work, but all the package managers have a feature called Workspaces, which npm describes like this:
[Workspaces] provides support to managing multiple packages from your local files system from within a singular top-level, root package.
That sure sounds relevant, so let's give it a try!
npm
The npm documentation is so terse I've honestly no clue how to get anything working π€·ββοΈ. If you know your way around npm workspaces I'm happy to swap stories, but for now I'm giving up on this.
pnpm
Documentation here is definitely a step up, with more examples to draw inspiration from. Still a bit hard to grasp though, but I also came across this nice "actual complete guide to typescript monorepos" article by @cryogenicplanet that put some of the details together in an understandable way. Thanks Rahul!
The end-result of workspacifying the product comes out like this:
webby
βββ apps
β βββ api/
β βββ web/
βββ libs
β βββ analytics/
β βββ logging/
β βββ types/
βββ package.json
βββ pnpm-lock.yaml
βββ pnpm-workspace.yaml
βββ tsconfig.json
βΉοΈ This project is prepared on GitHub1s if you'd like to familiarize yourself with the code.
Each app and lib's package.json
is scoped to just that piece of code, so just like before we have a great immediate overview. The real question is: Does it work?
Well⦠apps/web
runs fine:
$ cd apps/web
$ pnpm install
Scope: all 6 workspace projects
ββ Done in 3.2s
$ pnpm start
[razzle] > Started on port 3000
So just running pnpm install
in apps/web
actually resolved all dependencies for the whole repository, which is very nice. And all it takes to configure it are a few lines in the ppm-workspace.yaml
file, so it's all very easy to get working.
But apps/api
fails just as it did in the previous article:
$ cd ../api
$ pnpm start
[api] TSError: β¨― Unable to compile TypeScript:
[api] ../../libs/analytics/src/index.ts(8,3): error TS2564: Property 'uninitializedProperty' has no initializer and is not definitely assigned in the constructor.
With help from @cryogenicplanet's article I finally looked into Typescript Project References, which is a way to tell Typescript how to deal with multiple code pieces. But the same error occurs with or without references so Iβm not sure if theyβre the answer and Iβve just done it wrong or if thereβs a deeper problem.
Conclusion
I'm not sure how to proceed from here. The pnpm tool itself seems to work great, what I need to figure out is how to get Typescript to use each package's own tsconfig file.
At this point I think my best bet is to focus on Typescript configuration, rather than dive further into alternative dependency managers like yarn. If you have ideas of how to get Typescript configured to respect a package's tsconfig settings then please leave a comment.
Posted on June 27, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.