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:
- Soubor
/app/templates/base.tplzavolá tag{T assets/frontend} - Asset::vite() detekuje běžící server na 5174
- Vrací
<script src="http://localhost:5174/frontend.js"></script> - Prohlížeč stáhne JS přímo z dev serveru
- Jakmile změníš soubor v
/src/frontend/→ dev server vygeneruje update - 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:
- Vite optimalizuje/minifikuje JS a CSS
- Vygeneruje bundly s hash jmény
- Vytvoří
.vite/manifest.jsonv/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:
- Soubor zavolá tag
{T assets/frontend} - Asset::vite() nedetekuje dev server
- Čte
/public/.vite/manifest.json - 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:
- Najde
login.jsv manifestu - Přidá script tag pro soubor
- Rekurzivně zpracuje
imports→ přidá_main.js(ale jen CSS) - Všechna CSS z obou souborů se přidají
- 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