isaacs / tshy

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

workspace / monorepo usage?

busticated opened this issue Β· comments

hey there πŸ‘‹

thanks for making this awesome tool πŸ™ ❀️ i'm just diving in and wondering if you / the community can provide any usage examples or tips for how to use tshy within a workspace / monorepo. i understand from this comment, that the basic approach is to have each package in the workspace do their own builds. that's something i've done successfully in the past but i'm wondering about some details - specifically:

  • how are you sharing tsconfig.json settings between packages? is it just a matter of each package using "extends": "../path/to/root/tsconfig.json",?
  • how are you wiring up typcheck commands (npm scripts, etc)? does each package implement something like "typecheck": "tsc --project tsconfig.json --noemit" which the root package then runs or..?
  • similarly, what about linting? in the past, i've had eslint just run from the root and treat everything in subdirectories as source code (iow, no package-specific anything) - any reason why that wouldn't work in this case?
  • how do interdependencies work between packages? e.g. assuming "workspaces": ["./packages/*"] in package.json (or equivalent) when packages/a depends on packages/b, what does the import statement look like?
  • when testing, are you targeting compiled (/dist) files or relying on the test runner to build, etc? does each package expose a test command / script or does it work more like linting where tests are discovered + run by some singular root process?
  • any special considerations around publishing? assuming some reasonable amount of orchestration by the root package, is it just a matter of test > tag > build > publish for each package?
  • edit: should we check the .tshy directory into source control?

if it's helpful, i'd be happy to compile feedback here and open a PR with doc updates πŸ‘

answering some of my own questions...

how are you sharing tsconfig.json settings between packages?

a base tsconfig.json in the root package which each workspace package extends works fine. i moved the tsconfig.json that tshy generated for me to my root package and updated my workspace packages to use:

{
  "extends": "../../tsconfig"
}

how are you wiring up typcheck commands (npm scripts, etc)?

in general, it seems the approach of having each workspace package implement a command which then the root package calls works fine. so my root package.json uses:

{
  "scripts": {
    "typecheck": "npm run typecheck --workspaces",
  }   
}

(other bits omitted)

while my workspace package.json files use:

{
  "scripts": {
    "typecheck": "tsc --noemit"
  }   
}

(other bits omitted)


what about linting?

in this case the top-down approach seems good. my root package.json uses:

{
  "scripts": {
    "lint": "eslint . --ext .js,.jsx,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore"
  }   
}

(other bits omitted)

i also added the dist directories to my .gitignore file so all files generated by tshy are ignored. i'm using @typescript-eslint but relying on the typescript that comes with tshy (iow, typescript is not a direct dependency)


how do interdependencies work between packages?

TBD


when testing, are you targeting compiled (/dist) files or relying on the test runner to build, etc?

i went the route of targeting the compiled bits. seems to work fine. each workspace package implements a test script and the root package simply calls them via npm run test --workspaces (or equivalent). i'm using Node's built-in test runner so my package.json uses:

{
  "scripts": {
    "test": "npm run build && NODE_V8_COVERAGE=tmp/coverage node --test --test-reporter spec --experimental-test-coverage --enable-source-maps dist/esm/*.test.js",
    "build": "tshy"
  }   
}

(other bits omitted)


any special considerations around publishing?

TBD


should we check the .tshy directory into source control?

seems so πŸ€—

πŸ•΅οΈ more answers...

how do interdependencies work between packages?

basically, as normal. import statements referencing external packages use that package's name - e.g. import thing from 'my-thing', etc. interdependent packages within the root workspace are installed with: npm install my-thing --workspace path/to/my-thing. (assumes npm@7.x and above - see docs).

NOTE: terminology is a bit awkward imo - "package" === "workspace" when working from your project's root directory

It seems like you've got most of the questions answered?

I'm using tshy quite extensively in https://github.com/tapjs/tapjs (that's actually where it came out of), maybe that could provide some guidance?

I don't find it's very useful to do tsc --noEmit just to type check. Better to just compile the code and let that fail if there's a type problem.

If you do tsc --noEmit, you'll probably want to provide it with something like tsc -p .tshy/esm.json --noEmit (or .tshy/commonjs.json), or else you may get spurious errors from the cjs/mjs shim stuff.