Live data from Hacker News

Monorepos in JavaScript and TypeScript

robinwieruch.de

21–30 of 79 posts

Re: Monorepos in JavaScript and TypeScript

#21
Good read. I recently ran into this problem with Yarn Workspaces and TypeScript. There doesn’t seem to be a way to keep NPM packages in a monorepo if their TypeScript “lib” configurations clash e.g. a package shared utilities, another for React Native, and the browser.

AFAIK this is due to some limit in TypeScript’s project references. It’s not possible to add a typing lib to a particular package without the checker merging all global namespaces.

Re: Monorepos in JavaScript and TypeScript

#22
post #4
post #2

What is the beneficial distinction between this and composing the monorepo with git submodules? I have been doing that in my codebase after suffering from all the regrets of attempting to emulate npm package releases of my modules. I feel that utilizing submodules feels more pure and conveys isolation and separation. It feels like I am not grokking something vital about why Monorepos > Repo w/ git submodules.

if submodules work for you, there’s no point in changing how you’re working. that said, monorepos solve a certain set of real problems for organizations by allowing contributions across code bases from one VCS repository, and by reframing the release/deploy pipeline around singular atomic refs. the impact is multiplicative and happens in downstream tooling and processes. they squash some problems in one place in the…

Our org is a very small team. The biggest boon is the capability to create cohesive experiences and UI in a small handful of applications that are in isolated codebases by sharing Component libraries. I also use it for improved DX with up-to-date scrubbed and sanitized production data to ensure we aren't breaking things utilizing simplified test data.

Re: Monorepos in JavaScript and TypeScript

#23
post #2

What is the beneficial distinction between this and composing the monorepo with git submodules? I have been doing that in my codebase after suffering from all the regrets of attempting to emulate npm package releases of my modules. I feel that utilizing submodules feels more pure and conveys isolation and separation. It feels like I am not grokking something vital about why Monorepos > Repo w/ git submodules.

I imagine it can get annoying to create another git repo every single time you want to share code between some projects. It becomes an even bigger pain when you have to update more than one repo at the same time. A monorepo makes it easier to keep versions in sync and encourages code reuse because it's all in one place.

That does sound annoying. Though, in our reality it is only a half dozen evergreen projects and applications which are incorporated this way. I do imagine it will grow over time.

Re: Monorepos in JavaScript and TypeScript

#24
post #6

The article doesn't go into how to integrate TypeScript in the monorepo for development - what we do on the Yarn repository is that we point all the package.json `main` fields to the TypeScript sources, then use `publishConfig.main` to update it to the JS artifacts right before being published. This way, we can use babel-node or ts-node to transparently run our TS files, no transpilation needed.

Yeah, I would be interested to hear from others how they accomplish this. I played around with Nx and it uses TypeScript project references. It is a lot of boiler plate to set up every time you want to create a new app or library. Fortunately, their generators do this with one command.

Re: Monorepos in JavaScript and TypeScript

#25
post #12

I had an extraordinarily hard time getting a monorepo set up for a proof of concept for a pretty basic dashboard app. I was using react for the frontend, node for the backend (Typescript for both), and GraphQL for the API. I tried both npm and yarn for "workspaces" but neither really made things any easier. What I wanted most of all was a repo where both frontend code and backend code were based on the same single-so…

Surprised you haven't heard of or used lerna (with yarn workspaces), which is the defacto monorepo setup in JS world. I use it to maintain a bunch of monorepos and works pretty flawlessly.

Re: Monorepos in JavaScript and TypeScript

#26
post #2

What is the beneficial distinction between this and composing the monorepo with git submodules? I have been doing that in my codebase after suffering from all the regrets of attempting to emulate npm package releases of my modules. I feel that utilizing submodules feels more pure and conveys isolation and separation. It feels like I am not grokking something vital about why Monorepos > Repo w/ git submodules.

The biggest gain I get from monorepos is being able to branch many inter-dependendent projects in one command. This is especially valuable when you have a chain of dependencies (A -> B -> C ->... Z). With package-based dependencies living in individual repos, this is tedious work - branch A, modify package.json, build, branch B, update A version to new build, give B new version number, build,..., branch Z. Submodules…

Great points here. We probably have a non-conformist flow when, even though the package deps are defined in the projects that aren't stand-alone, we define them and utilize them in the root projects. This has potential to footgun us.

