Jak si přehledně uspořádat složku s JavaScript projekty
- Co je adresář JavaScript souborů
- Typická struktura složky s projektem
- Rozdíl mezi zdrojovým a sestaveným kódem
- Soubory src a dist vysvětlení
- Role souboru package.json ve složce
- Moduly a jejich organizace v adresářích
- Konfigurační soubory a jejich umístění
- Testovací soubory a jejich struktura
- Minifikované a zabalené výstupní soubory
- Nástroje pro správu balíčků a složek
- Doporučené konvence pojmenování souborů
- Bezpečnostní rizika veřejně dostupných složek
Co je adresář JavaScript souborů
Adresář JavaScript souborů je v podstatě obyčejná složka v rámci souborového systému projektu, do které se ukládají všechny soubory s příponou .js, tedy soubory obsahující kód napsaný v jazyce JavaScript. Na první pohled se může zdát, že jde o něco triviálního, ale ve skutečnosti má takový adresář v každém webovém nebo aplikačním projektu docela zásadní roli. Slouží jako místo, kde jsou logicky soustředěny veškeré skripty, které zajišťují chování stránky nebo aplikace – od jednoduchých validací formulářů přes animace až po složitou logiku jednostránkových aplikací.
V praxi se takový adresář nejčastěji nazývá js, scripts nebo javascript a bývá umístěn v kořenovém adresáři projektu nebo ve složce s veřejně dostupnými soubory, jako je třeba public nebo assets. Důvod je prostý – vývojáři potřebují mít přehled o tom, kde hledat konkrétní funkcionalitu, a oddělení JavaScript kódu od HTML struktury nebo CSS stylů dává celému projektu jasný řád. Bez takového rozdělení by se v rozsáhlejších projektech jen těžko orientovalo, protože počet souborů s funkcemi, moduly a pomocnými skripty roste s velikostí aplikace poměrně rychle.
Uvnitř adresáře JavaScript souborů se často nachází další podsložky, které rozdělují kód podle jeho účelu. Může jít třeba o oddělené složky pro komponenty, pro pomocné funkce (takzvané utils), pro konfigurační soubory nebo pro soubory třetích stran, tedy knihovny a frameworky, které si vývojář do projektu přidal. Tato hierarchie pomáhá udržet kód přehledný a usnadňuje i týmovou spolupráci, protože každý člen vývojářského týmu ví, kam má nový soubor umístit a kde naopak hledat existující funkcionalitu.
Důležité je zmínit, že adresář JavaScript souborů není jen pasivní úložiště – jeho struktura přímo ovlivňuje, jak se kód načítá do prohlížeče, jak se sestavuje pomocí nástrojů typu bundler a jak snadno se dá kód udržovat a rozšiřovat. V moderních projektech, kde se využívají frameworky jako React, Vue nebo Angular, bývá organizace tohoto adresáře ještě promyšlenější, protože se často kombinuje s dalšími typy souborů, jako jsou styly nebo šablony, do takzvaných komponentových složek.
Za zmínku stojí i to, že v menších nebo starších projektech může být celý JavaScript kód uložen v jediném souboru, zatímco u větších a modernějších aplikací je naprosto běžné mít desítky až stovky souborů rozdělených do logických celků. Tento přístup odpovídá principu modularity, který je dnes v programování považován za standard, protože umožňuje znovupoužitelnost kódu, snadnější testování a rychlejší odhalování chyb. Adresář JavaScript souborů tak představuje základní stavební kámen organizace každého projektu, který s tímto jazykem pracuje, ať už jde o jednoduchou webovou prezentaci, nebo rozsáhlou webovou aplikaci s komplexní business logikou.
Typická struktura složky s projektem
Když otevřete typický projekt napsaný v JavaScriptu, hned na první pohled zjistíte, že struktura složek a souborů se u drtivé většiny moderních aplikací řídí podobnými zvyklostmi. Není to náhoda – vychází to z konvencí, které si vynutily nástroje jako npm, Node.js a nejrůznější buildovací systémy. Úplně na kořenové úrovni projektu obvykle najdete soubor package.json, což je vlastně vizitka celého projektu. Obsahuje název balíčku, verzi, seznam závislostí a skripty, kterými se projekt spouští, testuje nebo sestavuje. Vedle něj bývá soubor package-lock.json nebo v případě použití jiného správce balíčků třeba yarn.lock, který zajišťuje, že se na různých strojích nainstalují naprosto stejné verze knihoven.
Samotný zdrojový kód se pak téměř vždy ukrývá ve složce nazvané src, což je zkratka z anglického slova „source“. Právě tady programátoři tráví většinu času, protože zde leží veškerá logika aplikace. Uvnitř této složky bývá struktura dál členěná podle typu projektu – u webových aplikací se často setkáte s podsložkami jako components, kde se ukládají jednotlivé znovupoužitelné části uživatelského rozhraní, dále utils nebo helpers s pomocnými funkcemi, a často také services, kde bývá kód komunikující s externími API nebo databází. U rozsáhlejších aplikací se přidává i složka hooks, pokud se pracuje s frameworkem React, nebo store v případě využití nástrojů pro správu stavu aplikace.
Mimo složku se zdrojovým kódem je naprostou samozřejmostí adresář node_modules, do kterého se stahují veškeré knihovny a balíčky definované v souboru package.json. Tato složka bývá obrovská, často obsahuje desítky tisíc souborů, a proto se nikdy neverzuje v systému Git – místo toho se do konfiguračního souboru .gitignore přidá pravidlo, které tuto složku z verzování úplně vynechá. Dalším běžným adresářem je public nebo static, kam se ukládají soubory, které nemusí procházet žádným zpracováním při sestavování, tedy obrázky, ikony nebo statický soubor HTML sloužící jako vstupní bod aplikace.
Pro testování kódu se zpravidla vyčleňuje samostatná složka, nejčastěji pojmenovaná test nebo __tests__, kde se udržují soubory s jednotkovými i integračními testy odděleně od produkčního kódu. U projektů využívajících TypeScript nebo moderní nástroje pro sestavování, jako je Webpack, Vite nebo Rollup, bývá v kořenovém adresáři i konfigurační soubor s příponou .config.js, případně .ts, který určuje, jak se má výsledná aplikace sestavit a optimalizovat.
Celá tato struktura se samozřejmě může lišit podle velikosti projektu, zvoleného frameworku i osobních preferencí týmu, nicméně výše popsané uspořádání představuje jakýsi neformální standard, se kterým se v JavaScriptovém světě setkáte prakticky všude a který výrazně usnadňuje orientaci novým vývojářům i spolupráci napříč týmy.
Rozdíl mezi zdrojovým a sestaveným kódem
Když programátor otevře složku s JavaScriptem, často narazí na dva naprosto odlišné světy souborů, které na první pohled vypadají podobně, ale slouží zcela jiným účelům. Prvním z nich je zdrojový kód – tedy to, co vývojář skutečně píše ve svém editoru. Je to kód psaný pro člověka, obsahuje smysluplné názvy proměnných, komentáře vysvětlující logiku, odsazení a strukturu, která dává smysl při čtení. Může využívat moderní syntaxi jazyka JavaScript, případně nadstavby jako TypeScript, JSX používaný v Reactu nebo nejnovější funkce specifikace ECMAScript, které ještě nemusí být podporovány všemi prohlížeči. Tento kód je rozdělený do mnoha menších souborů a modulů, protože takové členění usnadňuje údržbu, spolupráci v týmu a orientaci v projektu.
Oproti tomu sestavený kód, často označovaný anglickým termínem build nebo bundle, vzniká až po zpracování zdrojového kódu speciálními nástroji. Mezi nejznámější patří webpack, Vite, Rollup nebo Parcel, které dokážou stovky i tisíce samostatných souborů spojit do jednoho nebo několika málo výsledných souborů. Tento proces se nazývá bundling a jeho hlavním cílem je optimalizace pro reálné nasazení na webu. Sestavený kód bývá minifikovaný, což znamená, že jsou z něj odstraněny veškeré zbytečné znaky – mezery, odřádkování, komentáře – a názvy proměnných jsou zkráceny na jedno nebo dvě písmena. Díky tomu je výsledný soubor výrazně menší a prohlížeč jej načte rychleji, což má přímý dopad na rychlost načítání stránky.
Rozdíl mezi zdrojovým a sestaveným kódem tedy spočívá především v účelu, pro který je kód určen. Zdrojový kód je psán pro vývojáře, zatímco sestavený kód je určen pro stroj, konkrétně pro prohlížeč nebo běhové prostředí jako Node.js. Při přechodu ze zdrojové podoby do sestavené navíc často dochází k takzvané transpilaci, kdy nástroje jako Babel převádějí moderní syntaxi do starší verze JavaScriptu, aby byla zajištěna kompatibilita se staršími prohlížeči. Pokud vývojář používá TypeScript, musí navíc proběhnout kompilace, při které se odstraní typové anotace a vznikne čistý JavaScript srozumitelný prohlížeči.
Důležitým prvkem, který tyto dva světy propojuje, jsou takzvané source mapy. Jedná se o soubory, které umožňují prohlížeči i vývojářským nástrojům přiřadit konkrétní místo v minifikovaném, sestaveném kódu zpět k odpovídajícímu místu ve zdrojovém kódu. Díky tomu lze i po sestavení aplikace ladit chyby přímo v původních, čitelných souborech, i když se ve skutečnosti spouští jejich zkomprimovaná verze. Bez této technologie by bylo hledání chyb v produkčním nasazení prakticky nemožné, protože by vývojář viděl jen nesrozumitelný řetězec znaků bez jakékoliv struktury.
Ve složce projektu proto bývá jasně oddělena adresářová struktura – typicky existuje složka src, kde se nachází veškerý zdrojový kód určený k úpravám, a složka dist nebo build, která obsahuje výstup sestavovacího procesu a nikdy by se neměla ručně upravovat, protože při dalším sestavení by byly veškeré změny přepsány.
Soubory src a dist vysvětlení
Každý vážnější JavaScriptový projekt dříve nebo později narazí na potřebu oddělit zdrojový kód od toho, co se nakonec posílá do prohlížeče nebo na produkční server. Právě od toho jsou tu dva adresáře, se kterými se setká téměř každý vývojář pracující s moderními nástroji jako Webpack, Vite, Rollup nebo Babel – src a dist. Jejich pochopení není žádná věda, ale bez znalosti jejich role se člověk snadno ztratí v tom, proč se vlastně stejný kód objevuje ve dvou různých podobách a proč jeden z nich nikdy neupravujeme ručně.
| Typ adresáře / složky | Obvyklý název | Typický obsah | Použití | Běžné nástroje |
|---|---|---|---|---|
| Zdrojové soubory | src/js nebo src/scripts | Nezkompilované .js nebo .ts soubory, moduly, komponenty | Vývoj aplikace, úprava kódu | Visual Studio Code, WebStorm |
| Výstupní (sestavené) soubory | dist/js nebo build/js | Minifikované a zkompilované .js soubory připravené pro nasazení | Produkční nasazení webu | Webpack, Vite, Rollup |
| Knihovny třetích stran | node_modules | Stažené balíčky a závislosti z npm registru | Sdílený kód, externí funkce | npm, yarn, pnpm |
| Veřejné statické skripty | public/js nebo assets/js | Skripty přímo odkazované v HTML stránkách | Klientská interaktivita webu | Prohlížeč, HTML parser |
| Testovací soubory | tests/js nebo __tests__ | Unit testy, integrační testy psané v JavaScriptu | Ověřování funkčnosti kódu | Jest, Mocha, Cypress |
| Konfigurační skripty | config nebo scripts | Soubory pro build proces, nasazení, automatizaci | Řízení vývojového workflow | Node.js, Gulp, npm scripts |
Adresář src (zkratka od anglického slova source, tedy zdroj) obsahuje skutečný zdrojový kód aplikace. Jsou zde soubory .js, případně .jsx, .ts nebo .tsx, pokud se pracuje s TypeScriptem nebo frameworky jako React. Kód v této složce je psaný tak, aby byl pro vývojáře co nejčitelnější a nejpohodlnější na úpravu – obsahuje komentáře, je rozdělený do logických modulů a komponent, využívá moderní syntaxi jazyka, importy a exporty mezi soubory. Právě v této složce probíhá veškerá reálná práce programátora. Pokud se má do aplikace přidat nová funkce, opravit chyba nebo upravit chování komponenty, dělá se to vždy zde, nikdy jinde.
Naproti tomu dist (od slova distribution, tedy distribuce) obsahuje výstupní, zkompilovaný a optimalizovaný kód, který vznikl automatickým zpracováním souborů ze složky src pomocí sestavovacích nástrojů. Tento proces se běžně nazývá build nebo bundling. Výsledné soubory bývají minifikované, tedy zbavené zbytečných mezer, komentářů a dlouhých názvů proměnných, aby zabíraly co nejméně místa a načítaly se co nejrychleji. Často se také více souborů spojí do jednoho nebo několika málo balíčků, aby prohlížeč nemusel stahovat desítky samostatných souborů zvlášť. Kód ve složce dist je tak sice funkčně identický s tím ve složce src, ale pro člověka je prakticky nečitelný a nikdo by ho neměl ručně upravovat, protože jakýkoliv zásah se při dalším sestavení projektu stejně přepíše.
Tento princip má praktický důvod. Vývojář potřebuje pracovat s přehledným kódem, který lze snadno ladit a rozšiřovat, zatímco prohlížeč nebo produkční prostředí potřebuje co nejmenší a nejrychlejší soubory. Proto se do verzovacího systému, jako je Git, soubory ve složce dist často vůbec nenahrávají a generují se automaticky při nasazení pomocí příkazu typu npm run build. Některé knihovny naopak složku dist zveřejňují i jako součást balíčku na npm, protože právě tyto zkompilované soubory jsou to, co si ostatní projekty při instalaci stahují a používají. Rozdělení na src a dist tak představuje jasně danou hranici mezi světem vývoje a světem reálného nasazení, což usnadňuje spolupráci v týmu i údržbu kódu v dlouhodobém horizontu.
Role souboru package.json ve složce
Soubor package.json tvoří jádro prakticky každé moderní složky s JavaScriptovým kódem a bez něj by se jen stěží dalo mluvit o projektu v pravém slova smyslu. Jakmile vývojář vytvoří adresář určený pro aplikaci postavenou na Node.js nebo pro knihovnu, kterou plánuje publikovat či sdílet s kolegy, téměř vždy jako první krok spustí příkaz, jenž tento soubor vygeneruje. Výsledkem je textový dokument ve formátu JSON, který na první pohled vypadá jednoduše, ale ve skutečnosti drží pohromadě celou strukturu projektu a definuje, jak se s ním má zacházet.
Základní funkcí package.json je evidence metadat o projektu – tedy jeho název, verze, autor, licence nebo stručný popis. Tyto údaje sice nemusí mít přímý vliv na běh aplikace, ale jsou klíčové zejména tehdy, pokud se balíček publikuje do veřejného registru, jako je npm. Díky nim ostatní vývojáři snadno zjistí, o jaký projekt jde, kdo za ním stojí a jakým způsobem jej mohou legálně používat.
Mnohem důležitější je ovšem role, kterou package.json hraje při správě závislostí. V sekci dependencies a devDependencies jsou vyjmenovány všechny externí knihovny a nástroje, na kterých je projekt postavený, včetně jejich verzí. Díky tomu stačí, aby se ke složce s kódem připojil nový člen týmu nebo se projekt přenesl na jiný počítač, a jediným příkazem npm install se nainstalují přesně ty balíčky, které aplikace potřebuje ke správnému fungování. Bez tohoto souboru by bylo nutné závislosti dohledávat ručně, což by bylo nejen zdlouhavé, ale i náchylné k chybám.
Dále package.json obsahuje sekci scripts, která umožňuje definovat vlastní příkazy spouštěné pomocí npm run. Vývojáři si tak mohou nastavit zkratky pro spuštění testů, sestavení produkční verze aplikace, spuštění vývojového serveru nebo formátování kódu. Tato funkce výrazně zjednodušuje každodenní práci, protože odpadá nutnost pamatovat si složité kombinace příkazů a parametrů – stačí napsat jednoduchý a srozumitelný zkrácený zápis.
Neméně podstatná je i informace o tom, který soubor je vstupním bodem celé aplikace nebo knihovny, což se obvykle definuje pomocí klíče main, případně modernějšího module nebo exports. Tato hodnota říká ostatním nástrojům i vývojářům, kde hledat výchozí kód, jenž se má načíst při importu balíčku.
V neposlední řadě package.json slouží i jako nástroj pro zajištění konzistence napříč týmem a prostředími. Díky přesně definovaným verzím závislostí a doplňkovému souboru package-lock.json lze zaručit, že aplikace poběží stejně na vývojářském počítači, testovacím serveru i v produkčním prostředí. To výrazně snižuje riziko chyb způsobených odlišnými verzemi knihoven a zjednodušuje celý proces nasazení a údržby JavaScriptových projektů.
Moduly a jejich organizace v adresářích
Organizace JavaScriptového kódu do adresářové struktury představuje jeden z nejdůležitějších aspektů, se kterými se musí vypořádat každý vývojář, ať už pracuje na drobném skriptu nebo na rozsáhlé aplikaci čítající tisíce souborů. Jakmile projekt přeroste rámec jednoho jediného souboru, přirozeně vyvstává potřeba rozdělit kód do logických celků, které se následně ukládají do samostatných adresářů podle své funkce či účelu. Tento přístup se v praxi ukázal jako nesmírně praktický, protože umožňuje udržet přehlednost i ve velmi komplexních projektech a zároveň usnadňuje spolupráci mezi více vývojáři najednou.
Typická složka s JavaScriptovým kódem bývá označována jako src nebo source, uvnitř které se pak nachází další podadresáře odpovídající jednotlivým vrstvám či oblastem aplikace. Běžně se tak setkáváme s adresáři nazvanými components, utils, services, helpers nebo models, přičemž každý z nich slouží k uchování specifického typu modulů. Komponenty uživatelského rozhraní tak zůstávají oddělené od pomocných funkcí, které zase nejsou míchány s logikou komunikace se serverem. Díky tomu lze snadno dohledat, kde se jaká funkcionalita nachází, aniž by bylo nutné procházet desítky souborů bez jakéhokoliv systému.
Samotné moduly představují základní stavební kameny moderního JavaScriptu. Díky zavedení standardu ES modulů, který se postupně stal nedílnou součástí jazyka, je nyní možné rozdělit kód do samostatných souborů a mezi nimi exportovat a importovat konkrétní funkce, třídy či proměnné. Tím pádem každý soubor představuje izolovanou jednotku s jasně definovaným rozhraním, což výrazně snižuje riziko konfliktů a nechtěného přepisování proměnných. Dříve se v tomto ohledu používaly i jiné přístupy, například CommonJS v prostředí Node.js, které fungují na podobném principu, ačkoliv syntaxe se liší.
Organizace do adresářů se často odvíjí od architektonického vzoru, který daný projekt využívá. V aplikacích postavených na komponentovém přístupu, jako jsou ty vytvářené pomocí Reactu nebo Vue, se běžně setkáváme s adresářovou strukturou, kde každá komponenta má svou vlastní složku obsahující nejen samotný JavaScriptový soubor, ale i přidružené styly, testy a případně i soubory s typy. Tento přístup, někdy nazývaný co-location, se osvědčil zejména u větších týmů, protože veškerá logika spojená s konkrétní částí aplikace zůstává pohromadě a není rozptýlena napříč celým projektem.
Jiné projekty naopak preferují rozdělení podle technické vrstvy, kdy se veškerá business logika shromažďuje v jednom adresáři, zatímco vizuální prvky zůstávají oddělené jinde. Žádný z těchto přístupů není univerzálně správný, vždy záleží na konkrétních potřebách projektu, velikosti týmu a také na osobních preferencích vývojářů. Důležité je zachovat konzistenci v rámci celého projektu, protože nejednotná struktura vede k chaosu a zbytečně prodlužuje dobu potřebnou na orientaci v kódu. Mnoho moderních nástrojů a šablon dnes nabízí předpřipravenou adresářovou strukturu, kterou lze použít jako výchozí bod a dále ji přizpůsobit podle konkrétních požadavků daného projektu.
Konfigurační soubory a jejich umístění
Konfigurační soubory tvoří páteř každého JavaScriptového projektu a jejich správné umístění v adresářové struktuře rozhoduje o tom, jak snadno se bude aplikace udržovat, sestavovat a nasazovat. Naprostá většina těchto souborů se tradičně umísťuje do kořenového adresáře projektu, tedy do té složky, kde se nachází i soubor package.json. Tento soubor je vlastně srdcem celého projektu, protože obsahuje seznam závislostí, skripty pro build a spouštění aplikace, metadata o projektu a mnoho dalších informací, které nástroje jako npm nebo yarn potřebují ke správné funkci.
Kromě package.json se v kořenovém adresáři obvykle nachází i soubor package-lock.json nebo jeho ekvivalent yarn.lock, který zamyká přesné verze nainstalovaných balíčků a zajišťuje konzistenci napříč různými prostředími a stroji vývojářů. Je důležité tento soubor nemazat ani ručně neupravovat, protože by to mohlo vést k nekonzistenci mezi vývojovým, testovacím a produkčním prostředím.
Dalším klíčovým souborem je .eslintrc nebo jeho novější varianty jako eslint.config.js, které definují pravidla pro statickou analýzu kódu. Tento soubor se obvykle také nachází v kořenovém adresáři, ačkoliv v rozsáhlejších projektech s více balíčky, takzvaných monorepozitářích, se může vyskytovat i v jednotlivých podsložkách, kde přepisuje nebo rozšiřuje globální nastavení. Podobně je to s konfigurací formátovače kódu, nejčastěji Prettier, jehož nastavení bývá uloženo v souboru .prettierrc.
Pokud projekt využívá nějaký build nástroj, jako je Webpack, Vite nebo Rollup, i jejich konfigurační soubory se standardně umísťují do kořenové složky, nejčastěji pod názvy webpack.config.js nebo vite.config.js. Tyto soubory definují, jak se má zdrojový kód transformovat, minifikovat a sbalovat do výsledných souborů určených pro nasazení. V případě projektů používajících TypeScript nesmí chybět soubor tsconfig.json, který určuje, jak se má kód kompilovat a jaká pravidla typové kontroly se mají uplatňovat.
Samotná struktura složek se zdrojovým kódem bývá oddělená od konfiguračních souborů a většinou se nachází v adresáři nazvaném src. Uvnitř této složky se kód dále člení podle logiky aplikace, typicky na komponenty, služby, utility nebo stránky, podle toho, jaký framework nebo architekturu projekt využívá. Testovací soubory bývají buď přímo vedle zdrojového kódu s příponou jako .test.js nebo .spec.js, nebo se shromažďují ve zvláštní složce nazvané tests či __tests__.
Proměnné prostředí a citlivé údaje, jako jsou přístupové klíče nebo adresy databází, se obvykle ukládají do souboru .env, který by nikdy neměl být součástí verzovacího systému a měl by být uveden v souboru .gitignore. Díky této organizaci zůstává projekt přehledný, snadno škálovatelný a noví vývojáři se v něm dokážou rychle zorientovat bez zbytečného hledání, kde se co nachází.
Testovací soubory a jejich struktura
Ve složce s JavaScriptovým kódem bývají testovací soubory jednou z nejčastějších součástí adresářové struktury a jejich správné umístění výrazně ovlivňuje přehlednost celého projektu. V praxi se zpravidla setkáváme se dvěma základními přístupy – buď jsou testy umístěny přímo vedle souborů, které testují, nebo tvoří samostatnou izolovanou složku, typicky pojmenovanou test, tests nebo __tests__. Druhý přístup je u větších projektů mnohem oblíbenější, protože umožňuje jasně oddělit produkční kód od testovacího a usnadňuje konfiguraci nástrojů, které testy spouštějí.
Soubory s testy bývají pojmenovány tak, aby bylo na první pohled jasné, k jakému modulu nebo komponentě se vztahují. Nejčastější konvence využívá přípony jako .test.js nebo .spec.js, případně jejich varianty pro TypeScript. Pokud tedy existuje soubor utils.js, jeho testovací protějšek se obvykle nazývá utils.test.js nebo utils.spec.js. Díky této konvenci dokážou testovací frameworky, jako je Jest, Vitest nebo Mocha, automaticky rozpoznat, které soubory obsahují testovací sady, a spustit je bez nutnosti ručního vyjmenovávání cest.
Struktura testovacích souborů bývá hierarchicky organizována pomocí bloků, které popisují testovanou funkcionalitu srozumitelným způsobem. Typicky se využívá funkce describe, která seskupuje související testy do logických celků, a funkce it nebo test, která definuje konkrétní testovací případ. Uvnitř těchto bloků se pak pomocí assertion knihoven, jako je expect, ověřuje, zda kód skutečně vrací očekávané výsledky. Tato struktura umožňuje psát testy, které jsou čitelné i pro lidi, kteří se na vývoji přímo nepodíleli, protože popisy testů fungují téměř jako dokumentace chování aplikace.
Velké projekty často rozdělují testy do několika kategorií podle jejich účelu – jednotkové testy, integrační testy a end-to-end testy. Jednotkové testy se soustředí na izolované funkce či komponenty a bývají umístěny nejblíže testovanému kódu, zatímco integrační a end-to-end testy, které ověřují spolupráci více částí aplikace nebo chování celého systému, mívají vlastní samostatné adresáře, často pojmenované integration nebo e2e. Takové rozdělení pomáhá nejen při orientaci v projektu, ale i při nastavování různých spouštěcích skriptů, kdy lze jednotlivé kategorie testů spouštět odděleně podle potřeby, například při rychlé kontrole během vývoje nebo při komplexním ověření před nasazením do produkce.
Nedílnou součástí struktury testovacích souborů bývají i pomocné soubory, takzvané mocky a fixtures, které simulují data nebo chování závislostí, jež nejsou předmětem testu. Tyto soubory se obvykle ukládají do samostatných podsložek, aby nezatěžovaly hlavní testovací logiku a zároveň byly snadno znovupoužitelné napříč více testovacími soubory. Díky promyšlené organizaci testů tak vývojáři dokážou udržovat kód udržitelný, snadno rozšiřitelný a odolný vůči chybám, které by jinak mohly zůstat dlouho nepovšimnuty.
Složka s JavaScriptem je jako městská čtvrť za soumraku – na první pohled chaos uliček a stínů, ale každý soubor zná svou cestu domů a ví, kam patří.
Bohumil Krejčí
Minifikované a zabalené výstupní soubory
Ve složce s JavaScriptovým kódem se vedle zdrojových souborů téměř vždy objevují i jejich minifikované a zabalené varianty, které slouží k nasazení do produkčního prostředí. Zatímco zdrojové soubory jsou psané tak, aby jim rozuměl programátor – obsahují odsazení, komentáře, smysluplné názvy proměnných a funkcí – minifikované výstupy mají úplně jiný účel. Jejich jediným smyslem je být co nejmenší a nejrychleji zpracovatelné prohlížečem nebo runtime prostředím, jako je Node.js. Proto se z nich odstraňují veškeré bílé znaky, komentáře se mažou, dlouhé názvy proměnných se nahrazují jednopísmennými zkratkami a často se i sémanticky ekvivalentní zápisy nahrazují kratšími alternativami.
Tento proces se obvykle neprovádí ručně. Vývojáři k tomu využívají nástroje typu Terser, UglifyJS nebo minifikační pluginy zabudované přímo v bundlerech, jako je Webpack, Rollup či modernější esbuild a Vite. Výsledkem bývá soubor s příponou .min.js, který se od původního zdrojového kódu může lišit natolik, že je prakticky nečitelný – a to je záměr. Menší velikost souboru znamená rychlejší stahování stránky, menší zátěž sítě a rychlejší spuštění aplikace, což má přímý dopad na uživatelský zážitek i na hodnocení výkonu webu například v nástrojích jako Google PageSpeed Insights.
Vedle minifikace se v JavaScriptových projektech běžně setkáváme i se zabalením více souborů do jednoho celku, tzv. bundlingem. Moderní aplikace se totiž skládají z desítek až tisíců modulů, které mezi sebou komunikují pomocí importů a exportů. Pokud by se takové množství souborů posílalo prohlížeči jednotlivě, znamenalo by to obrovské množství síťových požadavků a výrazné zpomalení načítání stránky. Bundler proto projde celý strom závislostí, zjistí, které moduly se skutečně používají, a spojí je do jednoho nebo několika výstupních souborů. Často se přitom aplikuje i tzv. tree shaking, tedy odstranění nepoužívaného kódu, což dále zmenšuje výslednou velikost.
Ve složce s kódem tak kromě originálních zdrojů bývá i podadresář, typicky nazvaný dist nebo build, kde se tyto zabalené a minifikované soubory ukládají. Spolu s nimi se často generují i tzv. source mapy – soubory s příponou .map, které umožňují zpětně dohledat, které řádce minifikovaného kódu odpovídají původnímu zdrojovému souboru. Díky tomu lze i v produkčním prostředí efektivně ladit chyby, aniž by bylo nutné nasazovat nečitelný kód v nezměněné podobě pro potřeby debugování.
Je důležité si uvědomit, že minifikované a zabalené soubory by nikdy neměly sloužit jako hlavní pracovní verze kódu. Jsou to pouze odvozené výstupy generované automatizovaně na základě zdrojových souborů, a jakýkoliv zásah by měl probíhat výhradně ve zdrojové podobě, ze které se poté nový výstup znovu vygeneruje.
Nástroje pro správu balíčků a složek
Při práci se složkou nebo adresářem souborů napsaných v JavaScriptu se vývojář dříve nebo později setká s potřebou nějakým způsobem organizovat závislosti, knihovny a moduly, které projekt využívá. Právě proto vznikly nástroje pro správu balíčků, bez kterých si dnes vývoj v JavaScriptu lze jen těžko představit. Nejrozšířenějším z nich je npm (Node Package Manager), který se instaluje automaticky společně s Node.js a slouží jako výchozí bod pro naprostou většinu projektů. Díky němu lze během pár vteřin stáhnout a nainstalovat knihovnu přímo do složky node_modules, která se vytváří v kořenovém adresáři projektu a obsahuje veškerý kód třetích stran, jenž aplikace potřebuje ke svému běhu.
Vedle npm se stále častěji používá i Yarn, alternativní správce balíčků vyvinutý společností Meta, který si v minulosti získal oblibu především díky vyšší rychlosti instalace a lepší konzistenci díky souboru yarn.lock. Dnes už jsou rozdíly mezi npm a Yarn poměrně malé, protože se oba nástroje v průběhu let navzájem inspirovaly a doplnily o podobné funkce, jako je workspaces pro správu monorepozitářů nebo deterministické instalace závislostí. Třetí variantou, která si získává stále více příznivců zejména kvůli úspoře místa na disku a rychlosti, je pnpm. Ten namísto duplikování souborů v každém projektu využívá systém symbolických odkazů a sdíleného úložiště, což výrazně snižuje nároky na úložný prostor při práci s více projekty najednou.
Důležitou roli v organizaci kódu a složek hraje rovněž soubor package.json, který funguje jako jakýsi manifest celého projektu. Obsahuje nejen seznam závislostí a jejich verzí, ale také informace o skriptech, které lze spouštět pomocí příkazové řádky, metadata o projektu a konfiguraci nástrojů, jako jsou linter nebo formátovač kódu. Společně s ním se obvykle objevuje i soubor package-lock.json nebo yarn.lock, jenž zajišťuje, že všichni členové týmu i produkční prostředí používají přesně stejné verze balíčků, což předchází neočekávaným chybám způsobeným nekompatibilitou mezi verzemi knihoven.
Pro správu samotné struktury složek se v komplexnějších projektech využívají i nástroje pro takzvané monorepozitáře, mezi něž patří Turborepo nebo Nx. Ty umožňují v jednom repozitáři spravovat více souvisejících balíčků či aplikací, sdílet mezi nimi kód a zároveň udržovat přehlednou a logickou hierarchii adresářů. Výhodou je centralizovaná správa závislostí, snazší refaktoring napříč projekty a možnost spouštět buildy či testy pouze pro ty části kódu, které byly skutečně změněny.
Nezastupitelnou roli hrají také bundlery, jako je Webpack, Vite nebo esbuild, které sice primárně neslouží ke správě balíčků, ale úzce s organizací souborů souvisí, protože rozhodují o tom, jak se jednotlivé moduly ze složek projektu spojí do výsledných souborů určených pro nasazení. Správná kombinace těchto nástrojů dnes tvoří základ efektivního a udržitelného vývoje v JavaScriptu.
Doporučené konvence pojmenování souborů
Při pojmenovávání souborů a složek obsahujících kód napsaný v JavaScriptu se v praxi vyplatí držet se několika zavedených zvyklostí, které vycházejí jak z technických omezení různých operačních systémů, tak z běžných konvencí komunity vývojářů. Nejrozšířenějším přístupem je takzvaný kebab-case, kdy se jednotlivá slova v názvu souboru oddělují pomlčkou, například user-profile.js nebo shopping-cart-controller.js. Tento formát je oblíbený především proto, že je čitelný, funguje spolehlivě napříč operačními systémy a nezpůsobuje problémy ani při nahrávání na servery či do verzovacích systémů typu Git, kde velká a malá písmena mohou hrát roli a způsobovat nekonzistence mezi Windows a Linuxem nebo macOS.
Druhou často používanou konvencí je camelCase, který se obvykle používá spíše pro pojmenování proměnných a funkcí uvnitř kódu, ale v některých projektech se objevuje i u názvů souborů, zejména pokud daný soubor exportuje jednu konkrétní funkci nebo třídu pojmenovanou právě v tomto stylu. U souborů, které obsahují definici třídy nebo komponenty, se naopak často setkáváme s PascalCase, tedy zápisem, kde každé slovo začíná velkým písmenem, například UserProfile.js nebo ShoppingCartComponent.js. Tato konvence je typická zejména ve frameworcích jako React, kde název souboru komponenty obvykle odpovídá přesně názvu samotné komponenty, což usnadňuje orientaci a napovídá, co se uvnitř souboru skrývá.
Důležitým doporučením je také konzistence v rámci celého projektu. Pokud se tým rozhodne pro jeden styl pojmenování, měl by ho dodržovat ve všech souborech a složkách, protože míchání různých konvencí v jednom repozitáři vede k chaosu a ztěžuje orientaci novým členům týmu. Stejně tak je vhodné zamyslet se nad strukturou složek, do kterých se soubory JavaScriptu ukládají. Běžně se používají názvy jako components, utils, hooks, services nebo helpers, které jasně naznačují účel obsažených souborů. I zde platí, že malá písmena a pomlčky jsou bezpečnější volbou než mezery nebo speciální znaky, jež mohou způsobovat problémy při práci s příkazovou řádkou nebo při automatizovaném zpracování souborů build nástroji.
Dále se doporučuje vyhýbat se diakritice a jakýmkoliv nestandardním znakům v názvech, protože ačkoliv moderní systémy soubory s diakritikou obvykle zvládnou, mohou nastat komplikace při sdílení projektu mezi různými platformami nebo při nasazení na produkční servery. Vhodné je také zachovávat krátké, ale výstižné názvy, které jasně popisují obsah souboru, aniž by byly zbytečně dlouhé. Pokud soubor obsahuje testy, zaběhlou praxí je přidat příponu nebo část názvu jako .test.js nebo .spec.js, což usnadňuje automatické rozpoznání testovacích souborů nástroji jako Jest nebo Mocha. Dodržování těchto zvyklostí sice není vynucováno žádným technickým pravidlem, ale výrazně přispívá k přehlednosti, udržovatelnosti a snazší spolupráci v týmu.
Bezpečnostní rizika veřejně dostupných složek
Veřejně dostupné složky s JavaScriptovým kódem představují jedno z nejčastěji podceňovaných bezpečnostních rizik moderního webu. Mnoho vývojářů nasadí aplikaci do produkčního prostředí a zapomene, že struktura adresářů zůstává přístupná komukoliv, kdo zná nebo uhodne správnou cestu. Pokud server není správně nakonfigurován, může se stát, že celý obsah složky s JavaScriptovými soubory je viditelný ve formě výpisu adresáře, což útočníkovi poskytne přehledný seznam všech souborů, včetně těch, které měly zůstat skryté.
Problém spočívá v tom, že JavaScriptové soubory často obsahují citlivé informace, které tam vývojáři vloží z pohodlnosti nebo z nedostatku zkušeností. Jde například o API klíče, přístupové tokeny, konfigurační údaje k databázím nebo interní komentáře popisující logiku aplikace. Pokud je taková složka veřejně přístupná, stačí útočníkovi otevřít prohlížeč a projít si zdrojové soubory jeden po druhém. Není k tomu potřeba žádný sofistikovaný nástroj, postačí základní znalost struktury webu a trpělivost.
Dalším rizikem je takzvané mapování útočné plochy. Když má útočník přístup k adresářové struktuře, dokáže si poměrně rychle udělat obrázek o tom, jaké knihovny a frameworky aplikace používá, jaké verze jsou nasazené a zda neobsahují známé zranitelnosti. Staré a neaktualizované knihovny jsou přitom jedním z nejčastějších vstupních bodů pro útoky, protože mnoho firem zapomíná pravidelně aktualizovat závislosti svých projektů. Pokud je navíc vidět celá adresářová struktura, útočník snadno odhalí i soubory, které nejsou běžně linkované z hlavní stránky, ale přesto jsou funkční a dostupné.
Nezanedbatelným rizikem je také možnost manipulace s nechráněnými soubory. Pokud server umožňuje nejen čtení, ale i zápis do veřejně dostupné složky, hrozí nahrání škodlivého skriptu, který se následně může vykonat v kontextu důvěryhodné domény. To otevírá dveře k útokům typu cross-site scripting nebo k distribuci malwaru přímo z legitimní webové stránky, což výrazně zvyšuje důvěryhodnost škodlivého obsahu v očích uživatelů i bezpečnostních nástrojů.
Je třeba zmínit i to, že vystavené zdrojové soubory usnadňují reverzní inženýrství celé aplikace. Útočník může studovat, jak probíhá validace vstupů, jak se odesílají požadavky na server nebo jakým způsobem je implementována autentizace uživatelů. Díky tomu dokáže cíleně hledat slabá místa, která by jinak musel objevovat metodou pokus omyl.
Řešením je důsledná konfigurace webového serveru tak, aby zakazovala výpis adresářů, pravidelná kontrola, jaké soubory jsou skutečně veřejně dostupné, a oddělení citlivých konfiguračních údajů od zdrojového kódu, nejlépe pomocí proměnných prostředí. Důležité je také minimalizovat a obfuskovat produkční JavaScriptový kód, čímž se útočníkům ztíží orientace i v případě, že se k souborům přece jen dostanou.
Publikováno: 25. 10. 2026
Kategorie: Programování a vývoj