Si sou un desenvolupador de Node.js , coneixeu npm i Yarn . Fins i tot podeu tenir una opinió ferma sobre l'ús d'uns sobre els altres. Durant anys, els desenvolupadors han estat lluitant amb la inflor (en l'emmagatzematge del disc i el temps de creació) quan treballen amb gestors de paquets Node.js, especialment npm .
Després, va venir pnpm , un gestor de paquets que gestiona l'emmagatzematge de paquets de manera diferent, estalviant espai als usuaris i reduint el temps de creació. Així és com pnpm descriu la diferència :
"Quan instal·leu un paquet, el guardem a una botiga global de la vostra màquina i, a continuació, en creem un enllaç dur en lloc de copiar-lo. Per a cada versió d'un mòdul, només es conserva una còpia al disc. Quan utilitzeu npm o yarn, per exemple, si teniu 100 paquets amb lodash, tindreu 100 còpies de lodash al disc. pnpm us permet estalviar gigabytes d'espai en disc!
No és d'estranyar que pnpm estigui guanyant força, amb cada cop més desenvolupadors que el converteixen en el seu gestor de paquets preferit. Juntament amb aquesta creixent taxa d'adopció, molts desenvolupadors que executen les seves aplicacions a Heroku (com jo) volien veure compatible amb pnpm.
Afortunadament, pnpm està disponible a través de Corepack , que es distribueix amb Node.js. Per tant, a partir del maig de 2024, pnpm ja està disponible a Heroku !
En aquesta publicació, explicarem què cal per començar amb pnpm a Heroku. A més, també mostrarem alguns dels avantatges d'emmagatzematge i temps de construcció que obteniu en utilitzar-lo.
pnpm es va crear per resoldre el problema de llarga data del gestor de paquets Node.js d'emmagatzematge redundant i ineficiències en la gestió de dependències . npm i Yarn copien les dependències als node_modules
de cada projecte. En canvi, pnpm manté tots els paquets de tots els projectes en una única botiga global i després crea enllaços durs a aquests paquets en lloc de copiar-los. Què vol dir això?
Suposem que tenim un projecte Node.js que utilitza lodash
. Naturalment, el projecte tindrà una carpeta node_modules
, juntament amb una subcarpeta anomenada lodash
, plena de fitxers. Per ser exactes, [email protected]
té 639 fitxers i una altra subcarpeta anomenada fp
, amb altres 415 fitxers.
Això són més de mil fitxers només per lodash
!
Vaig crear sis projectes Node.js: dos amb pnpm, dos amb npm i dos amb Yarn. Cadascun d'ells utilitza lodash
. Fem una ullada a la informació d'un sol dels fitxers de la carpeta de dependència lodash
.
~/six-projects$ ls -i npm-foo/node_modules/lodash/lodash.js 14754214 -rw-rw-r-- 544098 npm-foo/node_modules/lodash/lodash.js ~/six-projects$ ls -i npm-bar/node_modules/lodash/lodash.js 14757384 -rw-rw-r-- 544098 npm-bar/node_modules/lodash/lodash.js ~/six-projects$ ls -i yarn-foo/node_modules/lodash/lodash.js 14760047 -rw-r--r-- 544098 yarn-foo/node_modules/lodash/lodash.js ~/six-projects$ ls -i yarn-bar/node_modules/lodash/lodash.js 14762739 -rw-r--r-- 544098 yarn-bar/node_modules/lodash/lodash.js ~/six-projects$ ls -i pnpm-foo/node_modules/lodash/lodash.js 15922696 -rw-rw-r-- 544098 pnpm-foo/node_modules/lodash/lodash.js ~/six-projects$ ls -i pnpm-bar/node_modules/lodash/lodash.js 15922696 -rw-rw-r-- 544098 pnpm-bar/node_modules/lodash/lodash.js
El fitxer lodash.js
té una mida d'una mica més de mig megabyte. No estem veient enllaços suaus, així que a primera vista sembla que cada projecte té la seva pròpia còpia d'aquest fitxer. Tanmateix, aquest no és realment el cas.
Vaig utilitzar ls
amb la bandera -i
per mostrar l' inode del fitxer lodash.js
. Podeu veure als projectes pnpm-foo
i pnpm-bar
, tots dos fitxers tenen el mateix inode ( 15922696
). Apunten al mateix fitxer! Aquest no és el cas de npm o Yarn.
Per tant, si teniu una dotzena de projectes que utilitzen npm o Yarn, i aquests projectes utilitzen lodash
, tindreu una dotzena de còpies diferents de lodash
, juntament amb còpies d'altres dependències en aquells projectes que ells mateixos utilitzen lodash
. A pnpm, cada projecte i dependència que requereix aquesta versió específica de lodash
apunta a la mateixa còpia global, única.
El codi de [email protected]
té una mida de poc menys de 5 MB. Preferiríeu tenir-ne 100 còpies redundants a la vostra màquina o només una còpia global?
Al cap i a la fi, la instal·lació de dependències amb pnpm és significativament més ràpida, i requereix menys espai en disc i menys recursos. Per als desenvolupadors que treballen en diversos projectes o gestionen dependències a plataformes al núvol, pnpm ofereix una manera més ràpida i ràpida de gestionar paquets. Això fa que pnpm sigui ideal per a un entorn de desplegament simplificat com Heroku.
Estàs preparat per començar a utilitzar-lo? Anem a veure com.
Aquí teniu la versió de Node.js amb la qual estem treballant a la nostra màquina:
$ node --version v20.18.0
Com hem esmentat anteriorment, Corepack ve amb Node.js, de manera que només hem d'utilitzar corepack
per habilitar i utilitzar pnpm. Creem una carpeta per al nostre projecte. A continuació, executem aquestes ordres:
~/project-pnpm$ corepack enable pnpm ~/project-pnpm$ corepack use pnpm@latest Installing [email protected] in the project... Already up to date Done in 494ms
Això genera un fitxer package.json
amb aquest aspecte:
{ "packageManager": "[email protected]+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228" }
Això també genera un fitxer pnpm-lock.yaml
.
A continuació, afegim dependències al nostre projecte. Amb finalitats de demostració, estem copiant la llista de dependencies
i devDependencies
que es troben en aquest fitxer de benchmarking package.json
a GitHub . Ara, el nostre fitxer package.json
té aquest aspecte:
{ "version": "0.0.1", "dependencies": { "animate.less": "^2.2.0", "autoprefixer": "^10.4.17", "babel-core": "^6.26.3", "babel-eslint": "^10.1.0", ... "webpack-split-by-path": "^2.0.0", "whatwg-fetch": "^3.6.20" }, "devDependencies": { "nan-as": "^1.6.1" }, "packageManager": "[email protected]+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228" }
A continuació, instal·lem els paquets.
~/project-pnpm$ pnpm install
L'ús de pnpm és bastant semblant a npm o yarn, i per tant hauria de ser intuïtiu. A continuació es mostra una taula que compara els diferents usos de les ordres habituals (pres d' aquesta publicació ).
Ara que hem mostrat com posar en funcionament un projecte amb pnpm (és bastant senzill, oi?), volíem comparar els temps de creació de diferents gestors de paquets quan s'executen a Heroku. Hem configurat tres projectes amb dependències idèntiques: utilitzant npm, Yarn i pnpm.
Primer, iniciem sessió a la CLI d'Heroku ( heroku login
).
A continuació, creem una aplicació per a un projecte. Mostrarem els passos per al projecte npm.
~/project-npm$ heroku apps:create --stack heroku-24 npm-timing Creating ⬢ npm-timing... done, stack is heroku-24 https://npm-timing-5d4e30a1c656.herokuapp.com/ | https://git.heroku.com/npm-timing.git
Hem trobat un paquet de compilació que afegeix segells de temps als passos de construcció al registre d'Heroku perquè puguem calcular els temps de construcció reals dels nostres projectes. Volem afegir aquest paquet de compilació al nostre projecte i que s'executi abans que el paquet de compilació estàndard per a Node.js. Ho fem amb les dues ordres següents:
~/project-npm$ heroku buildpacks:add \ --index=1 \ https://github.com/edmorley/heroku-buildpack-timestamps.git \ --app pnpm-timing ~/project-npm$ heroku buildpacks:add \ --index=2 heroku/nodejs \ --app npm-timing Buildpack added. Next release on npm-timing will use: 1. https://github.com/edmorley/heroku-buildpack-timestamps.git 2. heroku/nodejs Run git push heroku main to create a new release using these buildpacks.
Això és tot! Aleshores, aixequem el codi del nostre projecte gestionat per npm.
~/project-npm$ git push heroku main ... remote: Updated 4 paths from 5af8e67 remote: Compressing source files... done. remote: Building source: remote: remote: -----> Building on the Heroku-24 stack remote: -----> Using buildpacks: remote: 1. https://github.com/edmorley/heroku-buildpack-timestamps.git remote: 2. heroku/nodejs remote: -----> Timestamp app detected remote: -----> Node.js app detected ... remote: 2024-10-22 22:31:29 -----> Installing dependencies remote: 2024-10-22 22:31:29 Installing node modules remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 added 1435 packages, and audited 1436 packages in 11s remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 184 packages are looking for funding remote: 2024-10-22 22:31:41 run `npm fund` for details remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 96 vulnerabilities (1 low, 38 moderate, 21 high, 36 critical) remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 To address issues that do not require attention, run: remote: 2024-10-22 22:31:41 npm audit fix remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 To address all issues possible (including breaking changes), run: remote: 2024-10-22 22:31:41 npm audit fix --force remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 Some issues need review, and may require choosing remote: 2024-10-22 22:31:41 a different dependency. remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 Run `npm audit` for details. remote: 2024-10-22 22:31:41 npm notice remote: 2024-10-22 22:31:41 npm notice New minor version of npm available! 10.8.2 -> 10.9.0 remote: 2024-10-22 22:31:41 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.0 remote: 2024-10-22 22:31:41 npm notice To update run: npm install -g [email protected] remote: 2024-10-22 22:31:41 npm notice remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 -----> Build remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 -----> Caching build remote: 2024-10-22 22:31:41 - npm cache remote: 2024-10-22 22:31:41 remote: 2024-10-22 22:31:41 -----> Pruning devDependencies remote: 2024-10-22 22:31:44 remote: 2024-10-22 22:31:44 up to date, audited 1435 packages in 4s remote: 2024-10-22 22:31:44 remote: 2024-10-22 22:31:44 184 packages are looking for funding remote: 2024-10-22 22:31:44 run `npm fund` for details remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 96 vulnerabilities (1 low, 38 moderate, 21 high, 36 critical) remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 To address issues that do not require attention, run: remote: 2024-10-22 22:31:45 npm audit fix remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 To address all issues possible (including breaking changes), run: remote: 2024-10-22 22:31:45 npm audit fix --force remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 Some issues need review, and may require choosing remote: 2024-10-22 22:31:45 a different dependency. remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 Run `npm audit` for details. remote: 2024-10-22 22:31:45 npm notice remote: 2024-10-22 22:31:45 npm notice New minor version of npm available! 10.8.2 -> 10.9.0 remote: 2024-10-22 22:31:45 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.0 remote: 2024-10-22 22:31:45 npm notice To update run: npm install -g [email protected] remote: 2024-10-22 22:31:45 npm notice remote: 2024-10-22 22:31:45 remote: 2024-10-22 22:31:45 -----> Build succeeded! ...
Hem analitzat el moment dels passos següents, fins que el missatge Build succeeded
al final:
Installing dependencies
Build
Pruning devDependencies
Caching build
En total, amb npm, aquesta construcció va trigar 16 segons.
Vam executar la mateixa configuració per al projecte gestionat per pnpm, també utilitzant el paquet de creació de temps.
~/project-pnpm$ heroku apps:create --stack heroku-24 pnpm-timing ~/project-pnpm$ heroku buildpacks:add \ --index=1 \ https://github.com/edmorley/heroku-buildpack-timestamps.git \ --app pnpm-timing ~/project-pnpm$ heroku buildpacks:add \ --index=2 heroku/nodejs \ --app pnpm-timing ~/project-pnpm$ git push heroku main … remote: 2024-10-22 22:38:34 -----> Installing dependencies remote: 2024-10-22 22:38:34 Running 'pnpm install' with pnpm-lock.yaml … remote: 2024-10-22 22:38:49 remote: 2024-10-22 22:38:49 dependencies: remote: 2024-10-22 22:38:49 + animate.less 2.2.0 remote: 2024-10-22 22:38:49 + autoprefixer 10.4.20 remote: 2024-10-22 22:38:49 + babel-core 6.26.3 … remote: 2024-10-22 22:38:51 -----> Build succeeded!
Per a la mateixa compilació amb pnpm, només va trigar 7 segons.
Hem trobat que l'estalvi de temps no és només per a la instal·lació inicial. Les compilacions posteriors, que utilitzen la memòria cau de dependències, també són més ràpides amb pnpm.
Quan vaig començar el desenvolupament de Node.js , vaig utilitzar npm. Fa uns quants anys, vaig canviar a Yarn, i això és el que havia estat fent servir. . . fins fa poc. Ara, he fet el canvi a pnpm. A la meva màquina local, puc alliberar una gran quantitat d'espai en disc. Les construccions també són més ràpides. I ara, amb el suport d'Heroku per a pnpm, això tanca el bucle perquè pugui utilitzar-lo exclusivament des del desenvolupament local fins al desplegament al núvol.
Feliç codificació!