A Simple Install Test Between Npm, Yarn and Pnpm
Last updated on May 6, 2024 pm
I’m working on my new open-source project docker-wechatbot-webhook recently, it’s a Node.js app that allows you to easily send messages to Wechat through http requests.
A Discussion Of Dockerfile
Three months ago, my friend J were discussed with me about this project’s dockerfile. He thought the npm install
layer may slowed down the docker’s build speed in Github Actions.
1 |
|
J:“Daniel, It’s 2023, why are you still using the broken slow npm to install the node_modules, it’s the time of pnpm — faster and smaller”.
Me: “well, I’ve heard this before, so let’s try it”.
And for the principle of “talk is cheap, show me the PR”, he helped to optimize the dockerfile finally.😂
1 |
|
Pnpm Improves Nothing?
We know, pnpm uses symbol links point to a global space to resolve the node_modules in every project, so that each project installs modules only once in specific version, that’s one of the advantages why pnpm takes little space and install node_modules so quick.
With the high expectation of pnpm’s magic, I found the docker build speed is almost unchanged in Github Actions. 🤨
Why was that? In Github Runner, each building task owns a new environment. it means whether to choose npm , yarn or pnpm , they all need to reinstall again.
Github Actions Cache
If you install node_modules in Github Actions workflow, there comes a way to cache dependencies and build outputs 👉 https://github.com/actions/cache.
What my workflow does is to build dockerfile, upload to dockerHub, and then push a release PR. The npm install
step is only running in docker building progress. So this cache method is helpless.
Docker actually support DLC (docker layer caching) , but Github Actions don’t support it in native.
You can still rely on some third party service to cache layer, however, it makes this node app more complex. it’s not necessary right now.
At least, it claims that I don’t need to alternate it from npm to pnpm at current stage, I know it’s not pnpm ’s fault. one of the reasons is my app is not too much complex, I believed it can speed up my works in local dev.
Performance In Local Dev
I had tested the performance between these 3 package managers in development. built them in 3 different conditions separately for comparing the installation size and time.
- install modules with no cache and no lock file.
- install modules with no cache but with lock file.
- clear cache and remove package manager after building finished.
pkg manager | no cache and no lock file | no cache but with lock File | clear cache and remove pkg manager | clear cache command | problem after remove cache |
---|---|---|---|---|---|
npm | 669 MB / 74.3s | 655.2MB / 36.3s | 568.41MB | npm cache clean –force | |
yarn | 616MB / 59.7s | 616MB / 36s | 467.75MB | yarn cache clean | |
pnpm | 732 MB / 42.5s | 701.67MB / 36.5s | 566.63MB | pnpm store prune | Error: Cannot find module ‘file-box’ |
No cache and no lock file
just like the scene that we init a new project, pnpm is far ahead in installation time than yarn about 40.47%, npm about 74.82%, it’s a incredible score! But yarn has the minimal installation size, pnpm is at the bottom.
No cache but with lock file
like the most common build scene, the installation time is roughly similar, but the size is still minimal via yarn installed, pnpm is at the bottom
Clear cache and remove package manage
yarn is ahead over others in installation size, however, the node_modules that installed via pnpm comes an error when I try to launch my project. but I found it was my fault after I carefully debug the reason.
I was tried to import the module called “file-box” which is not declared in the package.json**.** Actually, it’s a dependency of Wechaty.
Pnpm helped me find an potential issues, it called “phantom dependencies”.
Phantom dependencies is dangerous because it will cause error or crash if “Wechaty” don’t depends “file-box” anymore. Although it runs well in local dev.
Final Thoughts
- Use
pnpm
in most scenarios because it offers faster installation speeds, uses less disk space cross multiple projects, it helps prevent potential issues. - Use
yarn
if you wanna have a minimal app size, like Docker image or other one-time build package.