Jak uspořádat složku JavaScriptu pro větší projekty

Javascript

Co je složka souborů JavaScriptu

Složka souborů JavaScriptu je v podstatě adresář, který obsahuje jeden nebo více souborů napsaných v programovacím jazyce JavaScript. Tyto soubory mají zpravidla příponu .js, případně novější příponu .mjs pro moduly, a dohromady tvoří základ jakékoliv webové aplikace nebo projektu, který využívá JavaScript jako svůj primární programovací jazyk. Bez dobré organizace těchto souborů by byl jakýkoliv větší projekt prakticky nespravovatelný.

Když vývojář začíná pracovat na novém projektu, jednou z prvních věcí, které musí vyřešit, je právě struktura složek a souborů. Tato struktura totiž přímo ovlivňuje, jak snadno se bude v projektu orientovat, jak jednoduše bude možné přidávat nové funkce a jak efektivně bude celý tým schopen spolupracovat. Složka JavaScriptových souborů tedy není jen technická záležitost, ale i organizační a týmová.

V praxi se velmi často setkáváme s tím, že projekty mají více různých složek pro různé typy JavaScriptových souborů. Například složka components může obsahovat soubory pro jednotlivé komponenty uživatelského rozhraní, zatímco složka utils nebo helpers sdružuje pomocné funkce a nástroje, které jsou využívány napříč celou aplikací. Složka services pak typicky obsahuje soubory, které se starají o komunikaci s externími API nebo backendem. Toto rozdělení není náhodné a vychází z dlouholeté praxe vývojářů po celém světě.

Správná organizace JavaScriptových souborů je klíčová zejména u větších projektů, kde se počet souborů může pohybovat ve stovkách nebo dokonce tisících. V takovém případě je naprosto nezbytné mít jasně definovanou hierarchii složek, aby se předešlo chaosu a zbytečnému zdvojování kódu. Moderní vývojové prostředí a nástroje jako například Webpack, Vite nebo Parcel pak tyto složky zpracovávají a výsledný kód optimalizují pro nasazení do produkčního prostředí.

Důležitým aspektem práce se složkami JavaScriptových souborů je také správa závislostí. Soubory v jedné složce mohou importovat funkce nebo třídy ze souborů v jiné složce, a proto je nutné mít přesný přehled o tom, jak jsou jednotlivé části projektu propojeny. Špatně navržená struktura složek může vést k tzv. kruhovým závislostem, které způsobují chyby při spouštění aplikace a jsou velmi obtížně detekovatelné.

V kontextu moderního vývoje webových aplikací se také stále více prosazuje přístup, kdy jsou JavaScriptové soubory organizovány podle funkčních celků nebo tzv. feature-based struktury. To znamená, že veškeré soubory relacionované s konkrétní funkcionalitou jsou umístěny do jedné složky, bez ohledu na to, zda jde o komponenty, styly nebo testovací soubory. Tento přístup výrazně zjednodušuje orientaci v projektu a usnadňuje práci vývojářům, kteří se s projektem teprve seznamují.

Nelze také opomenout roli souborů jako index.js, které se v JavaScriptových složkách vyskytují velmi často. Tyto soubory slouží jako vstupní bod pro danou složku a umožňují ostatním částem aplikace importovat obsah složky bez nutnosti znát přesnou cestu ke každému jednotlivému souboru. Tím se výrazně zjednodušuje správa importů a celkový kód se stává přehlednějším a čitelnějším.

Celkově lze říci, že složka souborů JavaScriptu je mnohem více než jen technický kontejner pro kód. Je to odraz myšlení vývojáře, jeho přístupu k organizaci práce a schopnosti předvídat budoucí potřeby projektu. Dobře navržená struktura složek šetří čas, snižuje počet chyb a přispívá k dlouhodobé udržitelnosti celého softwarového projektu.

Typická struktura adresáře JavaScriptového projektu

Každý JavaScriptový projekt, ať už jde o jednoduchou webovou stránku nebo rozsáhlou aplikaci, má svou vlastní organizaci souborů a adresářů. Tato organizace není náhodná – vznikla postupem času jako výsledek zkušeností tisíců vývojářů, kteří hledali způsob, jak udržet svůj kód přehledný, snadno udržovatelný a srozumitelný pro ostatní členy týmu.

Základem každého projektu je takzvaný kořenový adresář, anglicky označovaný jako „root directory. Právě zde se nachází srdce celého projektu. V kořenovém adresáři najdeme soubor package.json, který je naprosto klíčový pro každý moderní JavaScriptový projekt. Tento soubor obsahuje metadata projektu, seznam závislostí, skripty pro spuštění nebo sestavení aplikace a mnoho dalšího. Bez tohoto souboru by správce balíčků npm nebo yarn nedokázal správně fungovat a projekt by bylo velmi obtížné sdílet s ostatními vývojáři.

Dalším důležitým souborem v kořenovém adresáři bývá soubor .gitignore, který říká systému pro správu verzí Git, které soubory a adresáře má ignorovat. Typicky se jedná o adresář node_modules, který může obsahovat stovky megabajtů kódu třetích stran a rozhodně nemá co dělat v repozitáři. Tento adresář vzniká automaticky po spuštění příkazu npm install nebo yarn install a obsahuje veškeré závislosti projektu.

Samotný zdrojový kód projektu se zpravidla nachází v adresáři pojmenovaném src, což je zkratka anglického slova „source, tedy zdroj. Uvnitř tohoto adresáře se pak dále větví struktura podle povahy projektu. U frontendových aplikací postavených na frameworcích jako React, Vue nebo Angular bývá zvykem mít složky pojmenované components, pages, hooks, utils nebo services. Každá z těchto složek plní specifickou roli. Ve složce components se nacházejí znovupoužitelné komponenty uživatelského rozhraní, ve složce pages pak jednotlivé stránky nebo pohledy aplikace.

javascript

Složka utils, zkratka od „utilities, obsahuje pomocné funkce, které se používají napříč celou aplikací. Mohou to být funkce pro formátování dat, práci s řetězci nebo různé matematické výpočty. Tyto funkce jsou záměrně odděleny od ostatního kódu, protože jsou obecné povahy a nemají přímou vazbu na konkrétní část aplikace.

Velmi důležitou součástí moderního JavaScriptového projektu je také složka public nebo static. Zde se nacházejí statické soubory, jako jsou obrázky, fonty, ikony nebo soubor index.html, který slouží jako vstupní bod webové aplikace. Tyto soubory jsou servírovány přímo bez jakékoliv transformace nebo kompilace.

Pro testování kódu existuje samostatná složka, nejčastěji pojmenovaná tests nebo __tests__. V ní jsou uloženy testovací soubory, které ověřují správnost fungování jednotlivých částí aplikace. Testovací soubory mívají příponu .test.js nebo .spec.js a jsou organizovány tak, aby jejich struktura zrcadlila strukturu zdrojového kódu.

Konfigurační soubory tvoří další neodmyslitelnou část projektu. Soubory jako .babelrc, webpack.config.js, eslint.config.js nebo jest.config.js se nacházejí buď přímo v kořenovém adresáři, nebo ve speciální složce config. Tyto soubory definují, jak má být projekt sestavován, jaká pravidla pro psaní kódu mají být dodržována nebo jak mají být spouštěny testy.

