Skip to content

Příklady použití Asset

Praktické příklady a best practices.


Základní použití v tazích

Frontend – Veřejný web

Vytvoř tag /app/tags/assets/frontend.php:

<?php
declare(strict_types=1);

use Petrovo\Asset\Asset;

$entryPoint = 'frontend.js';

echo Asset::vite(CONFIG['vite_frontend'], $entryPoint);

V šabloně:

<!DOCTYPE html>
<html>
<head>
    {T assets/frontend}
</head>
<body>
    <!-- obsah -->
</body>
</html>

Dev režim – výstup:

<script type="module" crossorigin src="http://localhost:5174/frontend.js"></script>

Production – výstup:

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


Admin Panel – Různé vstupní body

Vytvoř tag /app/tags/ADMIN/assets/admin.php:

<?php
declare(strict_types=1);

use Petrovo\Asset\Asset;

// Różné vstupní body podle stránky
$entryPoint = (PAGE === 'login') ? 'login.js' : 'admin.js';

echo Asset::vite(CONFIG['vite_backend'], $entryPoint);

V admin šabloně:

<!DOCTYPE html>
<html>
<head>
    {T ADMIN/assets/admin}
</head>
<body>
    <!-- admin obsah -->
</body>
</html>

Dev režim – admin.js:

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

Dev režim – login.js:

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

Production – admin.js:

<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?1705234568">

Manifest automaticky řeší všechny CSS a JS závislosti.


Dev vs Production workflow

Development

Spuštění dev serveru:

cd src/
bun run dev  # Spustí Vite na portů 5173 (backend) a 5174 (frontend)

V prohlížeči:

  1. Soubor /app/templates/base.tpl zavolá tag {T assets/frontend}
  2. Asset::vite() detekuje běžící server na 5174
  3. Vrací <script src="http://localhost:5174/frontend.js"></script>
  4. Prohlížeč stáhne JS přímo z dev serveru
  5. Jakmile změníš soubor v /src/frontend/ → dev server vygeneruje update
  6. Hot reload aktualizuje prohlížeč (nebo si stáhne nový soubor)

Výhody:

  • Super rychlý vývoj
  • Okamžitý feedback
  • Bez waiting na build

Production

Build:

cd src/
bun run build  # Kompiluje do /public/ a /public/ADMIN/

Co se stane:

  1. Vite optimalizuje/minifikuje JS a CSS
  2. Vygeneruje bundly s hash jmény
  3. Vytvoří .vite/manifest.json v /public/ a /public/ADMIN/

Manifest obsah:

{
  "frontend.js": {
    "file": "js/frontend.js",
    "css": ["css/frontend.css"],
    "imports": ["_shared.js"]
  },
  "_shared.js": {
    "file": "js/shared.js"
  }
}

V prohlížeči:

  1. Soubor zavolá tag {T assets/frontend}
  2. Asset::vite() nedetekuje dev server
  3. Čte /public/.vite/manifest.json
  4. Vrací optimalizované tagy s verzemi:
    <script type="module" crossorigin src="/js/frontend.js?1705234567"></script>
    <link rel="stylesheet" href="/css/frontend.css?1705234567">

Výhody:

  • Malé bundly (tree-shake, minify)
  • Vysoký výkon
  • Cache-busting (verze v URL)

Příklady vstupních bodů

Admin panel s více vstupními body

/src/backend/admin.js – Hlavní admin:

import './js/main.js';
import './js/menu.js';
import './js/tabs.js';
import './scss/main.scss';

/src/backend/login.js – Login stránka:

import './js/login.js';
import './scss/login.scss';

V tagu zvolíš správný vstupní bod:

$entryPoint = (PAGE === 'login') ? 'login.js' : 'admin.js';
echo Asset::vite(CONFIG['vite_backend'], $entryPoint);


Frontend s jedním vstupním bodem

/src/frontend/frontend.js – Kompletní frontend:

import './js/base.js';
import './js/menu.js';
import './js/gallery.js';
import './scss/frontend.scss';

// Import z app/tags (komponenty z formulářů atd.)
import '../../app/tags/form/contact/form.js';
import '../../app/tags/user/registration/form.js';

V tagu:

echo Asset::vite(CONFIG['vite_frontend'], 'frontend.js');


Manifest řešení – Co vidíš v production

Příklad: Login stránka

Manifest:

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

Asset::vite() výstup:

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

Co se stalo:

  1. Najde login.js v manifestu
  2. Přidá script tag pro soubor
  3. Rekurzivně zpracuje imports → přidá _main.js (ale jen CSS)
  4. Všechna CSS z obou souborů se přidají
  5. Deduplikuje (CSS se neopakuje)

Testování režimu

Ručně vynutit production v dev prostředí

