Srovnání správců balíčků: Yarn, NPM, PNPM

Yarn, NPM i PNPM jsou tzv. package managers z JavaScriptího světa. NPM mají všichni, kteří si stáhnou Node.js, je tedy nejpoužívanější. Yarn vytvořila Meta. Nejmladší a nejrychlejší je PNPM. Pojďme se na ně podívat detailně.

Výhody a nevýhody NPM (Node Package Manager)

Tím, že je NPM defaultní package manager pro Node.js, má kolem sebe velkou komunitu, jeho použití je jednoduché a většinou bezproblémové. Když už nějaký problém nastane, lze jeho řešení dobře dohledat právě díky komunitě.

Mezi nevýhody patří sekvenční instalace – balíčky se instalují postupně a tím se prodlužuje doba instalace. Další nevýhodou je NPM audit. K němu vznikl zajímavý článek – NPM Audit: Broken by Design. Jde o to, že se vám při instalaci zobrazují kritické chyby, které vás straší, ale ta kritická chyba může spočívat v tom, že případný útočník by musel mít plný přístup k vašemu počítači. Pokud ale takový přístup má, budete mít úplně jiné starosti.

Výhody a nevýhody Yarn

Yarn má stahování vyřešeno paralelně a právě díky tomu je o dost rychlejší. K tomu například nabízí out-of-the-box offline mód, což je fajn, když vám spadne net, a plug-n-play feature, ke které se dostanu.

Tohle asi známe všichni, ale nešlo by to vylepšit? Pojďme se podívat, co se s tím dá udělat.

Využití hoistingu v Yarn

V Yarnu si řekli, že chtějí vyřešit potíže se správou node modules. Balíčky jsou obvykle obrovské a trvá dlouho je kopírovat, mazat atd. Problémem je, že balíček má další závislosti a ty mohou mít zase další závislosti – tím se strom závislostí stává zbytečně hlubokým, a může dojít dokonce k duplikaci stejných verzí balíčků. Aby se tomu Yarn vyhnul, využívá tzv. hoisting (v češtině by se dalo říct „pořadí vyzdvihování“).

Hoisting se snaží posunout společné balíčky ve stromě závislostí co nejvíc nahoru, aby je mohly sdílet i ostatní balíčky. Tím pádem není potřeba tolik stahovat a kopírovat. Má to však i zajímavou nevýhodu – může se stát, že si omylem naimportujete funkci z podbalíčku, který jste neinstalovali, ale nainstalovala si jej vámi používaná knihovna. Moderní IDE by na to však mělo upozornit.

Další možnou nevýhodou je, že hoisting používá semver, a pokud ho některý z balíčků používá špatně, může vzniknout problém. Například označí velkou změnu (major change X.x.x), která rozbíjí zpětnou kompatibilitu, jen jako menší změnu (minor change x.X.x), Yarn (netušící, že by se mohlo něco rozbít) pak stáhne tuto verzi a problém je na světě. Často to zmiňují na Githubu u problémových balíčků.

Yarn Plug'n'Play

Yarn proto přišel s Plug'n'Play (PnP). Funguje to tak, že už nemáme složku node_modules, ale všechno je uloženo do globálního adresáře a v projektu máme pouze .pnp.cjs, který obsahuje odkazy (vysvětlení níže), a PnP loader, který říká, jak je načíst. To nám umožňuje sdílet balíčky mezi několik projektů, a tím pádem je nemusíme dokola stahovat a instalovat. Například pokud máte spoustu projektů v Next.js, nechcete ho znovu stahovat. Plug'n'Play udržuje globálně jednu instalaci.

Implementace Yarn Plug'n'Play používá tzv. symlinks, tedy nativní odkazy na soubory. Jsou dva druhy:

  1. Soft link, ten se při přesunu souboru stane nefunkčním.
  2. Hard link, který naopak udržuje vazbu i po přesunu souboru.

Chtěl bych upozornit na to, že Yarn Plug'n'Play nefunguje na všechny balíčky, což může být zákeřné. Řeknete si: „React Native, to je vlastně hodně velký balíček, používaný, knihovna obrovská, využiju Plug'n'Play“. Tak tohle nefunguje, protože React Native používá svůj vlastní builder Metro, který nedokáže používat symlinky.

Pokud nechcete Plug'n'Play používat, dá se nastavit v konfiguračním souboru mód node-linker, ale přijdete o výše zmíněné výhody, včetně rychlosti.

Výhody a nevýhody PNPM (Performant NPM)

PNPM je nejmladší správce balíčků a měl by být také nejrychlejší. Funguje dost podobně jako Plug'n'Play od Yarnu, taky používá symlinky. Dost cool je, že nestahuje celé balíčky, ale pouze rozdíly mezi verzemi. Takže nemusí stahovat celou knihovnu.

Další pěkná funkce je, že když PNPM použijete, tak vám vypíše do konzole, kolik balíčků přepoužíváte a kolik jste ušetřili na disku, takže když rádi recyklujete, je to fakt super.

PNPM má stejnou nevýhodu jako Plug'n'Play – nemusí podporovat všechny balíčky.

Struktura node_modules u PNPM je dobře čitelná a pěkně udělaná – co balíček, to odkaz (vizte obrázek výše).

Srovnání rychlosti package managerů

Na následujícím grafu je vidět, že NPM je většinou nejpomalejší. Zajímavé je, že ačkoliv Yarn PnP a PNMP používají obdobnou technologii, tak lze sledovat rozdíly v rychlosti.

Zdroj grafu je přímo ze stránky PNPM, takže tam může být jistě nějaký bias. Měření probíhá každý den, přičemž se můžete podívat na aktuální měření i jeho metodiku.

Experimentální featura od Node.js: CorePack

CorePack se zapíná v konzoli a cílí na to, že už nepotřebujete instalovat Yarn ani PNPM. Node.js pozná v package jsonu, který package manager je definován. Je to takové ulehčení, které je zabudované od verze 16.9.0. Jde o experimentální funkci, ale je jednoduché ji spustit. Ještě bych dodal, že s CorePackem je psaní delší. Místo psaní <inline-code>yarn add foo<inline-code> je nutné na začátek připsat <inline-code>corepack yarn add foo<inline-code>. Lze to případně zkrátit aliasy.

Existuje vítěz?

Pojďme si to shrnout. NPM je pomalejší, ale jeho tvůrci se to snaží zlepšovat. Dotahuje se tedy na konkurenci, ale sekvenční stahování je stále problém.

PNPM a Yarn PnP jsou rychlé, ale jejich implementace může občas přinášet problémy. Yarn je podle mě pořád in a zatím jsem při jeho používání nenarazil na žádné větší potíže.

A co vy? Jaký správce balíčků to vyhrál u vás? Dejte mi vědět na tomas.veprek[at]cookielab.io.

Srovnání správců balíčků: Yarn, NPM, PNPM
Tomáš Vepřek
Frontend Developer
By clicking “Accept”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.