Hacker News new | ask | show | jobs
by lhorie 2060 days ago
We have a pretty large monorepo codebase (460 packages and counting) that we're migrating from yarn v1 to yarn v2. I'll say it's definitely not a plug-n-play migration (pardon the pun).

Some issues we ran into:

- it can be difficult to reason about the layout of peer dependencies. Often times libraries that rely on Symbols or referential equality break and you need to mess with packageExtensions or add resolutions or unplug. Debugging mostly consists of throwing stuff at a wall and see what sticks

- file watching at large enough projects breaks w/ file descriptor exhaustion errors, forcing you to find and unplug the offending libraries

- there's a number of known incompatible libraries (flow being one of the most prominent) and the core team approach to these at this point follows paretto (20% effort for 80% results, e.g. special casing for typescript), meaning I don't believe there will ever be a 100% compatibility milestone w/ the ecosystem

- it's much more black-boxy in terms of day-to-day debugging (e.g. it's much harder to manually edit files in node_modules to trace some root cause)

- we ran into inscrutable errors deep in packages that interface w/ C++ and basically were only able to fix by pinning to an earlier version of a library that did not depend on said package.

- migration cost is heavily proportional to codebase complexity. My understanding is that Facebook gave up on it completely for the foreseeable future and ours has similarly been a significant time investment (and we're not even targeting strict mode yet)

The pros:

- install times and project switching times are indeed fast, even in our codebase that contains multiple major versions of various packages

- yarn v2 has many interesting features, such as protocols (though it's debatable if you want to commit to lock-in to benefit from those)

2 comments

Regarding TypeScript, I think it's important to point out that we have a working PR in the TypeScript repository that we've been maintaining for about a year now. It's not so much special casing as being ahead of trunk. I still hope the TypeScript team will show interest eventually and we'll be able to streamline the development.

[1] https://github.com/microsoft/TypeScript/pull/35206

I meant special casing in the sense that this a conscious effort specifically targeted at Typescript support, as opposed to some generic design that would cater to a large class of projects.

Mind you, I understand that there are legitimate reasons to approach it this way now (e.g. technical limitations, differences in opinion wrt project governance, cost/benefit on long tail, etc). I'm mostly cautioning the unaware that one shouldn't necessarily expect that every package will work under yarn v2 (though an overwhelmingly large majority does work just fine).

From what I've seen, the "unplug" command is supposed to allow you the ability to temporarily unzip a package so that you can do the traditional "hand-edit a file in a dependency" debugging approach.
Yes, but when you're dealing w/ transitive dependencies, often times you need to jump between many packages. And you then need to clean up after your debugging since you typically don't want to leave things unplugged if they don't need to be (as that affects performance).

I'm not saying it's impossible to debug, just that you end up having to jump through more hoops.

Well, you gotta clean up files you've hand-edited in `node_modules`, too, if you've been adding a bunch of `console.log` statements :)

at least this way it's just deleting the temp package folder or running whatever the "replug" command is, instead of having to go figure out all the files you were editing.

Eh, node_modules hacking is certainly not great by any stretch of the imagination, but once you work with it long enough, there's a bunch of stuff that you just get efficient at. Spamming undos in open files is fairly easy. If the editing ends up being a real fix, then you upstream it and install again. There's also considerations about jump-to-definition and similar tools, etc.

You can't accidentally commit your debugging (unplug edits package.json and there's no replug command) and you don't end up with 3 unplugged folders for the same package (that's a whole can of worms on its own). There's also some yarn 2 specific pitfalls regarding __dirname in local packages, symlinking semantics, etc.

Anyways, getting way too into the weeds here, I better stop now lol :)