// Někde v debug kódu
use Petrovo\Asset\Asset;

Asset::setProduction(true);

// Teď Asset::vite() bude chovat jako production
// (přečte manifest, nedetekuje dev server)

Asset::setProduction(false);  // Zpět na auto-detekci

Testování s vlastním public dir

Asset::setPublicDir('/custom/public');

// Asset bude hledat manifest a soubory zde

Docker prostředí

Asset automaticky detekuje Docker a používá správné hostname:

// V Docker kontejneru
$host = isPetrovoDockerEnvironment() ? 'host.docker.internal' : 'localhost';

// Takže fsockopen automaticky testuje docker.internal:5173

To znamená:

  • Docker kontejner → dev server na host machine
  • Asset::isViteDevServerRunning('http://localhost:5173') → detekuje ✓

Best Practices

Správně – Oddělené vstupní body

// /app/tags/ADMIN/assets/admin.php
$entryPoint = (PAGE === 'login') ? 'login.js' : 'admin.js';
echo Asset::vite(CONFIG['vite_backend'], $entryPoint);

Výhody:

  • Login stránka nezačíná s celým admin JS
  • Menší bundle pro login
  • Lepší performance

Špatně – Jeden vstupní bod pro všechno

// Všechno v admin.js
echo Asset::vite(CONFIG['vite_backend'], 'admin.js');

Login stránka stahuje zbytečný admin JS.


Správně – Detekce je automatická

use Petrovo\Asset\Asset;

// Nemusíš nic dělat - Asset se sám rozhodne
echo Asset::vite(CONFIG['vite_frontend'], 'frontend.js');

Asset automaticky:

  • Detekuje dev server (fsockopen)
  • Vybere dev mode nebo production
  • Čte manifest v production

Špatně – Ruční detekce

if (APP_ENV === 'dev') {
    echo "<script src=\"http://localhost:5173/frontend.js\"></script>";
} else {
    // Ruční manifest parsing...
}

Zbytečné a náchylné na chyby.


Správně – Konfigurace v config/

# config/development.yaml
vite_backend: http://localhost:5173
vite_frontend: http://localhost:5174

Používáno v tazích:

Asset::vite(CONFIG['vite_backend'], 'admin.js');

Špatně – Hardcoded URLs

Asset::vite('http://localhost:5173', 'admin.js');  // URL v kódu

Těžko se měnilo mezi env.


Troubleshooting

Dev server nedetekuje

# Zkontroluj zda server běží
cd src/ && bun run dev

# Zkontroluj port v Tracy panelu (měl by být zelený)
# Pokud šedý → server neběží nebo je firewall

# Ruční test
php -r "echo stream_socket_client('tcp://localhost:5173') ? 'OK' : 'FAIL';"

CSS se nenačítá

// Zkontroluj manifest
file_get_contents('/public/.vite/manifest.json');

// CSS musí být v "css" poli vstupního bodu
{
  "admin.js": {
    "css": ["css/admin.css"]  // Mělo by tu být
  }
}

Chybí? → Přidej import v src/backend/admin.js:

import './scss/admin.scss';  // SCSS se kompiluje na CSS

Verze v URL se nemění

// V production se verze bere z filemtime()
// Pokud soubor neexistuje → random číslo (1000-9999)

// Zkontroluj že soubor existuje
file_exists('/public/js/admin.js') // ? true : false

// Pokud build failed → zkus znova
cd src/ && bun run build

Advanced – Custom tags

Vytvoření vlastního tagu s Asset:

<?php
// /app/tags/custom/vite-script.php

declare(strict_types=1);

use Petrovo\Asset\Asset;

/**
 * {T custom/vite-script file="app.js" server="vite_frontend"}
 *
 * Vlastní tag pro jednodušší zápis
 *
 * @param array{file: string, server?: string} $params
 * @param object $BOX
 * @param array $calls
 * @return array
 */
return function(array $params, object $BOX, array $calls): array {
    $file = $params['file'] ?? 'frontend.js';
    $serverKey = $params['server'] ?? 'vite_frontend';
    $server = CONFIG[$serverKey] ?? '';

    $html = Asset::vite($server, $file);

    return [$html, $BOX];
};

Použití:

{T custom/vite-script file="login.js"}
{T custom/vite-script file="admin.js" server="vite_backend"}


Performance monitoring

Asset automaticky přidává verze v URL:

<script src="/js/admin.js?1705234567"></script>

Query string ?1705234567 je filemtime() souboru:

  • Když se soubor změní → nová verze → prohlížeč ho znovu stáhne
  • Starší verze zůstávají v cache
  • Zero cold-start pro statické soubory

V Dev Tools (Network):

  • Zelená 304 (Not Modified) → z cache
  • Modrá 200 (OK) → nový soubor