Dokumentace projektu bývá umístěna ve složce docs. Přestože mnoho vývojářů dokumentaci podceňuje, jedná se o velmi důležitou součást každého projektu, zejména pokud na něm pracuje více lidí nebo pokud je určen pro veřejné použití. Dobře napsaná dokumentace může ušetřit hodiny zbytečného hledání a dohadování.

Celkově lze říci, že správná organizace adresářové struktury JavaScriptového projektu je základem pro jeho dlouhodobou udržitelnost a rozvoj. Vývojáři, kteří věnují čas promyšlení struktury na začátku projektu, se vyhnou mnoha problémům v budoucnosti. Přehledná struktura usnadňuje onboarding nových členů týmu, zjednodušuje ladění chyb a přispívá k celkové kvalitě výsledného produktu.

JavaScript složka je jako dobře organizovaná knihovna – každý soubor má své místo, svůj účel a svůj příběh. Když procházíš adresáře plné kódu, nacházíš nejen funkce a proměnné, ale také myšlenky programátorů, kteří před tebou budovali základy, na nichž dnes stavíš. Udržovat pořádek ve složkách JavaScriptu znamená udržovat pořádek ve vlastní mysli.

Radovan Sklenář

Hlavní typy souborů uvnitř složky

Když se podíváme do typické složky JavaScriptového projektu, setkáme se s celou řadou různých typů souborů, které dohromady tvoří funkční celek. Každý z těchto souborů má svůj specifický účel a bez pochopení jejich role je orientace v projektu přinejmenším obtížná. Nejdůležitějším typem jsou samozřejmě samotné soubory s příponou .js, tedy soubory obsahující čistý JavaScript kód. Právě v nich se nachází veškerá logika aplikace, funkce, třídy, objekty a vše, co dává programu jeho skutečnou funkčnost. Tyto soubory mohou být organizovány do různých podsložek podle toho, jakou část aplikace obsluhují — například složka `components` obsahuje znovupoužitelné části uživatelského rozhraní, zatímco složka `utils` sdružuje pomocné funkce.

V moderních projektech se stále častěji setkáváme také se soubory s příponou .jsx, které jsou typické pro projekty využívající knihovnu React. Tyto soubory kombinují JavaScript s HTML-like syntaxí, která se nazývá JSX, a umožňují vývojářům psát strukturu uživatelského rozhraní přímo uvnitř JavaScriptového kódu. Podobně fungují soubory s příponou .ts a .tsx, které patří do světa TypeScriptu — nadmnožiny JavaScriptu, jež přidává statické typování. Tyto soubory se před spuštěním překládají do čistého JavaScriptu, ale vývojářům poskytují mnohem silnější nástroje pro odhalování chyb již při psaní kódu.

Neméně důležitou roli hrají konfigurační soubory, které se nacházejí zpravidla v kořenové složce projektu. Soubor package.json je absolutním základem každého Node.js nebo JavaScriptového projektu — obsahuje metadata o projektu, seznam závislostí, skripty pro spouštění, testování nebo sestavování aplikace a mnoho dalšího. Bez tohoto souboru by správce balíčků npm nebo yarn vůbec nevěděl, jak s projektem pracovat. Vedle něj existuje soubor `package-lock.json` nebo `yarn.lock`, který zaznamenává přesné verze všech nainstalovaných závislostí a zajišťuje, že projekt bude fungovat stejně na každém počítači, kde bude nainstalován.

Dalším běžným typem souboru je .env, tedy soubor pro ukládání proměnných prostředí. Zde se uchovávají citlivé informace jako jsou API klíče, databázová hesla nebo adresy serverů — informace, které by rozhodně neměly skončit ve veřejném repozitáři. Proto se soubor `.env` téměř vždy přidává do souboru .gitignore, který říká systému správy verzí Git, které soubory a složky má ignorovat a nezahrnovat do sledování změn.

javascript

Velmi důležitou součástí moderních JavaScript projektů jsou také konfigurační soubory pro různé nástroje. Soubor `webpack.config.js` nebo `vite.config.js` definuje, jak má být projekt sestaven a optimalizován pro produkční nasazení. Soubor `.babelrc` nebo `babel.config.js` konfiguruje překladač Babel, který umožňuje používat moderní syntaxi JavaScriptu i v prostředích, která ji ještě nativně nepodporují. Soubor `.eslintrc` nebo `eslint.config.js` nastavuje pravidla pro ESLint, nástroj, který kontroluje kvalitu kódu a upozorňuje na potenciální chyby nebo nedodržení konvencí.

Testovací soubory tvoří další důležitou kategorii. Tyto soubory mají zpravidla příponu .test.js nebo .spec.js a obsahují automatizované testy, které ověřují správnost fungování kódu. Jsou obvykle umístěny buď vedle testovaných souborů, nebo ve zvláštní složce nazvané `__tests__` nebo `tests`. Dobře napsané testy jsou zárukou toho, že změny v kódu nezpůsobí neočekávané problémy v jiných částech aplikace.

Nesmíme zapomenout ani na soubory stylů, které sice nejsou JavaScriptem v pravém slova smyslu, ale v moderních projektech jsou s ním úzce provázány. Soubory s příponou `.css`, `.scss` nebo `.less` definují vizuální podobu aplikace a v projektech využívajících nástroje jako webpack nebo Vite jsou importovány přímo z JavaScriptových souborů. Existují také takzvané CSS moduly, kde každý soubor stylů patří konkrétní komponentě a jeho třídy jsou automaticky unikátní, čímž se předchází konfliktům názvů.

Soubory README.md a další soubory s příponou `.md` jsou psány v jazyce Markdown a slouží jako dokumentace projektu. Popisují, k čemu projekt slouží, jak ho nainstalovat, jak ho spustit a jak do něj přispívat. I když nejde o kód v pravém slova smyslu, jejich přítomnost výrazně zvyšuje srozumitelnost a použitelnost celého projektu pro ostatní vývojáře.

Rozdíl mezi modulárním a monolitickým uspořádáním kódu

Když se podíváme na způsob, jakým vývojáři organizují svůj JavaScript kód, narazíme na dva zásadně odlišné přístupy, které ovlivňují nejen přehlednost projektu, ale také jeho dlouhodobou udržitelnost a škálovatelnost. Každý, kdo někdy pracoval na větším projektu, ví, jak rychle se může zdánlivě jednoduchý kód proměnit v nepřehlednou změť funkcí a proměnných, pokud není od začátku správně strukturován.

Monolitické uspořádání kódu představuje přístup, při němž je veškerá logika aplikace soustředěna do jednoho nebo několika málo souborů. V praxi to znamená, že vývojář píše veškerý JavaScript do jediného souboru, který může postupem času narůstat na stovky, ba tisíce řádků. Tento přístup byl v minulosti velmi rozšířený, zejména v době, kdy webové stránky nebyly tak komplexní jako dnes. Soubor s názvem app.js nebo main.js obsahoval úplně vše – od obsluhy událostí přes manipulaci s DOM až po volání API a správu stavu aplikace. Na první pohled se může zdát, že mít vše na jednom místě je pohodlné, ale realita je poněkud jiná.