I have seen several articles addressing the folder/file structure. The author has done an excellent job and taken it a bit further. Now I have questions to research about deployment. What are best practice for isolation of code for Docker images which are to become k8s Deployments and Pods? Does it matter to stuff it all into a mega image? Are Monoimages a thing and what susceptibilities to performance do these yield?

Re: Monorepos in JavaScript and TypeScript

#27
post #6

The article doesn't go into how to integrate TypeScript in the monorepo for development - what we do on the Yarn repository is that we point all the package.json `main` fields to the TypeScript sources, then use `publishConfig.main` to update it to the JS artifacts right before being published. This way, we can use babel-node or ts-node to transparently run our TS files, no transpilation needed.

Yeah, I would be interested to hear from others how they accomplish this. I played around with Nx and it uses TypeScript project references. It is a lot of boiler plate to set up every time you want to create a new app or library. Fortunately, their generators do this with one command.

We use pnpm and meta-updater to keep the TS project references in sync. An example of a project setup that way is pnpm's repo itself.

https://github.com/pnpm/pnpm/blob/main/.meta-updater/src/ind...

Re: Monorepos in JavaScript and TypeScript

#28
post #12

I had an extraordinarily hard time getting a monorepo set up for a proof of concept for a pretty basic dashboard app. I was using react for the frontend, node for the backend (Typescript for both), and GraphQL for the API. I tried both npm and yarn for "workspaces" but neither really made things any easier. What I wanted most of all was a repo where both frontend code and backend code were based on the same single-so…

Surprised you haven't heard of or used lerna (with yarn workspaces), which is the defacto monorepo setup in JS world. I use it to maintain a bunch of monorepos and works pretty flawlessly.

Was the defacto?

Learna needed a new maintainer and is now moving to Nrwl who develops Nx and seems to be the better choice for future projects?

https://nx.dev/

Re: Monorepos in JavaScript and TypeScript

#29
post #2

What is the beneficial distinction between this and composing the monorepo with git submodules? I have been doing that in my codebase after suffering from all the regrets of attempting to emulate npm package releases of my modules. I feel that utilizing submodules feels more pure and conveys isolation and separation. It feels like I am not grokking something vital about why Monorepos > Repo w/ git submodules.

Is it literally just your codebase or a shared one? Generally with submodules we run into issues like each dev having to maintain the setup on their own machine, and unique commands to work with module repositories. For WAY more writeup: https://codingkilledthecat.wordpress.com/2012/04/28/why-your... Whole tools were created to get around these issues (git-subtree for ex).

This isn't the only place this pops up - commit hooks are another example, since they live in .git they don't travel with the repo when it is cloned (or maybe when it is updated, don't remember the specifics).

I really feel there needs to be like a git --pull-config option or something to pull all project configs (including submodules, commit hooks, etc). Or perhaps move those things into the top-level folder and allow them to be git-add'd.

Re: Monorepos in JavaScript and TypeScript

#30
post #6

The article doesn't go into how to integrate TypeScript in the monorepo for development - what we do on the Yarn repository is that we point all the package.json `main` fields to the TypeScript sources, then use `publishConfig.main` to update it to the JS artifacts right before being published. This way, we can use babel-node or ts-node to transparently run our TS files, no transpilation needed.

Yeah, I would be interested to hear from others how they accomplish this. I played around with Nx and it uses TypeScript project references. It is a lot of boiler plate to set up every time you want to create a new app or library. Fortunately, their generators do this with one command.

In the past, I'd put a "typescript:main" field in package.json and configured my bundler to prefer that field. I gave up at some point - probably when I migrated to rollup.

Moving forward, I'm going to use wireit for these things. Pure modules get built with tsc. At the highest level (e.g. where it needs to be embedded in a page), make a bundle with rollup.

wireit has two nice properties: incremental building and file-system-level dependencies. Within a repo, you can depend on ../package-b. However, if you have multiple monorepos that often get used together, you can also depend on ../../other-project/packages/package-b. No matter where in your tree you make changes, wireit knows when to make a new bundle.

I've just started with wireit (it was only launched recently), but it seems to be a nice solution to wrangling dependencies between related JS libraries.

[1] https://github.com/google/wireit

Post reply on HN