Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type definitions for peer packages in TypeScript monorepos: development vs production

I have a monorepo project that uses yarn workspaces and lerna; all its parts are written in TypeScript. The modules are located in subfolders like packages/module-n and each module has its own package.json with the following lines:

"main": "dist/index.js",
"types": "dist/index.ts",

The source code for each package is located in packages/module-n/src/index.ts, so nothing unusual.

When it comes to building from the command line or publishing, all works well – thanks to tsconfig.json and a build script in each package folder. However, when it comes to a day-to-day code editing in VSCode, things become not very convenient, even despite that I run tsc --watch all packages to keep linked dependencies in sync.

When I command-click on a definition that refers to a peer package, VSCode brings me to packages/package-n/dist/index.d.ts instead of packages/package-n/src/index.ts that I may be currently editing. Also, when I want to refactor something with F2, may dist/index.d.ts files get occasionally modified, which forces me to restart build:watch due to errors. The thing is that TypeScript sees manual tweaks in **/dist/index.d.ts and refuses to further update these files.

In order to overcome this inconvenience, I have written these two scripts in the root package.json, but I'm not a big fan of my own solution:

"use-dev-typings": "lerna exec \"replace --quiet dist\\/index\\.d\\.ts src/index.ts package.json\"",
"use-prod-typings": "lerna exec \"replace --quiet src\\/index\\.ts dist/index.d.ts package.json\""

Here is how I'm using them in the same root package.json:

"build": "yarn use-prod-typings && lerna run build",
"build:watch": "lerna run build; yarn use-dev-typings && lerna run --parallel build:watch",

The idea is that before I start editing files in VSCode and thus go for yarn build:watch, I patch all packages/package-n/package.json files by replacing "types": "dist/index.d.ts" with "types": "src/index.ts". This fixes command+clicking and refactoring, which is great. When it comes to one-off building (e.g. before publishing), "types" revert to "dist/index.d.ts".

I'm wondering if there is a better way to achieve what I'm after and it'd be great if someone could give me the advice. I'm pretty sure I will commit "src/index.ts" by an accident one day or even publish a version with this value. The contents of src/*.ts are excluded the npm releases to keep my packages small.

like image 637
Alexander Kachkaev Avatar asked Apr 30 '18 17:04

Alexander Kachkaev


1 Answers

https://github.com/Izhaki/mono.ts

It uses yarn workspaces and marry well with VSCode. I hope the README is clear enough.

Basically, use two (parallel) typescript configuration trees:

  • Pre-build - uses aliases (for VSCode, tests, webpack, etc).
  • Build - uses typescript 3 project references for publishing essentially.
like image 190
Izhaki Avatar answered Oct 05 '22 23:10

Izhaki