Problém s monolitickým přístupem se projeví nejpozději ve chvíli, kdy na projektu začne pracovat více lidí nebo kdy se aplikace rozroste natolik, že orientace v kódu začne být skutečnou noční můrou. Hledání konkrétní funkce v souboru o třech tisících řádcích je časově náročné a frustrující. Navíc jakákoliv úprava jedné části kódu může nechtěně ovlivnit jinou část, protože vše je propojeno v jednom celku bez jasně definovaných hranic.

Modulární uspořádání kódu přichází s diametrálně odlišnou filozofií. Místo jednoho obřího souboru je kód rozdělen do mnoha menších, logicky oddělených souborů a složek, přičemž každý soubor má jasně definovanou odpovědnost. Složka nebo adresář souborů kódu napsaných v jazyce JavaScript pak tvoří organizovanou strukturu, kde například složka components obsahuje jednotlivé komponenty uživatelského rozhraní, složka utils sdružuje pomocné funkce, složka services zapouzdřuje komunikaci s externími API a složka models definuje datové struktury.

Tento přístup je úzce spojen se systémem modulů, který JavaScript podporuje prostřednictvím klíčových slov import a export. Každý soubor může exportovat funkce, třídy nebo proměnné, které jsou pak dostupné v jiných souborech projektu. Tím vzniká jasná hierarchie závislostí a každý modul lze vyvíjet, testovat a udržovat zcela nezávisle na ostatních částech aplikace.

Jednou z největších výhod modulárního přístupu je znovupoužitelnost kódu. Pokud napíšete funkci pro formátování data v samostatném souboru, můžete ji snadno importovat kdekoliv v projektu, aniž byste ji museli kopírovat nebo přepisovat. Princip DRY – Don't Repeat Yourself – je v modulárním prostředí přirozeně dodržován. Oproti tomu v monolitickém souboru se velmi snadno stane, že podobná logika existuje na více místech v mírně odlišných variantách, což vede k nekonzistencím a zbytečnému technickému dluhu.

Dalším důležitým aspektem je testování. Modulární kód je výrazně snáze testovatelný, protože jednotlivé moduly mají jasně definované vstupy a výstupy. Napsat unit test pro izolovanou funkci je podstatně jednodušší než testovat logiku zakopanou hluboko v monolitickém souboru, kde je vše navzájem provázané a kde izolace konkrétní funkcionality vyžaduje složité mockovací techniky.

javascript

Z hlediska výkonu aplikace hraje roli také možnost lazy loadingu, tedy líného načítání. Moderní nástroje jako Webpack nebo Vite umí při modulárním uspořádání kódu rozdělit výsledný bundle do menších částí, které se načítají pouze tehdy, když jsou skutečně potřeba. To má přímý dopad na rychlost načítání stránky a celkový uživatelský zážitek. Monolitický přístup tuto optimalizaci prakticky neumožňuje, protože veškerý kód je sloučen dohromady.

Přechod z monolitického na modulární uspořádání není vždy jednoduchý, zejména u starších projektů, kde byl kód psán bez ohledu na budoucí strukturu. Refaktoring takového kódu vyžaduje pečlivé plánování a postupné oddělování jednotlivých odpovědností do samostatných souborů. Přesto se tato investice téměř vždy vyplatí, protože výsledkem je kód, který je přehledný, snadno rozšiřitelný a radost v něm pracovat.

Jak správně pojmenovávat soubory a složky

Pojmenování souborů a složek v JavaScriptovém projektu je téma, které se na první pohled může zdát jako drobnost, ale ve skutečnosti má zásadní vliv na čitelnost kódu, spolupráci v týmu a celkovou udržitelnost projektu. Každý vývojář, který někdy pracoval na větším projektu, ví, jak rychle se může stát adresářová struktura nepřehlednou, pokud se od začátku nedodržují jasná pravidla.

Jedním z nejrozšířenějších přístupů v JavaScriptovém světě je používání takzvaného kebab-case, tedy zápisu, kde jsou slova oddělena pomlčkami. Soubor pojmenovaný například `user-profile.js` nebo `shopping-cart.js` je okamžitě čitelný a nevznikají žádné problémy s operačními systémy, které rozlišují velikost písmen. Linux a macOS totiž považují `UserProfile.js` a `userProfile.js` za dva různé soubory, zatímco Windows je považuje za totožné. Tato nekonzistence může způsobit velmi zákeřné chyby, které se projeví až při nasazení aplikace na produkční server.

Další oblíbenou konvencí, zejména v prostředí Reactu, je PascalCase pro pojmenování komponent. Soubor obsahující React komponentu se tedy nejčastěji jmenuje `UserProfile.jsx` nebo `ShoppingCart.tsx`. Tato konvence má svůj logický základ — v Reactu se komponenty píší s velkým počátečním písmenem, takže název souboru přímo odpovídá názvu exportované třídy nebo funkce. Konzistence mezi názvem souboru a jeho obsahem výrazně usnadňuje orientaci v projektu.

Pokud jde o pojmenování složek, doporučuje se používat výhradně malá písmena a pomlčky, případně samotná malá písmena bez jakýchkoli speciálních znaků. Složka pojmenovaná `components`, `utils`, `hooks` nebo `api-services` je přehledná a nevyvolává žádné otázky. Naopak složky jako `MyComponents`, `UTILS` nebo `Api_Services` působí nekonzistentně a mohou způsobovat zmatek, zvláště když do projektu přichází nový vývojář.

Velmi důležitým pravidlem je vyhýbat se mezerám v názvech souborů a složek. Mezery v názvech souborů jsou zdrojem nekonečných problémů při práci s příkazovou řádkou, v importech a v různých nástrojích pro správu závislostí. Soubor pojmenovaný `user profile.js` bude způsobovat potíže prakticky všude, zatímco `user-profile.js` funguje bez problémů v každém prostředí.

Speciální pozornost si zaslouží také pojmenování indexových souborů. V JavaScriptových projektech je běžnou praxí vytvářet v každé složce soubor `index.js`, který slouží jako vstupní bod dané části aplikace. Tato technika umožňuje importovat obsah složky bez nutnosti uvádět konkrétní název souboru — stačí napsat cestu ke složce a JavaScript automaticky hledá `index.js`. Je to elegantní řešení, ale vyžaduje disciplínu, protože pokud má každá složka soubor `index.js`, může být při ladění obtížné rychle identifikovat, ve které složce se právě nacházíte.

Dalším aspektem, který bývá podceňován, je konzistentní používání přípon souborů. V moderním JavaScriptovém ekosystému se setkáme s příponami `.js`, `.jsx`, `.ts`, `.tsx`, `.mjs` nebo `.cjs`. Každá z nich nese specifický význam a jejich promíchávání bez jasného systému vede k chaosu. Soubory s příponou `.jsx` by měly obsahovat JSX syntaxi, soubory `.ts` jsou psány v TypeScriptu a soubory `.mjs` explicitně deklarují použití ES modulů. Dodržování těchto konvencí není jen otázkou estetiky, ale má přímý dopad na to, jak nástroje jako webpack, Vite nebo esbuild soubory zpracovávají.

