Skip to content

Reference - Asset Třída

Třída Petrovo\Asset\Asset zajišťuje integraci Vite build systému s PHP.


Princip fungování

Asset třída automaticky:

  1. Dev režim: Detekuje běžící Vite dev server → vrací <script> tagy přímo ze serveru
  2. Production: Čte manifest.json → vrací optimalizované <script> a <link> tagy s verzemi

Manifest je generován Vite při buildu a obsahuje mapy vstupních bodů na výstupní soubory.


Veřejné metody

vite() – Hlavní metoda

public static function vite(string $server, string $entry): string

Vrátí HTML tagy (script/link) pro daný vstupní bod.

Parametry:

Parametr Typ Popis
$server string Dev server URL (např. http://localhost:5173)
$entry string Vstupní bod (např. admin.js, frontend.js)

Návratová hodnota: - HTML tagy pro <script> a <link> elementy - Prázdný string pokud manifest neexistuje a dev server neběží

Dev režim – vráceno:

<script type="module" crossorigin src="http://localhost:5173/admin.js"></script>

Production – vráceno:

<script type="module" crossorigin src="/ADMIN/js/admin.js?1705234567"></script>
<link rel="stylesheet" href="/ADMIN/css/admin.css?1705234567">
<link rel="stylesheet" href="/ADMIN/css/main.css?1705234567">


isViteDevServerRunning() – Detekce dev serveru

public static function isViteDevServerRunning(string $server): bool

Kontroluje zda Vite dev server běží na daném portu.

Parametry:

Parametr Typ Popis
$server string Dev server URL (se schématem http://)

Návratová hodnota:

  • true pokud je server dostupný
  • false v production módu nebo pokud server neodpovídá

Techniky:

  • Používá fsockopen() pro low-level testování
  • Timeout 0.2 sekundy
  • V Docker prostředí používá host.docker.internal místo localhost

Testovací metody

Pro testování lze ručně nastavit režim:

Asset::setPublicDir('/custom/public/dir');    // Vlastní public dir
Asset::setProduction(true);                    // Vynutit production
Asset::setProduction(false);                   // Vynutit dev

Privátní metody

entry() – Rekurzivní řešení závislostí

private static function entry(string $entry, array $manifest): array

Rekurzivně projde vstupní bod a všechny jeho závislosti z manifestu.

Logika:

  1. Najde vstupní bod v manifestu
  2. Generuje tag pro hlavní soubor (JS nebo CSS)
  3. Rekurzivně zpracuje imports a dynamicImports
  4. Přidá CSS soubory
  5. Deduplikuje výsledky

Výsledek:

[
    '<script type="module" crossorigin src="/ADMIN/js/admin.js?v1"></script>',
    '<link rel="stylesheet" href="/ADMIN/css/admin.css?v1">',
    '<script type="module" crossorigin src="/ADMIN/js/main.js?v2"></script>',
    '<link rel="stylesheet" href="/ADMIN/css/main.css?v2">',
]


js() – Generátor script tagů

private static function js(string $url, bool $viteDev): string

Vytvoří HTML <script type="module"> tag s verzemi.

Parametry:

Parametr Typ Popis
$url string Cesta k JS souboru
$viteDev bool True = z dev serveru, False = z production

Dev režim:

<script type="module" crossorigin src="http://localhost:5173/admin.js"></script>

Production režim:

<script type="module" crossorigin src="/ADMIN/js/admin.js?1705234567"></script>


private static function css(string $url): string

Vytvoří HTML <link rel="stylesheet"> tag s verzemi.

Parametr:

Parametr Typ Popis
$url string Cesta k CSS souboru

Production – vráceno:

<link rel="stylesheet" href="/ADMIN/css/admin.css?1705234567">


getAssetVersion() – Verzionování

private static function getAssetVersion(string $path): string

Vrátí verzi assetu pro cache-busting.

Logika:

  • Pokud soubor existuje: použije filemtime() (čas změny)
  • Pokud neexistuje: generuje random číslo (1000-9999)

Výhody:

  • Soubory se změní → nová verze → prohlížeč znovu stáhne
  • Dev: random verze → vždy fresh load

getManifest() – Načtení manifestu

private static function getManifest(): array

Načte a dekóduje manifest.json ze správného umístění.

Cesty:

  • Frontend: /public/.vite/manifest.json
  • Admin: /public/ADMIN/.vite/manifest.json

Návratová hodnota:

  • Dekódované pole z JSON
  • Prázdné pole pokud soubor neexistuje

jsPreload() – Preload dynamických modulů

private static function jsPreload(string $url): string

Vytvoří <link rel="modulepreload"> tag pro dynamické importy.

<link rel="modulepreload" href="/js/utils.js">

Manifest.json struktura

Manifest je generován Vite během buildu a obsahuje mapu zdrojů na výstupní soubory.

Příklad manifestu

{
  "admin.js": {
    "file": "js/admin.js",
    "name": "admin",
    "src": "admin.js",
    "isEntry": true,
    "imports": [
      "_main.js"
    ],
    "css": [
      "css/admin.css"
    ]
  },
  "_main.js": {
    "file": "js/main.js",
    "name": "main",
    "css": [
      "css/main.css"
    ]
  }
}

Struktura záznamu

Klíč Popis
file Výstupní soubor po Vite buildu
src Zdrojový vstupní bod (vstup do Vite)
isEntry True = hlavní vstupní bod
imports Závislosti (sdílené moduly)
dynamicImports Dynamicky importované moduly
css CSS soubory závislé na JS

Dev vs Production režim

Development

Vite dev server běží → Asset detekuje → vrací:
<script src="http://localhost:5173/admin.js"></script>

Vlastnosti:

  • Přímý přístup k dev serveru
  • Hot reload (změna souboru = automatický refresh)
  • Bez optimalizace, bez minifikace
  • Rychlejší vývoj

Production

Vite build dokončen → Asset čte manifest → vrací:
<script src="/ADMIN/js/admin.js?1705234567"></script>
<link rel="stylesheet" href="/ADMIN/css/admin.css?1705234567">

Vlastnosti:

  • Načítá z manifest.json
  • Optimalizované bundly (tree-shake, minify)
  • Verzionování pro cache-busting
  • Deduplikované CSS/JS

Konfigurace

Vlastnosti se čtou z CONFIG:

# /config/development.yaml
vite_backend: http://localhost:5173   # Admin dev server
vite_frontend: http://localhost:5174  # Frontend dev server

Používá se v taggech:

// app/tags/ADMIN/assets/admin.php
Asset::vite(CONFIG['vite_backend'], 'admin.js');

// app/tags/assets/frontend.php
Asset::vite(CONFIG['vite_frontend'], 'frontend.js');

Konstanta SUBDIR

V projektu s podadresářem (starší projekty) se nastavuje:

private const string SUBDIR = '';  // výchozí - root
// nebo
private const string SUBDIR = '/content';  // v /content/*

Ovlivňuje vygenerované cesty:

// s SUBDIR = ''
/ADMIN/js/admin.js

// s SUBDIR = '/content'
/content/ADMIN/js/admin.js

Bezpečnost

  • XSS prevention: HTML tagy se negenerují z uživatelských dat
  • Path traversal: Cesty se berou pouze z manifestu
  • Dev server detekce: Měkký fallback (fsockopen timeout 0.2s)

Chování v edge cases

Případ Chování
Dev server běží + manifest existuje Priorita dev serveru
Dev server neběží + manifest existuje Čte manifest
Dev server neběží + manifest neexistuje Vrátí prázdný string
Neexistující vstupní bod Vrátí prázdný string
Docker prostředí Detekuje host.docker.internal

Integrace s Tracy

Debugger panel v /core/Tracy/VitePanel.php zobrazuje:

  • Stav Vite dev serveru (zeleně/šedě)
  • Aktuální port (5173/5174)
  • Dev/Production režim