Zpět na domů

Nafukování npm závislostí: 3 příčiny a řešení

Článek rozebírá tři příčiny rozrůstání npm závislostí: podpora legacy prostředí, atomární architektura a zastaralé ponyfily. Jsou popsány problémy duplikování, rizika řetězce dodávek a doporučení pro cleanup. Materiál je určen pro middle/senior vývojáře.

Tři příčiny 'nafukování' npm závislostí v JS
Advertisement 728x90

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:

Google AdInline article slot
  • Ochrana globálního prostoru: Node importuje primordials (např. Map), aby se předešlo problémům z přepsání. Balíčky jako math-intrinsics znovu exportují Math.* pro podobný účel.
  • Realm kompatibilita: instanceof nefunguje mezi iframe a rodičem (různé konstruktory RegExp). Alternativa je Object.prototype.toString.call(val) === '[object RegExp]', jako v chai nebo is-string pro new 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:

Google AdInline article slot
  • arrify: Array.isArray(val) ? val : [val]
  • slash: normalizace lomítek v cestách
  • cli-boxes: JSON s hranicemi UI prvků
  • path-key: env['PATH'] || env['Path']
  • onetime: jednorázové volání funkce
  • is-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-regex používá pouze shebang-command (stejný autor); cli-boxes – pouze boxen/ink.
  • Duplikace v hoistingu: V nuxt se 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í.

Google AdInline article slot

Problém: neodstraňují se po nativní podpoře.

Příklady zastaralých ponyfilů (s týdenními stahováními):

  • globalthis – pro globalThis (podpora od 2019, 49M downloads/week)
  • indexof – pro Array.prototype.indexOf (od 2010, 2.3M/week)
  • object.entries – pro Object.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 typeof místo is-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-updates pro analýzu.
  • e18e iniciativa: Zaměření na cleanup zastaralých deps pro výkon.

Praktické kroky k cleanupu

  • Spusťte npm dedupe a npm prune.
  • Přidejte overrides do package.json pro vynucený hoisting.
  • Používejte esbuild/vite s tree-shakingem.
  • Sledujte velikost bundle přes webpack-bundle-analyzer.

To zmenší velikost bundle o 20–50 % bez ztráty funkcionality.

— Editorial Team

Advertisement 728x90

Číst dál