Nesmíme zapomenout ani na pojmenování testovacích souborů. Nejčastěji se používá konvence, kdy testovací soubor nese stejný název jako testovaný soubor, ale s příponou `.test.js` nebo `.spec.js`. Soubor `user-profile.test.js` tedy obsahuje testy pro `user-profile.js`. Tato konvence je natolik rozšířená, že ji automaticky rozpoznávají testovací frameworky jako Jest nebo Vitest, a není tedy nutné jejich konfiguraci nijak složitě upravovat.

Celková konzistence napříč celým projektem je důležitější než volba konkrétní konvence. Ať už se váš tým rozhodne pro kebab-case, camelCase nebo PascalCase, klíčové je, aby se zvolená konvence dodržovala důsledně a aby byla zdokumentována například v souboru `CONTRIBUTING.md` nebo v interní dokumentaci projektu. Nový člen týmu by měl být schopen pochopit strukturu projektu a pojmenovávací konvence během několika minut, nikoli hodin.

javascript

Organizace složek v moderních frameworcích jako React

Každý, kdo někdy pracoval na větším projektu v Reactu, dobře ví, jak rychle se může adresářová struktura změnit z přehledného systému v nepřehledný chaos. Zpočátku to vypadá jednoduše – pár komponent, jeden soubor se styly, možná nějaký helper. Jenže jak projekt roste, přibývají soubory, závislosti se komplikují a najednou se člověk ocitá v situaci, kdy neví, kde co hledat.

Organizace složek v Reactu není žádné dogma, ale existují osvědčené přístupy, které výrazně usnadňují práci celému týmu. Jedním z nejrozšířenějších je takzvaná organizace podle funkcionality nebo domény. Místo toho, aby byly všechny komponenty pohromadě v jedné obří složce `components`, rozdělí se projekt do logických celků. Například složka `user` obsahuje vše, co se týká uživatele – jeho komponentu, hook, typy, testy i styly. Složka `dashboard` obsahuje vše potřebné pro dashboard. Tento přístup se nazývá feature-based structure a v praxi se ukazuje jako velmi efektivní, zejména u větších aplikací.

Naopak u menších projektů nebo prototypů může být jednodušší klasické rozdělení podle typu souboru. V takovém případě existuje složka `components`, složka `hooks`, složka `utils`, složka `services` a tak dále. Tento přístup je intuitivní a rychlý na pochopení, ale při větším počtu souborů se stává nepřehledným. Hledání konkrétní komponenty a jejích závislostí pak vyžaduje přeskakování mezi různými složkami, což zdržuje a frustruje.

Klíčovým prvkem dobré adresářové struktury je konzistence. Nezáleží tolik na tom, který přístup si tým zvolí, ale na tom, aby se ho důsledně držel. Pokud se komponenty pojmenovávají PascalCase a každá má svůj vlastní adresář s `index.tsx`, `styles.module.css` a `Component.test.tsx`, pak by to tak mělo být vždy a všude. Jakékoliv odchylky od zavedeného vzoru způsobují zmatek a zvyšují kognitivní zátěž při práci s kódem.

V ekosystému Reactu se také velmi osvědčila praxe takzvaných barrel exportů. Každá složka obsahuje soubor `index.js` nebo `index.ts`, který exportuje vše, co je z dané složky veřejně dostupné. Díky tomu lze importovat komponenty jednoduše jako `import { Button } from './components'` místo zdlouhavého `import Button from './components/Button/Button'`. Tato technika výrazně zjednodušuje importy a zároveň umožňuje skrýt interní implementaci.

Frameworky jako Next.js přinášejí vlastní konvence pro strukturu projektu. Složka `pages` nebo v novějších verzích `app` definuje routování aplikace přímo svou strukturou. Každý soubor v této složce odpovídá konkrétní URL adrese. To sice přináší jasnou logiku routování, ale zároveň to klade nároky na správné oddělení logiky stránek od sdílených komponent. Mnoho zkušených vývojářů proto doporučuje udržovat složku `app` co nejčistší a veškerou složitější logiku přesouvat do separátních modulů.

Zvláštní pozornost si zaslouží organizace sdílených komponent a utilit. Složka `shared` nebo `common` by měla obsahovat pouze skutečně sdílené věci – tedy takové, které jsou využívány napříč celou aplikací. Pokud je komponenta využívána pouze v jedné konkrétní feature, nepatří do sdílené složky, ale přímo do té feature. Toto pravidlo pomáhá předcházet situaci, kdy se sdílená složka stane odpadkovým košem pro vše, co vývojář nevěděl, kam jinam zařadit.

Testovací soubory by měly být co nejblíže testovanému kódu. Praxe ukládání testů do separátní složky `__tests__` na vrcholu projektu sice funguje, ale přináší zbytečné komplikace při refaktoringu. Když se přesune nebo přejmenuje komponenta, musí se pamatovat na aktualizaci testů na jiném místě. Naopak umístění testovacího souboru přímo vedle testované komponenty tuto vazbu zpřehledňuje a snižuje riziko, že testy zůstanou pozadu za změnami v kódu.

Moderní JavaScript a TypeScript projekty také stále více využívají absolutní importy namísto relativních. Konfigurace `tsconfig.json` nebo `jsconfig.json` umožňuje nastavit aliasy, takže místo `../../../components/Button` stačí napsat `@components/Button`. Tato zdánlivě drobnost výrazně zlepšuje čitelnost kódu a usnadňuje přesouvání souborů v rámci projektu.

Na závěr je důležité zdůraznit, že nejlepší adresářová struktura je ta, která odpovídá potřebám konkrétního projektu a týmu. Slepé kopírování vzorů z internetu bez pochopení jejich účelu vede k problémům. Struktura by měla vyrůstat organicky spolu s projektem, přičemž pravidelný refaktoring adresářové struktury je stejně důležitý jako refaktoring samotného kódu.

Správa závislostí pomocí souboru package.json

Každý projekt v JavaScriptu, který přesáhne hranice jednoduchého skriptu o pár řádcích, se dříve nebo později nevyhnutelně setká s potřebou spravovat externí knihovny a nástroje. Právě zde vstupuje do hry soubor package.json, který se nachází v kořenovém adresáři projektu a plní roli jakéhosi centrálního registru všeho, co projekt potřebuje ke svému fungování. Bez tohoto souboru by bylo sdílení kódu mezi vývojáři a nasazování aplikací na různá prostředí podstatně komplikovanější, ne-li přímo chaotické.

javascript

Když se podíváme na strukturu typického JavaScript projektu, adresář obsahuje zpravidla složky jako src pro zdrojové soubory, node_modules pro nainstalované závislosti a právě onen klíčový soubor package.json. Tento soubor není jen seznam knihoven — je to kompletní manifest projektu, který zahrnuje název projektu, jeho verzi, popis, vstupní bod aplikace, skripty pro automatizaci úkolů a samozřejmě sekce věnované závislostem.

