w3resource

Overview of PnP


PnP is a Yarn feature that should not be confused with pnpm (a standalone JavaScript package manager).

Plug'n'Play is an alternative installation strategy that was unveiled in September 2018. PnP presents us interesting characteristics that makes it suitable for a large panel of projects, it is designed to be compatible with the current ecosystem.

When you run Yarn install, Yarn will generate a node_modules folder that Node can consume. In this context, Node does not know what the package is about: it will only reason in terms of files. This are the steps Node will take:

  1. Does this file exist here? No?
  2. Check inside the parent node_modules then. (Does it exist here? Still?)
  3. Then it is in the parent folder.

Node will continue to do this until it finds something that matches one of the possibilities.

Now since Yarn has all the information about your dependency tree (You actually use Yarn to install them), why exactly do we need to use Node to locate your packages on the disk. When you can simply query Yarn and it informs us where to look for a package Y by a package X? When you use Yarn to query the dependency tree, it is known as Plug'n'Play (Pnp). We just have to generate a single .pnp.js file, and let Yarn tell us where we can find our packages, rather than generating a node_modules directory and then leaving the resolution to Node. The benefits of doing this are:

  • The node_modules directory has a gargantuan amount of files. When you generate this folder, it will make up for more than 70% of the time that you need to run yarn install with a hot cache. Since the copy is I/O bound, package managers cannot really optimize - you can use hardlinks or copy-on-write, but even then you will still need to make a bunch of syscalls that dramatically slow you down.
  • Since Node does not have a concept of "package", it does not know whether a file is meant to be accessed, on top of being available. It is actually possible that the code you wrote will work during development but break when you switch to production because you forgot to list one of your dependencies in your package.json file - and most times you will not know it until it becomes a problem and you have lost a day investigating the issue.
  • Even at runtime, the Node resolution will need to make a bunch of stat and readdir calls so as to figure out where a resolution should end up. It is extremely wasteful, and is part of the reason that booting a Node application takes so much time - this is because Node will spend time querying the filesystem for information before even starting executing it, and this is actually information that Yarn could have easily given to it.
  • Finally, the very design of the node_modules folder is impractical because it does not allow us to dedupe packages as efficiently as one would hope. Since two packages with the same name but different versions cannot coexist in the same directory, we cannot guarantee a perfect hoisting. Also, since the node_modules folder is deeply nested in a way that depend on the project dependencies, they can't be shared from one project to the other.

Plug'n'Play solves all these problems and more.

Previous: Getting started with Plug n Play
Next: Troubleshooting



Follow us on Facebook and Twitter for latest update.