Update TypeScript Project References for Yarn Workspaces - magically!

Update TypeScript Project References for Yarn Workspaces - magically!

As I've written in an earlier post, TypeScript project references and Yarn Workspaces are powerful tools for managing complex TypeScript projects. Yarn Workspaces manages dependencies between multiple JavaScript packages within one project, and contains tools that let us easily deduce which packages depend on which other packages in our workspace.

Background

Talking specifically about Yarn 2 workspaces, one can simply run the command yarn workspaces list (reference documentation) to get a breakdown of all packages within one project:

Output from yarn workspaces list commad

With this information it is easy to go through each project individually and parse their dependencies from their respective package.json files. For instance, if the package packages/app-nextjs-bootstrap depends on packages/lambda-express, the following dependency would be declared in the package.json of app-nextjs-bootstrap:

 "dependencies": {
    "lambda-express": "workspace:packages/lambda-express"
  }

To configure TypeScript project references, we need to list in the references property of each tsconfig.json all local packages that each module depends on. we need to add the following to the tsconfig.json of the app-nextjs-bootstrap package:

  "references": [
    {
      "path": "../lambda-express"
    }
  ]

While these references are not too difficult to maintain manually, Yarn 2 workspaces provides us with all the information needed for the references configuration in tsconfig.json. Unfortunately Yarn 2 does not maintain these references automatically for us (see yarn/berry#2338).

There are however a number of tools that help with keeping package.json dependencies and TypeScript project references in sync, namely @monorepo-utils/workspaces-to-typescript-project-references and yarn-workspaces-to-typescript-project-references plus a number of scripts such as syncProjectRefs.ts and updateReference.js (created by yours truely).

Automated Tool

None of these integrate with Yarn 2 workspaces natively and I could not get them to work in my monorepo goldstack/goldstack (that contains two levels of nested workspaces). Thus I created a simple tool utils-typescript-references that provides a thin wrapper around the Yarn 2 and allows to easily create project references in sync.

🔗 utils-typescript-references on npm

Please see readme file for how to configure and use this library. When set up, one can simply run a script and all project references in the monorepo will be updated automatically.

$ yarn fix-project-references

Processing package packages/app-nextjs-bootstrap
Setting project references:
../lambda-express

Processing package packages/lambda-express
Setting project references:
../s3

Find an example project configured to use this tool here:

mxro / typescript-project-references-yarn-workspace-sync

For starting your own TypeScript monorepo project, you can use the Goldstack Project Builder that will create projects automatically configured to use utils-typescript-references.

🔗 Build TypeScript Project on Goldstack