Závislosti se v souboru package.json dělí do několika kategorií, přičemž nejdůležitější jsou dependencies a devDependencies. Závislosti uvedené pod klíčem dependencies jsou ty, které aplikace potřebuje ke svému běhu v produkčním prostředí. Patří sem například frameworky jako React nebo Vue, knihovny pro práci s HTTP požadavky jako axios, nebo nástroje pro správu stavu aplikace. Naproti tomu devDependencies obsahují balíčky, které jsou nezbytné pouze během vývoje — testovací frameworky jako Jest, bundlery jako Webpack nebo Vite, lintovací nástroje jako ESLint a podobně. Toto rozdělení má praktický dopad při nasazování aplikace, protože v produkčním prostředí není nutné instalovat vývojové závislosti, což šetří čas i diskový prostor.

Verzování závislostí je téma, které si zaslouží zvláštní pozornost. V souboru package.json se verze balíčků zapisují pomocí sémantického verzování, tedy ve formátu MAJOR.MINOR.PATCH. Před číslem verze se často nachází symbol stříšky (^) nebo vlnovky (~), které určují, jak flexibilní má být aktualizace dané závislosti. Stříška povoluje aktualizace v rámci stejné hlavní verze, zatímco vlnovka omezuje aktualizace pouze na záplaty. Pokud není žádný prefix uveden, npm nainstaluje přesně tu verzi, která je specifikována, bez jakýchkoliv odchylek.

Příkaz npm init slouží k vytvoření nového souboru package.json v aktuálním adresáři. Průvodce se postupně zeptá na název projektu, verzi, popis a další metadata. Alternativně lze použít příznak -y, který přeskočí všechny dotazy a vytvoří soubor s výchozími hodnotami. Jakmile je soubor vytvořen, přidávání nových závislostí probíhá pomocí příkazu npm install následovaného názvem balíčku. npm automaticky aktualizuje sekci dependencies v souboru package.json a stáhne příslušné soubory do složky node_modules.

Složka node_modules může být překvapivě objemná — není výjimkou, že obsahuje stovky nebo dokonce tisíce souborů. Je to proto, že každá závislost může mít své vlastní závislosti, a ty zase své, čímž vzniká hluboký strom vzájemně provázaných balíčků. Z tohoto důvodu se složka node_modules nikdy nepřidává do verzovacího systému jako Git. Místo toho se do repozitáře ukládá pouze soubor package.json a soubor package-lock.json, který zachycuje přesné verze všech nainstalovaných balíčků včetně jejich tranzitivních závislostí. Kdokoliv, kdo projekt naklonuje, pak jednoduše spustí příkaz npm install a npm podle těchto souborů přesně zrekonstruuje celou složku node_modules.

Sekce scripts v souboru package.json je další mocný nástroj, který vývojáři hojně využívají. Umožňuje definovat vlastní příkazy, které lze spustit pomocí npm run. Typicky se zde nachází skripty pro spuštění vývojového serveru, sestavení produkční verze aplikace, spuštění testů nebo kontrolu kódu pomocí linteru. Díky tomu nemusí každý člen týmu znát přesné příkazy pro jednotlivé nástroje — stačí se podívat do package.json a okamžitě vidí, jaké operace jsou pro daný projekt k dispozici.

Správa závislostí prostřednictvím souboru package.json tedy není jen technická formalita, ale základní pilíř každého seriózního JavaScript projektu. Zajišťuje reprodukovatelnost prostředí, usnadňuje spolupráci v týmu a přispívá k celkové přehlednosti a udržovatelnosti kódu. Pochopení jeho struktury a správné používání je dovednost, bez které se žádný moderní JavaScript vývojář neobejde.

Složka node_modules a její specifická role

Každý, kdo se někdy pustil do vývoje webových aplikací nebo jakéhokoliv projektu postaveného na JavaScriptu, se dříve či později setkal s adresářem, který nese název node_modules. Je to složka, která dokáže zaskočit začátečníky svou velikostí, ale zkušení vývojáři ji berou jako naprosto přirozenou součást každého projektu. Abychom pochopili, proč tato složka existuje a proč hraje tak zásadní roli, musíme se podívat na celý ekosystém JavaScriptu trochu hlouběji.

Když pracujete s JavaScriptem na straně serveru nebo při sestavování moderních frontendových aplikací, téměř vždy sáhnete po správci balíčků. Nejrozšířenějším z nich je npm, tedy Node Package Manager, který přišel spolu s platformou Node.js. Existují ale i alternativy jako Yarn nebo pnpm, které fungují na podobném principu. Každý z těchto nástrojů pracuje s ekosystémem balíčků, které jsou uloženy v centrálním registru, a právě tyto balíčky se po stažení ukládají do složky node_modules.

Samotná složka node_modules vzniká ve chvíli, kdy spustíte příkaz npm install nebo jeho ekvivalent v jiném správci balíčků. V tu chvíli nástroj přečte soubor package.json, který obsahuje seznam všech závislostí vašeho projektu, a začne je stahovat z registru. Každá závislost se uloží jako samostatný podadresář uvnitř node_modules, přičemž každá z těchto závislostí může mít své vlastní závislosti, které se ukládají buď do sdíleného prostoru, nebo do vnořených složek node_modules uvnitř samotného balíčku. Tato hierarchická struktura je jedním z důvodů, proč může složka narůst do obrovských rozměrů, které občas překvapí i ostřílené vývojáře.

javascript

Je naprosto běžné, že složka node_modules obsahuje stovky nebo dokonce tisíce samostatných balíčků, přestože vy sami jste do souboru package.json zapsali třeba jen deset přímých závislostí. Každý balíček totiž přináší své vlastní závislosti, ty zase své, a tak vzniká hluboký strom závislostí, který může být překvapivě rozsáhlý. Tato tranzitivní povaha závislostí je jedním z nejdůležitějších konceptů, který je třeba pochopit při práci s JavaScriptovými projekty.

Složka node_modules má ještě jednu velmi důležitou vlastnost, která ji odlišuje od ostatních adresářů v projektu. Nikdy by neměla být součástí verzovacího systému, jako je například Git. Právě proto se do souboru .gitignore téměř vždy přidává záznam node_modules. Důvod je prostý — tato složka může mít stovky megabajtů nebo dokonce gigabajty dat, a přitom ji lze kdykoliv znovu vygenerovat jediným příkazem. Ukládat ji do repozitáře by bylo nejen neefektivní, ale mohlo by to způsobit i problémy s kompatibilitou na různých operačních systémech, protože některé balíčky obsahují nativní binární soubory kompilované pro konkrétní platformu.

Při práci s node_modules je také důležité rozumět rozdílu mezi vývojovými závislostmi a produkčními závislostmi. Vývojové závislosti, označené v package.json jako devDependencies, jsou balíčky potřebné pouze během vývoje — například testovací frameworky, nástroje pro sestavení nebo lintovací nástroje. Produkční závislosti jsou naopak ty, které vaše aplikace skutečně potřebuje ke svému běhu. Toto rozlišení má přímý dopad na to, co se nainstaluje do node_modules při různých konfiguracích příkazu npm install.

