Yarn/npm linking slow across volumes
Yarn (and npm) were getting exceptionally slow on my system. Rather than accepting the ever longer install times, I tried solving the underlying problem.
For me, the problem turned out to be the case-sensitive volume I was using.
TLDR: Set cache folder to the same volume when working on another volume.
The problem
Both npm
and yarn
commands were dreadfully slow for larger projects.
I won't dive into npm here, but for yarn, I noticed that the linking took the bulk of the time.
The linking phase actually copies the files from the global cache dir to your local node_modules
.
For me the global directory is different from the volume where I keep my projects.
I use a case-sensitive filesystem wherever I can - one less source of hard-to-pin-down bugs.
On top of that, a case-sensitivity is the team-friendly option when you are sharing anything.
Try changing a file casing on a case-insensitive filesystem in a large project to understand what I'm getting at ;).
OS X is pretty poor on the case-sensitivity front. There's a hidden option on first boot to enable it system wide. If you didn't do that, you're pretty much stuck using a case-sensitive volume that is mounted on boot.
The problem is when you use your packager on this volume.
Step 2 of yarn fetches packages to yarn cache dir
: /Users/name/Library/Caches/Yarn/v6
.
And step 3, linking, copies those packages to your project node_modules
, crossing a volume boundary.
This is the sluggish process.
The solution
Use a cache directory on the same volume as your project directory.
If, like me, you only use the same volume for your work then you can set the cache dir globally:
mkdir -p ~/CaseSensitiveWorkspace/caches/Yarn
yarn config set cache-folder ~/CaseSensitiveWorkspace/caches/Yarn
If you don't want a global config you can also supply a --cache-folder
flag to the yarn
command.
Or you can set the YARN_CACHE_FOLDER
env variable.
See the official documentation for details.
Result
For a running large react-native project yarn add
went from 180 seconds to 17 seconds.
On top of that, the system didn't freeze anymore because of excessive IO.
A pleasant result for such a simple fix.
NPM cache
NPM of course has the same problem. While I haven't looked into NPM specifically, I'm sure the solution is similar. The following commands should help:
- Get cache dir location:
npm config get cache
- Set cache dir location:
npm config set cache --global <dir>