Proč se stromy závislostí npm nafukují: tři klíčové důvody
Stromy závislostí v JavaScriptových projektech často narůstají kvůli zastaralým balíčkům a duplikaci nativních funkcí platformy. To vede k zbytečným nákladům na stahování, řešení verzí a zranitelnostem v dodavatelském řetězci. Podívejme se na tři typické scénáře, které tuto situaci vysvětlují, a způsoby, jak je řešit.
Podpora legacy prostředí a realm specifikace
Mnoho balíčků jako is-string nebo hasown existuje pro kompatibilitu se starými runtime, jako je ES3 (IE6/7, raný Node.js). Implementují chybějící metody: Array.prototype.forEach, Array.prototype.reduce, Object.keys, Object.defineProperty.
Další motivace:
- Ochrana globálního prostoru: Node importuje primordials (např.
Map), aby se předešlo problémům z přepsání. Balíčky jakomath-intrinsicsznovu exportujíMath.*pro podobný účel. - Realm kompatibilita:
instanceofnefunguje mezi iframe a rodičem (různé konstruktoryRegExp). Alternativa jeObject.prototype.toString.call(val) === '[object RegExp]', jako vchainebois-stringpronew String(val).
const shebangRegex = /^#!(.*)/;
export default shebangRegex;
Pro většinu middle/senior vývojářů je to zbytečné: moderní Node (ne starší než 10 let) a prohlížeče takové hacky nevyžadují. Doporučení: zkontrolujte browserslist a odstraňte nepotřebné polyfily.
Atomární architektura: od teorie k problémům
Filozofie 'atomárních' balíčků předpokládá rozdělení na minimální bloky pro opakované použití. Příklad – graf závislostí execa s balíčky jako shebang-regex (5 řádků kódu).
Typické atomární utility:
arrify:Array.isArray(val) ? val : [val]slash: normalizace lomítek v cestáchcli-boxes: JSON s hranicemi UI prvkůpath-key:env['PATH'] || env['Path']onetime: jednorázové volání funkceis-wsl:process.platform === 'linux' && /microsoft/.test(os.release())is-windows:process.platform === 'win32'
V teorii to zjednodušuje sestavování CLI. V praxi:
- Jednorázovost:
shebang-regexpoužívá pouzeshebang-command(stejný autor);cli-boxes– pouzeboxen/ink. - Duplikace v hoistingu: V
nuxtse duplikujíis-docker,is-stream,is-wsl(po 2 verzích). Vestavěný kód se duplikuje zdarma, bez npm režie. - Rizika dodavatelského řetězci: Více balíčků – více zranitelností. Kompromitace jednoho maintainera (jako loni) ovlivnila stovky závislostí.
Řešení: inlining jednoduchých funkcí, tree-shaking, pnpm s strict hoistingem.
Ponyfily, které přežily svou dobu
Ponyfily (ponyfill) – polyfily bez mutace globálů, importované přímo. Užitečné pro knihovny: @fastly/performance-observer-polyfill umožňuje používat PerformanceObserver bez změny prostředí.
Problém: neodstraňují se po nativní podpoře.
Příklady zastaralých ponyfilů (s týdenními stahováními):
globalthis– proglobalThis(podpora od 2019, 49M downloads/week)indexof– proArray.prototype.indexOf(od 2010, 2.3M/week)object.entries– proObject.entries(od 2017, 35M/week)
V eslint-plugin-react je polovina grafu – legacy polyfily. Pro knihovny: spoléhejte na consumer-side polyfily (core-js). Před přidáním zkontrolujte caniuse.com.
Co je důležité
- Optimalizace legacy: 90 % balíčků nepotřebuje ES3/ES5 polyfily; používejte
typeofmístois-string. - Atomárnost škodí: Vkládejte 5-řádkové funkce, snižte duplikace a útočnou plochu.
- Audit ponyfilů: Odstraňujte balíčky pro funkce podporované >5 let v cílovém runtime.
- Nástroje:
npm ls --depth=0,depcheck,npm-check-updatespro analýzu. - e18e iniciativa: Zaměření na cleanup zastaralých deps pro výkon.
Praktické kroky k cleanupu
- Spusťte
npm dedupeanpm prune. - Přidejte
overridesdopackage.jsonpro vynucený hoisting. - Používejte
esbuild/vites tree-shakingem. - Sledujte velikost bundle přes
webpack-bundle-analyzer.
To zmenší velikost bundle o 20–50 % bez ztráty funkcionality.
— Editorial Team
Zatím žádné komentáře.