Zajímavým aspektem je také způsob, jakým Node.js samotný s touto složkou pracuje. Když v kódu napíšete příkaz require('express') nebo moderní import express from 'express', Node.js začne hledat odpovídající balíček právě v adresáři node_modules. Prohledávání probíhá hierarchicky — nejprve se hledá v node_modules aktuálního adresáře, pak v nadřazeném adresáři, a tak dále až ke kořeni souborového systému. Tento mechanismus rozlišování modulů je základem celého systému závislostí v JavaScriptovém ekosystému.

V poslední době se stále více hovoří o alternativních přístupech, které se snaží řešit některé nedostatky tradiční složky node_modules. Nástroj pnpm například používá centrální úložiště balíčků a do node_modules vytváří pouze symbolické odkazy, čímž výrazně šetří místo na disku. Projekt Yarn Plug'n'Play jde ještě dál a složku node_modules zcela eliminuje ve prospěch jiného mechanismu. Přesto zůstává tradiční přístup s node_modules nejrozšířenějším způsobem správy závislostí v JavaScriptovém světě a je nepravděpodobné, že by v dohledné době ztratil svou dominantní pozici.

Verzování a sdílení složek přes GitHub

Každý vývojář, který pracuje s JavaScriptem déle než pár týdnů, se dříve nebo později dostane do situace, kdy potřebuje svůj kód někam uložit, sdílet ho s kolegy nebo se prostě jen vrátit k předchozí verzi, protože něco pokazil. A právě tady přichází na řadu GitHub – platforma, která se stala de facto standardem pro správu verzí a spolupráci na projektech po celém světě.

Srovnání složek/adresářů kódu v různých jazycích
Vlastnost JavaScript Python Java PHP
Název složky/modulu JavaScript složka (adresář .js souborů) Python balíček (package) Java balíček (package) PHP adresář (.php souborů)
Přípona souborů .js, .mjs, .cjs .py .java .php
Správce balíčků npm, yarn, pnpm pip, conda Maven, Gradle Composer
Konfigurační soubor složky package.json __init__.py pom.xml / build.gradle composer.json
Systém modulů CommonJS (require), ES Modules (import) import / from import (package) require / use
Typická struktura složky src/, dist/, node_modules/ src/, venv/, dist/ src/main/java/, target/ src/, vendor/, public/
Průměrná velikost projektu (soubory) 50–500+ souborů 20–200 souborů 30–300 souborů 20–250 souborů
Podpora TypeScript/typování Ano (TypeScript, .ts soubory) Ano (type hints, mypy) Ano (statické typování) Částečně (PHPStan)
Oblíbenost (Stack Overflow 2023) 63,6 % 49,3 % 30,6 % 20,1 %
Prostředí spuštění Prohlížeč, Node.js, Deno Interpret Pythonu JVM (Java Virtual Machine) Webový server (Apache, Nginx)

Když mluvíme o javascriptových projektech, bavíme se nejčastěji o složkách plných souborů s příponou .js, případně modernějších .mjs nebo .cjs, které obsahují veškerou logiku aplikace. Může jít o jednoduchou složku s pěti soubory, nebo o rozsáhlou strukturu s desítkami adresářů, kde se nachází komponenty, utility, testy a konfigurace. Bez ohledu na velikost projektu platí jedno pravidlo – pokud to není verzováno, jako by to neexistovalo.

javascript

Základem celého procesu je Git, verzovací systém, který sleduje každou změnu v souborech. GitHub je pak vzdálená platforma, kde tyto změny ukládáte a odkud je ostatní mohou stahovat. Než vůbec začnete přemýšlet o GitHubu, musíte mít ve své složce inicializovaný Git repozitář. To se provede příkazem git init přímo v kořenovém adresáři vašeho javascriptového projektu. Po tomto kroku Git začne sledovat veškeré změny, které ve složce provedete.

Jenže ne všechno, co je ve složce, chcete sdílet nebo verzovat. Typickým příkladem je adresář node_modules, který může obsahovat stovky megabajtů závislostí nainstalovaných přes npm nebo yarn. Tyto soubory do repozitáře nepatří, protože každý, kdo projekt stáhne, si je může jednoduše doinstalovat sám pomocí příkazu npm install. Proto se do kořenové složky projektu přidává soubor .gitignore, kde se definují cesty a vzory souborů, které Git ignoruje. Pro javascriptové projekty tam typicky patří právě node_modules, různé build složky jako dist nebo build, a také soubory s citlivými informacemi jako jsou .env soubory obsahující API klíče nebo přístupové údaje k databázím.

Jakmile máte repozitář připravený a .gitignore nastavený, přichází na řadu samotný proces commitování. Commit je v podstatě snímek aktuálního stavu vaší složky v daném okamžiku. Nejprve přidáte soubory do tzv. staging area příkazem git add ., čímž řeknete Gitu, které změny chcete zahrnout do dalšího commitu. Pak samotný commit vytvoříte příkazem git commit -m popis změny. Zpráva commitu by měla být stručná, ale výstižná – například přidána validace formuláře nebo opravena chyba v parsování JSON dat.

Propojení lokálního repozitáře s GitHubem probíhá přes tzv. remote. Na GitHubu si vytvoříte nový repozitář, dostanete URL adresu, a tu pak přidáte do svého lokálního Gitu příkazem git remote add origin URL_repozitáře. Od tohoto momentu můžete svou složku nahrávat na GitHub pomocí git push origin main, přičemž main je název výchozí větve.

Větve, anglicky branches, jsou jednou z nejsilnějších funkcí Gitu a při práci na javascriptových projektech se bez nich prakticky neobejdete. Představte si situaci, kdy pracujete na nové funkci – třeba přidáváte do aplikace autentizaci přes OAuth. Nechcete tuto nedokončenou práci míchat s funkčním kódem v hlavní větvi. Proto si vytvoříte novou větev příkazem git checkout -b feature/oauth-login, kde vyvíjíte izolovaně. Když je funkce hotová a otestovaná, větev sloučíte zpátky do main přes pull request na GitHubu.

Pull requesty jsou klíčovým nástrojem pro týmovou spolupráci. Když vývojář dokončí práci na své větvi, otevře pull request, kde ostatní členové týmu mohou projít změny, komentovat konkrétní řádky kódu, navrhovat úpravy a nakonec změny schválit nebo zamítnout. Tento proces code review je naprosto zásadní pro udržení kvality javascriptového kódu, protože JavaScript jako dynamicky typovaný jazyk je náchylnější na určité typy chyb, které může odhalit právě druhý pár očí.

Pro sdílení složky s ostatními vývojáři stačí, aby si repozitář naklonovali příkazem git clone URL_repozitáře. Tím si stáhnou celou strukturu složek i s historií všech commitů. Historie commitů je přitom nesmírně cenná – v každém okamžiku se můžete podívat, kdo, kdy a proč udělal jakou změnu v libovolném souboru projektu.

Moderní javascriptové projekty navíc velmi dobře spolupracují s GitHub Actions, což je nástroj pro automatizaci různých procesů. Například pokaždé, když někdo pushne změny do repozitáře, může se automaticky spustit sada testů napsaných v Jestu nebo Mocha, zkontrolovat formátování kódu přes ESLint, nebo dokonce rovnou nasadit aplikaci na produkční server. Tato automatizace výrazně zefektivňuje vývoj a pomáhá udržovat javascriptovou složku v konzistentním a funkčním stavu bez ohledu na to, kolik lidí na projektu pracuje.

