Yarn 4.0 is officially released, with greatly improved performance!

Hello everyone, my name is Ruochuan. I have been organizing source code reading activities for nearly a year. If you are interested, you can click here to scan the code and add me on WeChat lxchuan12 to participate. Every week everyone will learn about 200 lines of source code together and make progress together. At the same time, it is highly recommended to subscribe to the “Learning the Overall Architecture of Source Code Series” written by me, which contains more than 20 source code articles. History interview series. In addition: There is currently a Jiangxi | Hunan | Hubei | Henan front-end group. You can add me to the group on WeChat. Reply to the keyword “Blind Date” on the public account to get the menu for boys and girls~

On 10.23, the Yarn team finally released Yarn 4 after more than a year of hard work and 53 candidate versions. A stable release of x.

Breaking Change Quick Fact

If you are currently using 3.x, you need to know the following points:

  • Currently requires Node.js 18 + version;

  • New projects created using yarn init will no longer have Zero-Install enabled by default;

  • New projects created using yarn init will use Corepack instead of yarnPath;

  • All official plugins (typescript, interactive-tools…) are now included by default.

  • yarn workspaces foreach command syntax slightly changed

Corepack

Since the Yarn 2.0 version, the official recommendation is to use the yarnPath setting to install Yarn in each project (can be done via yarn init -2 or yarn set version automatically set).

Additionally, it has been recommended in the past to use a yarnPath setting to point to a checked-in binary, but this pattern adds some unnecessary hassle and many people don’t like adding binaries to their code base. , even if it’s small.

To this end, Yarn collaborated with Node.js to develop a project called Corepack.

Corepack is a tool shipped with Node.js 16 + that automatically selects the correct package manager version based on the project you are working on.

e8239fb24c1471dfdd6fe12ad7ab512b.png

Now that Corepack has been released with Node 18 and 20, Yarn no longer depends on yarnPath. The yarn init -2 and yarn set version commands have also been updated to update packageManager fields where possible.

Corepack knows which package manager version to use via the standard packageManager field in package.json. This field is typically set via yarn init -2, yarn set version x.y.z or more generally corepack use [email protected].

Hardened Mode

Yarn adds a new mode (Hardened Mode) to try to protect users from some common attacks.

When running in this mode, Yarn will perform two additional validations:

  • Verify whether the parsing rules stored in the lock file are consistent with the versions that can be parsed by the scope.

When we define a dependency range in the project (such as a version range specified using symbols such as “^” or “~”), Yarn will parse and select the appropriate one based on these ranges. version installed into the project. However, sometimes problems may arise when resolving dependencies, for example the scope may not resolve to a compatible version that satisfies all dependencies, or the scope may be too loose resulting in too many dependencies being installed.

  • Verify that the npm package element metadata stored in the lock file is consistent with the metadata in the remote registry.

These operations are actually used to prevent some attackers from secretly modifying our lock file when using Yarn to PR our project.

5c97048a078057aae94c712e53b9d861.png

We can proactively enable Hardened Mode via enableHardenedMode, but when Yarn detects its GitHub Pull Request < on a public repository It is also automatically enabled when running in /code>. This feature can be disabled by explicitly turning off enableHardenedMode in the yarnrc file.

Additionally, installations running under Hardened Mode constraints will be much slower than normal because they need to perform many additional network requests, so enabling it by default is not recommended.

If you need to enable it in a specific CI Job, you can turn it on through an environment variable:

export YARN_ENABLE_HARDENED_MODE=1

New constraint engine

Yarn is currently the only package manager that implements a constraint engine, a feature that allows us to define a set of rules that a project must meet.

Suppose we have two workspaces (Workspaces) in our project: A and B, and they both depend on the same package, such as "lodash".

In previous versions, if workspace A depended on "lodash@^3.0.0", and workspace B depended on "lodash@ ^4.0.0", Yarn will allow this situation and install "lodash@^3.0.0" and respectively when installing dependencies. "lodash@^4.0.0".

However, sometimes such situations can lead to conflicts and problems. To solve this problem, Yarn introduces the JavaScript constraint engine.

Using the JavaScript constraint engine, we can define rules to limit the version relationships of dependencies between workspaces. For example, you can define a rule that requires all workspaces to use the same "lodash" version.

Yarn's constraints engine was historically powered by Tau-Prolog, a JavaScript Prolog implementation. Unlike imperative languages like JavaScript, Prolog uses a different model called logic programming - a rule that defines something to exist if it is true. This is a very interesting pattern that combines well with the rule-based concept of linting. Unfortunately, Prolog proved to be very complex to use, increasing the learning curve of constraints beyond the threshold of what everyone would accept.

Therefore, starting with Yarn 4, the Prolog constraints have been deprecated and replaced by a completely new engine based on JavaScript, with optional TypeScript is supported!

For example, in the simple example below, yarn.config.cjs will force all react dependencies to be set to 18.0.0.

module.exports = {
  async constraints({Yarn}) {
    for (const dep of Yarn.dependencies({ ident: 'react' })) {
      dep.update(`18.0.0`);
    }
  },
};

The following constraint forces the engines.node field to be set correctly in all workspaces:

module.exports = {
  async constraints({Yarn}) {
    for (const workspace of Yarn.workspaces()) {
      workspace.set('engines.node', `20.0.0`);
    }
  },
};

Optimize command line interface

To better convey information, various parts of the CLI interface have been improved. For example, yarn install now tells us which new packages were added, and their total weight. Additionally, it no longer prints warnings related to sibling dependencies as it did before, it now only prints warnings if it is actionable:

1c82fe3a4fc7347c435d2e01d7fafde7.png

Another example is the yarn config command, which displays a new tree display and now also accepts any number of settings as positional arguments, let's choose what you want to see:

df1035727203a8111ef39da2aeaab72f.png

Performance

4.0 is significantly faster to install than 3.6. For example, here's the difference in time to install Gatsby and its ~350MB dependency tree from cache. Performance has been improved by 3 times due to a new package metadata cache that significantly improves the performance of repeated installations:

hyperfine -L v stable,canary --prepare 'rm -rf ~/.yarn/berry/cache' 'cd $(mktemp -d) & amp; & amp; yarn init -2 & amp; & amp; yarn set version {v} & amp; & amp; yarn & amp; & amp; yarn add gatsby --mode=skip-build'

ed99200254b914ab40826be4b7183160.png

At present, the performance of Yarn is basically close to that of pnpm in most cases.

New official website

In addition, Yarn’s official website has also received a new revision, including new commands, configuration documents, etc.

d6154c14bba0dc5458234ef4d16af148.png

Finally

refer to:

  • https://yarnpkg.com/

  • https://yarnpkg.com/getting-started

  • https://yarnpkg.com/blog/release/4.0

syntaxbug.com © 2021 All Rights Reserved.