Skip to main content

Release: Yarn 2.3 ๐Ÿฆโœจ

ยท 7 min read
Maรซl Nison
Lead Yarn maintainer

Howdy! Another big month just went by, 2020 confirming being a very weird year for everyone. I hope things will be ok for you, wherever you are.

As for Yarn itself, we're happy to meet you again to talk a bit about the highlights for the work we've done in the third minor of the Yarn 2 release line! Remember that we try to limit these blog posts to about three core items, and that the exhaustive list will always be in our repository. Check it out sometime, there's some very good stuff there too! ๐Ÿ“

Don't know how to upgrade? It's easy: just run yarn set version berry in your project, and you'll get the latest build. Want to skip the upgrade? Just revert the changes!

Info commandโ€‹

Every now and then, we have this dependency that we want to know more about. We want to know its authors, we want to know its license, we want to know its size ... there's a lot of thing we want to know! And sometimes, we want to retrieve those information from many different packages at once.

Yarn already provides the yarn npm info command, but this command is a bit special in that it prints by default the latest info from the npm registry ... and that's not necessarily what we are using!

To address some of the problem with this command, we're now introducing a new top-level command, yarn info. It looks like this:

image

First, wow, that's pretty! But there are a few interesting things we can note about this display:

  • It prints by default the information based on what's currently used by the active workspace. I could use the -A,--all or -R,--recursive flags to change that, though!

  • It prints less information than yarn npm info. For instance, there's little point in printing the README content as a raw single-line string, so we removed it. By default, yarn info will only print the most relevant information.

  • But it prints more information than yarn npm info as well! For instance, because we passed the --cache flag, it also reported the size of the package in the cache, and its exact location.

There are many other gems in the command. By passing the --manifest flag you also get additional fields like the license or the homepage. By passing the --json flag you generate a stream of data that can be easily transformed using jq. You can even add your own data sections if you want, by using our plugin system! Ever wanted a place to show the number of downloads for your dependencies? Their CVEs? Their maintainers? Just use the provided hook, and all those information are yours to give!

Option Documentationโ€‹

You might not be aware of it, but Yarn uses a pretty unique CLI framework: Clipanion. Very few tools have as much requirements as we do, and it was very important for us to be able to fix bugs and implement features without decreasing our velocity.

In the latest Clipanion update, our contributors implemented a syntax to individually document options. Another one took this new feature, and went over every command, documenting each option one by one. The result looks absolutely great:

image

Because our CLI is the source of our website's documentation, you can find the exact same information online. We hope this effort will prove useful to you, as you discover new features you weren't even aware of until now!

Nohoistโ€‹

As package manager authors, we try to do our best to support the ecosystem, sometimes going as far as building features just to help one single large project migrating to better practices. In 2017, in order to let React Native users use our newly released workspaces, we implemented a feature called nohoist.

Nohoist was a bit weird. It accepted glob patterns, and presumably the paths matching this glob pattern couldn't be hoisted. But what if their ancestors were hoisted? Was it meant to support targeting deep packages? After all, it was really only meant to help React Native users in one specific case. Because the feature itself wasn't entirely clear, it suffered from many bugs over the years, where noone really knew what to do of it. In Yarn 2.0, we decided to completely remove it.

Now, the problem is, React Native still doesn't support workspaces without help. And we like React Native users. So we've been looking for a way to reintroduce something similar to nohoist, but in a way that actually made sense to us. That's where we introduce you to hoisting limits:

nodeLinker: node-modules
nmHoistingLimits: workspaces

By configuring the nmHoistingLimits setting to workspaces when using the node_modules linker, Yarn will prevent packages from being hoisted past the workspaces that transitively depends on them. In practice, it means that you don't need to care about the specific hoisting glob patterns: just declare where the hoisting limit is, and Yarn will take care of the rest.

This design is interesting, because it allows us to support one additional feature: "safe hoisting". See, one problem with the classic hoisting is that it makes it very likely that you're going to eventually start referring to dependencies without explicitly listing them. Then your users install your packages, and all hell breaks loose.

By configuring nmHoistingLimits on dependencies, Yarn will prevent packages from being hoist past their transitive top-level dependent. It may seem a bit arcane, said like this, but it's actually quite simple! Imagine the following project:

image

With the default hoisting, it would turn into the following, mistakenly letting you access all dependencies as your own:

image

With nmHoistingLimits set on dependencies, Yarn will instead generate the following, ensuring that you won't ever be able to mistakenly require dependencies you don't list as your own:

image

Of course it has its own drawbacks, since the imperfect deduplication also means an heavier disk footprint and slower installs, but it may provide a good safety valve until you can migrate to standard PnP installs.

What's to come?โ€‹

With Hacktoberfest coming, now is as good a time as ever to let you know about our issues labelled Good First Issues! In fact, we wrote a whole article about it a few days ago.

As for the features we're planning for Yarn 2.4, our focus are currently on:

  • Adding back yarn audit with revamped output
  • New changelog generation capabilities
  • PnP support for the exports field, and ESM in general
  • And more...!

Of course that's only on the top of my head, so it's possible our objectives shift during the next weeks depending on our own priorities - and of course depending on whether you help us or not ๐Ÿ˜›

One very long-term topic we're starting to explore are package support for non- JavaScript languages (think C++, Python, Rust, PHP, ...). We already have a few ideas (we have an experimental branch generating CMake files, and another contributor played with Python), and we'll keep evaluating the work needed to get there during the next few months. If you're familiar with any of those ecosystems and are interested in helping Yarn become the universal package manager, please contact us on Discord!