Nástroje pro automatizaci práce se složkami

Při práci s JavaScriptovými projekty se vývojáři velmi rychle setkávají s potřebou efektivně spravovat desítky, někdy i stovky složek a souborů. Ruční procházení adresářové struktury a opakované provádění stejných operací je nejen časově náročné, ale také náchylné k chybám. Právě proto vznikla celá řada nástrojů, které umožňují automatizovat práci se složkami a adresáři v JavaScriptových projektech.

javascript

Jedním z nejzákladnějších přístupů je využití vestavěného modulu Node.js zvaného fs (File System). Tento modul poskytuje rozhraní pro práci se souborovým systémem a umožňuje vytvářet, číst, přesouvat nebo mazat složky přímo z JavaScriptového kódu. Metody jako `fs.mkdir()`, `fs.readdir()` nebo `fs.rmdir()` jsou základními stavebními kameny pro jakoukoliv automatizaci. Moderní verze Node.js navíc nabízí jejich asynchronní varianty s podporou promises, což výrazně zjednodušuje psaní čistého a přehledného kódu bez tzv. callback hell.

Nad rámec základního modulu fs existuje populární balíček fs-extra, který rozšiřuje původní funkcionalitu o řadu užitečných metod. Například metoda `copy()` umožňuje rekurzivně kopírovat celé adresářové stromy včetně všech podsložek a souborů, což je operace, která by s čistým modulem fs vyžadovala podstatně více kódu. Podobně metoda `ensureDir()` zajistí, že daná složka existuje, a pokud neexistuje, automaticky ji vytvoří včetně všech nadřazených adresářů.

Pro složitější scénáře automatizace se vývojáři velmi často obracejí k nástrojům jako je Gulp nebo Grunt. Gulp je task runner postavený přímo na JavaScriptu, který využívá konceptu streamů pro zpracování souborů. Pomocí Gulpu lze definovat úlohy, které automaticky sledují změny v určitých složkách, kompilují SCSS soubory, minifikují JavaScript nebo kopírují statické soubory do výstupního adresáře. Konfigurace Gulpu se píše přímo v JavaScriptu, takže vývojář má plnou kontrolu nad logikou zpracování.

Webpack je dalším nepostradatelným nástrojem, který sice primárně slouží jako modul bundler, ale jeho schopnosti při práci s adresářovou strukturou jsou mimořádné. Webpack dokáže automaticky procházet složky projektu, rozpoznávat závislosti mezi soubory a sestavovat výsledný bundle. Pomocí pluginů jako je `CopyWebpackPlugin` lze snadno definovat pravidla pro kopírování celých adresářů do výstupní složky, přičemž lze využívat glob vzory pro přesné určení, které soubory mají být zahrnuty.

Velmi oblíbeným pomocníkem při automatizaci je také knihovna glob, která umožňuje vyhledávat soubory a složky pomocí vzorů podobných těm, které znají uživatelé příkazové řádky. Vzor jako `src/**/*.js` najde všechny JavaScriptové soubory ve složce src a všech jejích podsložkách, což je ideální základ pro hromadné operace. Glob lze kombinovat s prakticky jakýmkoliv dalším nástrojem a tvoří tak univerzální vrstvu pro výběr souborů.

Nesmíme zapomenout ani na Plop.js, nástroj zaměřený na generování kódu a vytváření nových složek a souborů podle předdefinovaných šablon. Když vývojový tým potřebuje konzistentně vytvářet nové komponenty, moduly nebo stránky se stejnou adresářovou strukturou, Plop.js je ideálním řešením. Stačí jednou definovat generátor a poté pomocí jednoduchého příkazu v terminálu nechat nástroj automaticky vytvořit celou složkovou hierarchii s předvyplněnými soubory.

Automatizace práce se složkami šetří vývojářům nejen čas, ale také snižuje riziko lidských chyb, které se při manuálním přesouvání a kopírování souborů zákonitě objevují. Správně nastavená automatizace zajistí, že výstupní adresář bude vždy obsahovat aktuální verzi kódu, že testovací prostředí bude mít k dispozici správné soubory a že celý tým bude pracovat s konzistentní strukturou projektu. Investice do nastavení těchto nástrojů se vrátí velmi rychle, zejména u větších projektů s komplexní adresářovou hierarchií.

Bezpečnostní rizika spojená se sdílením kódových složek

Sdílení kódových složek v JavaScriptu se stalo naprosto běžnou praxí, a to zejména díky obrovskému ekosystému balíčků dostupných přes npm nebo yarn. Vývojáři denně stahují tisíce závislostí, aniž by si plně uvědomovali, jaká rizika s sebou tento přístup přináší. Zdánlivě nevinná složka s několika soubory `.js` může skrývat závažné bezpečnostní hrozby, které mohou ohrozit celý projekt, data uživatelů nebo dokonce infrastrukturu celé firmy.

Jedním z nejzávažnějších problémů je takzvaný útok na dodavatelský řetězec softwaru (supply chain attack). Útočníci cílí na populární open-source balíčky, které jsou součástí tisíců projektů. Pokud se jim podaří do takové složky s kódem vložit škodlivý JavaScript, může se malware šířit lavinovitě. Historicky dobře zdokumentovaným příkladem je případ balíčku `event-stream`, kdy útočník získal přístup k repozitáři a vložil do něj kód určený ke krádeži kryptoměn. Tento incident jasně ukázal, jak snadno může být důvěra vývojářské komunity zneužita.

Dalším problémem je závislost na tranzitivních závislostech. Když vývojář přidá do projektu jednu složku s kódem, málokdy si uvědomuje, že tato složka sama o sobě závisí na desítkách dalších balíčků. Každý z těchto balíčků přitom představuje potenciální vstupní bod pro útočníka. Složka `node_modules`, která je typická pro JavaScriptové projekty, může obsahovat stovky nebo dokonce tisíce souborů od různých autorů, přičemž nikdo z vývojového týmu tyto soubory nikdy nečetl ani neauditoval.

javascript

Problém se dále prohlubuje tím, že JavaScript jako jazyk je ze své podstaty velmi dynamický. Kód může za běhu modifikovat vlastní chování, přistupovat k globálním objektům nebo odesílat data na vzdálené servery. Škodlivý kód ukrytý v JavaScriptové složce může například číst proměnné prostředí obsahující API klíče, hesla nebo tokeny a odesílat je útočníkovi, aniž by to kdokoli zaznamenal. Právě proto je tak důležité věnovat pozornost každé závislosti, kterou do projektu přidáváme.

Nezanedbatelnou hrozbou je také typosquatting, tedy vytváření balíčků s názvy podobnými populárním knihovnám. Vývojář, který omylem napíše `lodahs` místo `lodash`, může stáhnout škodlivý balíček obsahující nebezpečný JavaScript kód. Tato technika je překvapivě účinná, protože překlepy při psaní názvů balíčků jsou velmi časté, zejména při rychlém vývoji nebo při práci pod tlakem.

