Open borekb opened 3 years ago
Nice article! (I had to read it through Google Translate so pray forgive if I misunderstood something 😄) Two little notes:
Pak ale přišel Yarn 2 a ten udělal jedno ~vysoce kontroverzní~ špatné rozhodnutí: instalační strategii PnP (Plug'n'Play), která existovala už za časů Yarnu 1, udělal jedinou možnou. Z Yarnu se tak dočasně stal JS package manager, který neuměl nainstalovat závislosti do
node_modules
, resp. idea byla, že kdo chce node_modules, má používat Yarn 1 – no zkrátka chyba.
No version of Yarn 2.x shipped without node_modules support. It's been there from the very first stable release. I think some large accounts relayed incorrect information at the start (and we could have highlighted it a bit more, admittedly), but we specifically waited for it to be ready before getting out of beta.
Yarn 2 není veřejně vydanou binárkou, např.
npm i -g yarn
nebobrew install yarn
vždy nainstaluje verzi 1.22, Yarn 2 se pak instaluje jako.cjs
soubor do konkrétního projektu. Na jednu stranu je dobré, že různé části většího monorepa můžou používat svou specifickou verzi Yarnu, a taky je filosoficky pěkné, že package manager je u projektu commitnutý v přesně dané verzi, na druhou stranu my obecně do Gitu binárky necommitujeme, takže nám to vytváří drobné dilema. (Zmínka bokem: y2.)
Node just voted this week to include Corepack in future releases, so there's reasonable hope that the install experience will improve significantly during the next few months!
Děkuji za dobré slova!
What also makes pnpm unique is that it uses a content-addressable store and files are hard-linked from it. So you end up using less disk space for your dependencies. And it probably contributes to faster installation times as well.
@arcanis You're right, I was probably thinking about the pre-release period in 2019 where we were evaluating Yarn 2 (beta) and PnP was the only linker back then. I'll update the blog post, thanks for catching this.
What's your account of why there was a such a strong backlash against Yarn 2 then? Was it only because of the changed defaults? Would be great to know how you remember that...
@zkochan That is a great point, I'll add it to the lists of pnpm advantages. Thanks!
Díky za pěkné shrnutí. U nás dlouhodobě řešíme, na co zmigrovat naše NX monorepo z yarn classic. Největší bolístkou je rychlost (pomalost) předávání node_modules artefaktů v rámci Gitlab CI jobů. V tomhle ohledu zatím jasně vítězí Yarn pnp, jelikož upload/download několika zip souborů je řádově rychlejší (5s vs 1m:20s), než udělat to samé s node_modules složkou. Bohužel se nám zatím v pnp módu nepodařilo dosáhnout funkčního stavu.
@belaczek Většinou se "cachuje cache" neboli (globální) Yarn cache. Dělá to tak i actions/cache, viz zde.
@borekb Jojo, tady jde ale o předávání node_modules atrefaktů mezi jednotlivými joby v CI. GitLab to má tak, že každý job se spouští na čistém podu a je tak potřeba pokažde stáhnout a extrahovat už předtím nainstalované artefakty. A tohle stahování a extrahování docela trvá (alespoň na nešem železe). Alternativou by bylo instalovat node modules v každém jobu zvlášť, ale to by bylo ještě pomalejší.
Yarn vs. npm vs. pnpm
Inspirován zápiskem https://orta.io/notes/js/yarn-vs-npm, rád bych si taky poznamenal, jak se v roce 2021 dívám na situaci kolem JS package managerů.
Úvodem
JavaScript vypadá jako většina C-čkových jazyků, ale na rozdíl od těch klasických (Java / C# / PHP / ...) je hodně o konkrétních objektech namísto globálních jmen. Obecně tak není problém mít v projektu víc věcí jmenujících se stejně, resp. jednu knihovnu ve více verzích:
Ne každý to považuje za dobrou věc, ale já si moc dobře vzpomínám, jak jsme půl roku nemohli updatovat na novější PhpUnit, protože ten začal záviset na novější verzi knihovny X, kterou ještě jiný balíček nestihnul aktualizovat, a ještě horší to je u systémů, které člověk nemá plně pod kontrolou – VersionPress chtěl záviset na knihovnách typu Guzzle nebo Symfony FileSystem, ale nikdy jsme nemohli vědět, jestli výsledný WordPress web nebude používat další pluginy s nekompatibilními verzemi téhož. Zlé...
JavaScript tenhle problém nemá, ale to neznamená, že jsou věci jednoduché.
Věci jsou poměrně jednoduché v moderních prostředích typu ESM v browseru nebo Deno, kde se používají konkrétní importy z konkrétních cest, např.:
Ale převážná realita v Node.js je pořád něco jako:
(Technicky
require
, ale to je detail.)A tam je otázka, co ta "ramda" je. Na odpovědi spolupracují dvě věci:
Jednička je daná, ale pro bod 2 existují různé softwary dělající různé kompromisy. A o nich je tenhle blog post.
npm
npm je klasika. Dlouhé roky jsme s ním žili a vlastně to bylo docela OK. Z dnešního pohledu mi sice připadá šílené, že každé
npm install
mohlo vést k drobně jiné instalacinode_modules
, ale asi naše aplikace byly jednodušší, repozitáře menší atd. 😄Když pak v roce 2016 přišel Yarn, nebylo co řešit – daleko rychlejší, konečně lockfiles, lepší command-line UX, workspaces atd.
npm jsem ale nepřestal sledovat, hlavně kvůli verzi 7, která měla v mnoha ohledech dohnat Yarn. Bohužel se někdy kolem let 2018/19 začalo npm Inc. dostávat do velkých problémů – startupu docházely peníze, řada lidí uvnitř byla toxických, nebyla radost to sledovat a npm si prošlo poměrně temným obdobím. Záchrana nakonec přišla ze strany GitHubu / Microsoftu – bylo to o fous, ale vlastně to líp dopadnout nemohlo.
Co se mi na npm líbí:
Co se mi na npm nelíbí:
npm run <script>
místonpm <script>
, nutnost tam někdy dávat--
, já vlastně ani nevím, jestli jenpm install
ten správný příkaz nebo by to mělo býtnpm ci
, zkrátka řada drobností v použitelnosti. Ale s tím se dá žít.node_modules
instalaci, která má problémy typu doppelgangers nebo phantom dependencies (oba výborné články z dokumentace Rush.js) nebo nutnost dělat kompromisy kolem hoistování (viz např. změna layoutunode_modules
mezi verzemi 2 a 3). Větší projekty toto začne dřív nebo později trápit a npm na to nemá odpověď.peerDependencies
– kontroverzní rozhodnutí, a npm by podle mě nemělo jít proti jedné ze svých největších výhod.Celkově bych si npm 7 asi už celkem v pohodě vybral na jednodušší JS projekt, možná to je i nejlepší volba. U složitějšího projektu (např. company monorepo) jsou ale limity
node_modules
podstatné a nějaká alternativa je skoro "nutností".Yarn
Yarn má za sebou dvě životní etapy:
Yarn 1 byl miláček – používali ho "všichni" a dal JS světu mnoho dobrého – reproducible installs, rychlost, workspaces atd.
Yarn 2 ("Berry") vykročil tak trochu za hranice běžného package manageru – vedle instalace balíčků se snaží pomoct s DX v monorepu, s release workflows, ale taky má některé silné názory na to, jak by měl spolehlivý vývoj vypadat obecně – PnP, Zero-Installs atd.
Asi největší kontroverze je právě kolem PnP (Plug'n'Play) – tato instalační strategie existovala už za časů Yarnu 1 (a nikomu nevadila, protože byla volitelná a "schovaná"), ale Yarn 2 se rozhodl z ní udělat default. To byla za mě chyba, dejte si třeba tvíty z ledna 2020 nebo https://github.com/yarnpkg/berry/issues/766. Pořád to neutichlo, tohle je čerstvý příklad:
Je to škoda, protože Yarn 2 lze během dvou minut nakonfigurat tak, aby fungoval "postaru", ale nechme historie a pojďme k technickým věcem.
Co se mi na Yarnu líbí:
node_modules
pro lokální vývoj (lepší DX), ale na CIčku už je PnP (odhalí např. chybějící dependencies / peerDependencies), stejně tak pro Docker buildy. Obecně mít víc možností oceňujeme.plugin-typescript
automaticky doinstaluje odpovídající@types
, yarn.BUILD je hezký, minimalistický build systém, atd.Co se mi na Yarnu nelíbí:
npm i -g yarn
nebobrew install yarn
vždy nainstaluje verzi 1.22, Yarn 2 se pak instaluje jako.cjs
soubor do konkrétního projektu. Na jednu stranu je dobré, že různé části většího monorepa můžou používat svou specifickou verzi Yarnu, a taky je filosoficky pěkné, že package manager je u projektu commitnutý v přesně dané verzi, na druhou stranu my obecně do Gitu binárky necommitujeme, takže nám to vytváří drobné dilema. (Zmínka bokem: y2.)Celkově je Yarn pokročilý package manager, který i z velké části dokáže nahradit Lernu, build tool, monorepo managera atd. (což je za mě super, např. Lerna mě svého času vyloženě štvala; čím míň softwaru, tím líp). Hodí se nám dvě různé instalační strategie, různé stupně striktnosti, občas si do Yarnu napíšeme vlastní plugin, zkrátka pokročilý parťák.
pnpm
S pnpm nemáme moc reálných zkušeností, ale už dlouho po něm pokukujeme, protože jeho instalační strategie vypadá naprosto skvěle (zdroj):
Trochu to připomíná PnP, ale zůstává u prostých složek namísto ZIP souborů, což je v mnoha ohledech praktičtější.
Zde se nehodlám pustit do většího hodnocení, protože mi chybí zkušenosti, ale určité dojmy jsou:
<store>
v příkladu výše) a hardlinky na něj, což znamená, že daný balíček v konkrétní verzi je na disku pouze jednou. pnpm tak nevytváří černé díry.pnpm dále sledujeme, nebo by mi vlastně stačilo, kdyby se pnpm instalační strategie dostala do Yarnu jako plugin (https://github.com/yarnpkg/berry/issues/1845) 😎.
Asi se mi úplně nepovedlo udělat si pár krátkých poznámek 😄.
Package manager je pro nás super-důležitou věcí – už třeba instalace devDependencies v repo rootu do běžných node_modules není ve větším repu moc dobrý nápad, a vůbec s rostoucí komplexitou / množstvím balíčků je PM čím dál důležitější.
Já momentálně za "nejlepší" package manager považuju Yarn, ale vybrat si není jednoduché – tolik různých možností, tolik nuancí...
Opravy: