just spent a day trying and failing to share an enum between my client and server (both TypeScript) using Yarn Workspaces 1/n
the process involved fiddly modifications to 6 separate config files: a root package.json, a root tsconfig, and a package.json + tsconfig for both client and server "peak complexity" is right https://x.com/dan_abramov/stat...
for illustration purposes lets say you're trying to share code in your `server` directory with your `client`
the biggest gotcha (that no one seems to mention...) is that Yarn Workspaces basically doesn't work out of the box for TypeScript
for the uninitiated (read: lucky ones) Yarn Workspaces lets you split up your codebase into local "packages" and trick Yarn into thinking these packages are NPM modules. so you can import/export from them.
this lets you get around things like the create-react-app import restriction https://stackoverflow.com/ques...
because Yarn is treating your local "packages" like NPM modules, its imports from your build folder. (this is how TypeScript npm modules work; even pure TypeScript projects don't send *.ts files to npm. They build their code to *.js and *.d.ts files first
a consequence of this: if you haven't run `yarn build` on your package yet (e.g. if you just set up the project) you'll get the dreated "module not found" error. you will have a hell of a time debugging this because it's a TS-specific problem
another serious consequence of this: you need to re-build your packages every time you update them in order for their exports to be up-to-date (assuming your updates changes the implementation/typings of your exports)
this is extremely obnoxious if you're importing a significant fraction of your server code into your client. I'm importing the type signature of my entire API, because I'm using trpc: #creating-a-client-sdk class="text-blue-500 hover:underline" target="_blank" rel="noopener noreferrer">https://github.com/vriad/trpc#... so I'd have to rebuild every time I make _any_ change.
to get around this, you have to set up Project References, a TypeScript feature that lets you tell the TypeScript engine about dependencies between separate projects (each of which has its own tsconfig.json). https://www.typescriptlang.org...
this is pretty easy, just create a tsconfig.json in the root of your project with this
then wire up the dependencies between your packages, by also using the "references" property in the tsconfig. in your example, you'd just add this to the tsconfig for `client`:
with this set up, your import statements in `client` will reflect the current source code of `server`, so you don't have to rebuild every time 🚀
you might still be getting obscure `Module not found` errors, in which case you're probably using one of the many projects/libraries that don't play nice with Yarn Workspaces' practice of "hoisting" all your dependencies to your project root
Prisma is one of these, as I learned the hard way
So unless you have major space constraints I recommend turning off hoisting by adding this to your root project.json:
"nohoist" is literally not documented anywhere except in the blog post where it was introduced https://classic.yarnpkg.com/bl...
to really twist the knife, the valid values of the "workspaces" config option is documented with a **flow type** 😑
i now believe Next.js will dominate the next 5 years of webdev mostly because they cracked client-server codesharing without any of this bullsh*t
@vriad And it's silently not supported in yarn 2. And that's not documented :/