Sdílení kódových složek mezi různými projekty nebo týmy přináší také riziko neúmyslného úniku citlivých informací. Vývojáři někdy omylem zahrnou do sdílené složky soubory jako `.env`, konfigurační soubory s přihlašovacími údaji nebo soubory obsahující privátní klíče. Jakmile je taková složka nahrána na veřejný repozitář nebo sdílena přes npm, je prakticky nemožné zajistit, aby se tyto informace nedostaly do nesprávných rukou. I po odstranění citlivých dat z repozitáře mohou být tyto informace stále dostupné v historii commitů nebo v cache různých nástrojů.

Dalším aspektem, který si zaslouží pozornost, je problém zastaralých závislostí. Složky s JavaScriptovým kódem, které nejsou pravidelně aktualizovány, mohou obsahovat zranitelnosti, které jsou v novějších verzích již opraveny. Útočníci aktivně sledují databáze zranitelností jako CVE a cílí na projekty, které používají zastaralé verze knihoven. Pravidelný audit závislostí pomocí nástrojů jako `npm audit` nebo `snyk` je proto nezbytnou součástí bezpečnostní praxe každého vývojáře pracujícího s JavaScriptem.

Integrita stažených balíčků je dalším kritickým bodem. Při stahování kódových složek z veřejných registrů není vždy zaručeno, že obsah odpovídá tomu, co bylo původně publikováno. Útočníci mohou za určitých okolností podvrhnout obsah balíčku nebo kompromitovat samotný registr. Použití souborů jako `package-lock.json` nebo `yarn.lock`, které zaznamenávají přesné verze a kontrolní součty stažených souborů, výrazně snižuje toto riziko, ale neodstraňuje ho úplně.

V neposlední řadě je třeba zmínit rizika spojená se sdílením interních kódových složek mezi týmy v rámci jedné organizace. Pokud není nastaven jasný proces schvalování a revize kódu, může se stát, že do sdílené složky pronikne kód s bezpečnostními chybami, jako jsou například SQL injection zranitelnosti, cross-site scripting nebo nesprávné zacházení s uživatelskými daty. Tyto chyby se pak mohou šířit do všech projektů, které danou složku využívají, a jejich oprava může být velmi nákladná a časově náročná.

Nejlepší praktiky pro udržitelnou strukturu projektu

Udržitelná struktura projektu v JavaScriptu je jednou z těch věcí, které většina vývojářů podceňuje na začátku a pak za to draze platí v průběhu vývoje. Když projekt začíná, adresářová struktura vypadá přehledně a logicky, ale jak projekt roste, bez pevných pravidel se rychle změní v nepřehledný chaos, ve kterém se nikdo nevyzná. Správně navržená složková struktura není jen estetická záležitost — je to základ, na kterém stojí celý projekt.

Jednou z nejdůležitějších zásad je oddělení zodpovědností. Každá složka by měla mít jasně definovaný účel a soubory v ní by měly tento účel respektovat. Pokud máte složku `components`, měly by v ní být výhradně komponenty, nikoliv pomocné funkce, konstanty nebo konfigurační soubory. Míchání různých typů souborů do jedné složky je jednou z nejčastějších příčin toho, že projekt začne být nepřehledný. Vývojáři pak tráví zbytečně mnoho času hledáním souborů místo toho, aby psali kód.

Dalším důležitým aspektem je konzistence pojmenování souborů a složek. V JavaScriptových projektech se setkáváme s různými konvencemi — camelCase, PascalCase, kebab-case. Není tak důležité, kterou konvenci zvolíte, jako to, abyste ji důsledně dodržovali v celém projektu. Pokud pojmenováváte komponenty pomocí PascalCase, jako například `UserProfile.js` nebo `NavigationMenu.js`, pak by všechny komponenty měly následovat tento vzor. Nedůslednost v pojmenování způsobuje zmatek a zpomaluje orientaci v kódu, zejména v týmech, kde pracuje více vývojářů.

Hloubka zanořování složek je dalším faktorem, který výrazně ovlivňuje udržitelnost projektu. Příliš hluboká hierarchie složek ztěžuje navigaci a prodlužuje importní cesty, které se pak stávají noční můrou při refaktoringu. Obecně se doporučuje nepřekračovat tři až čtyři úrovně zanoření. Pokud zjistíte, že vaše cesty vypadají jako `../../../../../../utils/helpers/string/format.js`, je to jasný signál, že struktura potřebuje přehodnotit. Moderní nástroje jako webpack nebo Vite umožňují nastavit aliasy pro importy, což tento problém částečně řeší, ale není to náhrada za dobře navrženou strukturu.

javascript

Princip kolokace je jednou z nejpraktičtějších metodik pro organizaci JavaScriptových projektů. Místo toho, abyste všechny testy dávali do jedné globální složky `tests` a všechny styly do složky `styles`, umísťujte soubory, které spolu úzce souvisí, vedle sebe. Pokud máte komponentu `Button.js`, její testy `Button.test.js` a styly `Button.module.css` by měly být ve stejné složce. Tímto způsobem je okamžitě zřejmé, co k čemu patří, a při mazání nebo přesouvání komponenty nezapomenete na žádný přidružený soubor.

Sdílené utility a pomocné funkce by měly mít své pevné místo ve struktuře projektu. Složka `utils` nebo `helpers` by měla obsahovat pouze skutečně generické funkce, které jsou použitelné napříč celým projektem. Funkce, které jsou specifické pro určitou část aplikace, by měly zůstat v blízkosti té části, kde se používají. Toto rozlišení pomáhá udržet globální utility skutečně globálními a zabraňuje jejich zbytečnému nafukování.

Konfigurace projektu, jako jsou soubory `webpack.config.js`, `.eslintrc`, `.prettierrc` nebo `jest.config.js`, patří do kořenového adresáře projektu. Nikdy by neměly být pohřbeny hluboko ve struktuře složek, protože jsou to soubory, které ovlivňují celý projekt a vývojáři je potřebují rychle najít. Stejně tak soubor `package.json` a dokumentace ve formě `README.md` patří na nejvyšší úroveň.

Pro větší projekty se osvědčil přístup organizace podle funkčních domén nebo modulů namísto organizace podle technického typu souboru. Místo struktury, kde máte samostatné složky pro všechny komponenty, všechny hooky a všechny služby, rozdělíte projekt podle oblastí funkcionality. Například složka `user` by obsahovala vše, co se týká uživatelů — komponenty, hooky, API volání i typy. Tento přístup výrazně zlepšuje škálovatelnost projektu a usnadňuje práci v týmech, kde různí vývojáři pracují na různých částech aplikace.

Pravidelný audit struktury projektu by měl být součástí vývojového procesu. Struktura, která dávala smysl na začátku projektu, nemusí být optimální po šesti měsících vývoje. Nebojte se refaktorovat adresářovou strukturu, i když to vyžaduje úsilí — investice do přehledné struktury se vždy vrátí v podobě rychlejšího vývoje a snazší údržby.

Publikováno: 28. 06. 2026

Kategorie: Programování a vývoj