Integrace s Vite

Moderní JavaScriptové aplikace vyžadují sofistikované build nástroje. Nette Assets poskytuje prvotřídní integraci s Vite, nástrojem pro frontend build nové generace. Získejte bleskově rychlý vývoj s Hot Module Replacement (HMR) a optimalizované produkční buildy bez potíží s konfigurací.

  • Nulová konfigurace – automatické propojení mezi Vite a PHP šablonami
  • Kompletní správa závislostí – jeden tag zpracovává všechny assety
  • Hot Module Replacement – okamžité aktualizace JavaScriptu a CSS
  • Optimalizované produkční buildy – code splitting a tree shaking

Nette Assets se bezproblémově integruje s Vite, takže získáte všechny tyto výhody, zatímco budete psát své šablony jako obvykle.

Nastavení Vite

Pojďme nastavit Vite krok za krokem. Nebojte se, pokud jste v build nástrojích noví – vše vysvětlíme!

Krok 1: Instalace Vite

Nejprve nainstalujte Vite a Nette plugin do vašeho projektu:

npm install -D vite @nette/vite-plugin

Tím se nainstaluje Vite a speciální plugin, který pomáhá Vite perfektně fungovat s Nette.

Krok 2: Struktura projektu

Standardní přístup je umístit zdrojové soubory assetů do složky assets/ v kořenovém adresáři projektu a zkompilované verze do www/assets/:

web-project/
├── assets/                   ← zdrojové soubory (SCSS, TypeScript, zdrojové obrázky)
│   ├── public/               ← statické soubory (kopírovány tak, jak jsou)
│   │   └── favicon.ico
│   ├── images/
│   │   └── logo.png
│   ├── app.js                ← hlavní vstupní bod
│   └── style.css             ← vaše styly
└── www/                      ← veřejný adresář (document root)
	├── assets/               ← zde budou zkompilované soubory
	└── index.php

Složka assets/ obsahuje vaše zdrojové soubory – kód, který píšete. Vite tyto soubory zpracuje a umístí zkompilované verze do www/assets/.

Krok 3: Konfigurace Vite

Vytvořte soubor vite.config.ts v kořenovém adresáři projektu. Tento soubor říká Vite, kde má najít vaše zdrojové soubory a kam má umístit zkompilované.

Nette Vite plugin přichází s chytrými výchozími nastaveními, která zjednodušují konfiguraci. Předpokládá, že vaše front-end zdrojové soubory jsou v adresáři assets/ (možnost root) a zkompilované soubory jdou do www/assets/ (možnost outDir). Potřebujete pouze specifikovat vstupní bod:

import { defineConfig } from 'vite';
import nette from '@nette/vite-plugin';

export default defineConfig({
	plugins: [
		nette({
			entry: 'app.js',
		}),
	],
});

Pokud chcete zadat jiný název adresáře pro sestavení vašich assetů, budete muset změnit několik možností:

export default defineConfig({
	root: 'assets', // kořenový adresář zdrojových assetů

	build: {
		outDir: '../www/assets',  // kam jdou zkompilované soubory
	},

	// ... další konfigurace ...
});

Cesta outDir je považována za relativní k root, proto je na začátku ../.

Krok 4: Konfigurace Nette

Řekněte Nette Assets o Vite ve vašem common.neon:

assets:
	mapping:
		default:
			type: vite      # říká Nette, aby použilo ViteMapper
			path: assets

Krok 5: Přidání skriptů

Přidejte tyto skripty do vašeho package.json:

{
	"scripts": {
		"dev": "vite",
		"build": "vite build"
	}
}

Nyní můžete:

  • npm run dev – spustí vývojový server s hot reloadingem
  • npm run build – vytvoří optimalizované produkční soubory

Vstupní body

Vstupní bod je hlavní soubor, kde začíná vaše aplikace. Z tohoto souboru importujete další soubory (CSS, JavaScript moduly, obrázky), čímž vytváříte strom závislostí. Vite sleduje tyto importy a vše sváže dohromady.

Příklad vstupního bodu assets/app.js:

// Importovat styly
import './style.css'

// Importovat JavaScript moduly
import netteForms from 'nette-forms';
import naja from 'naja';

// Inicializovat vaši aplikaci
netteForms.initOnLoad();
naja.initialize();

V šabloně můžete vložit vstupní bod následovně:

{asset 'app.js'}

Nette Assets automaticky generuje všechny potřebné HTML tagy – JavaScript, CSS a jakékoli další závislosti.

Více vstupních bodů

Větší aplikace často potřebují samostatné vstupní body:

export default defineConfig({
	plugins: [
		nette({
			entry: [
				'app.js',      // veřejné stránky
				'admin.js',    // administrační panel
			],
		}),
	],
});

Použijte je v různých šablonách:

{* Na veřejných stránkách *}
{asset 'app.js'}

{* V administračním panelu *}
{asset 'admin.js'}

Důležité: Zdrojové vs. zkompilované soubory

Je klíčové pochopit, že v produkci můžete načíst pouze:

  1. Vstupní body definované v entry
  2. Soubory z adresáře assets/public/

Nemůžete načítat pomocí {asset} libovolné soubory z assets/ – pouze assety odkazované JavaScriptovými nebo CSS soubory. Pokud váš soubor není nikde odkazován, nebude zkompilován. Pokud chcete, aby Vite věděl o dalších assetech, můžete je přesunout do veřejné složky.

Vezměte prosím na vědomí, že Vite ve výchozím nastavení vloží všechny assety menší než 4KB, takže tyto soubory nebudete moci přímo odkazovat. (Viz dokumentace Vite).

{* ✓ Toto funguje – je to vstupní bod *}
{asset 'app.js'}

{* ✓ Toto funguje – je to v assets/public/ *}
{asset 'favicon.ico'}

{* ✗ Toto nebude fungovat – náhodný soubor v assets/ *}
{asset 'components/button.js'}

Vývojový režim

Vývojový režim je zcela volitelný, ale po aktivaci poskytuje značné výhody. Hlavní výhodou je Hot Module Replacement (HMR) – okamžitě vidíte změny bez ztráty stavu aplikace, což činí vývoj mnohem plynulejším a rychlejším.

Vite je moderní build nástroj, který činí vývoj neuvěřitelně rychlým. Na rozdíl od tradičních bundlerů, Vite během vývoje servíruje váš kód přímo do prohlížeče, což znamená okamžitý start serveru bez ohledu na velikost vašeho projektu a bleskově rychlé aktualizace.

Spuštění vývojového serveru

Spusťte vývojový server:

npm run dev

Uvidíte:

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose

Nechte tento terminál otevřený během vývoje.

Nette Vite plugin automaticky detekuje, když:

  1. Vite dev server běží
  2. Vaše Nette aplikace je v debug režimu

Když jsou splněny obě podmínky, Nette Assets načítá soubory z Vite dev serveru namísto zkompilovaného adresáře:

{asset 'app.js'}
{* Ve vývoji: <script src="http://localhost:5173/app.js" type="module"></script> *}
{* V produkci: <script src="/assets/app-4a8f9c7.js" type="module"></script> *}

Není potřeba žádná konfigurace – prostě to funguje!

Práce na různých doménách

Pokud váš vývojový server běží na něčem jiném než localhost (například myapp.local), můžete narazit na problémy s CORS (Cross-Origin Resource Sharing). CORS je bezpečnostní funkce ve webových prohlížečích, která ve výchozím nastavení blokuje požadavky mezi různými doménami. Když vaše PHP aplikace běží na myapp.local, ale Vite běží na localhost:5173, prohlížeč je vnímá jako různé domény a blokuje požadavky.

Máte dvě možnosti, jak to vyřešit:

Možnost 1: Konfigurace CORS

Nejjednodušší řešení je povolit cross-origin požadavky z vaší PHP aplikace:

export default defineConfig({
	// ... další konfigurace ...

	server: {
		cors: {
			origin: 'http://myapp.local',  // URL vaší PHP aplikace
		},
	},
});

Možnost 2: Spusťte Vite na vaší doméně

Dalším řešením je nechat Vite běžet na stejné doméně jako vaše PHP aplikace.

export default defineConfig({
	// ... další konfigurace ...

	server: {
		host: 'myapp.local',  // stejné jako vaše PHP aplikace
	},
});

Ve skutečnosti i v tomto případě musíte nakonfigurovat CORS, protože dev server běží na stejném hostiteli, ale na jiném portu. V tomto případě je však CORS automaticky konfigurován Nette Vite pluginem.

Vývoj s HTTPS

Pokud vyvíjíte na HTTPS, potřebujete certifikáty pro váš Vite vývojový server. Nejjednodušší způsob je použití pluginu, který automaticky generuje certifikáty:

npm install -D vite-plugin-mkcert

Zde je, jak to nakonfigurovat v vite.config.ts:

import mkcert from 'vite-plugin-mkcert';

export default defineConfig({
	// ... další konfigurace ...

	plugins: [
		mkcert(),  // automaticky generuje certifikáty a povolí https
		nette(),
	],
});

Všimněte si, že pokud používáte konfiguraci CORS (možnost 1 výše), musíte aktualizovat URL původu tak, aby používala https:// namísto http://.

Produkční buildy

Vytvořte optimalizované produkční soubory:

npm run build

Vite bude:

  • Minifikovat veškerý JavaScript a CSS
  • Rozdělit kód do optimálních chunků
  • Generovat hashované názvy souborů pro cache-busting
  • Vytvořit soubor manifestu pro Nette Assets

Příklad výstupu:

www/assets/
├── app-4f3a2b1c.js       # Váš hlavní JavaScript (minifikovaný)
├── app-7d8e9f2a.css      # Extrahované CSS (minifikované)
├── vendor-8c4b5e6d.js    # Sdílené závislosti
└── .vite/
	└── manifest.json     # Mapování pro Nette Assets

Hashované názvy souborů zajišťují, že prohlížeče vždy načtou nejnovější verzi.

Veřejná složka

Soubory v adresáři assets/public/ jsou kopírovány do výstupu bez zpracování:

assets/
├── public/
│   ├── favicon.ico
│   ├── robots.txt
│   └── images/
│       └── og-image.jpg
├── app.js
└── style.css

Odkazujte na ně normálně:

{* Tyto soubory jsou kopírovány tak, jak jsou *}
<link rel="icon" href={asset 'favicon.ico'}>
<meta property="og:image" content={asset 'images/og-image.jpg'}>

Pro veřejné soubory můžete použít funkce FilesystemMapperu:

assets:
	mapping:
		default:
			type: vite
			path: assets
			extension: [webp, jpg, png]  # Zkusit WebP jako první
			versioning: true             # Přidat cache-busting

V konfiguraci vite.config.ts můžete změnit veřejnou složku pomocí možnosti publicDir.

Dynamické importy

Vite automaticky rozděluje kód pro optimální načítání. Dynamické importy vám umožňují načítat kód pouze tehdy, když je skutečně potřeba, čímž se snižuje počáteční velikost balíčku:

// Načíst náročné komponenty na vyžádání
button.addEventListener('click', async () => {
	let { Chart } = await import('./components/chart.js')
	new Chart(data)
})

Dynamické importy vytvářejí samostatné chunky, které se načítají pouze v případě potřeby. Tomu se říká „code splitting“ a je to jedna z nejvýkonnějších funkcí Vite. Když používáte dynamické importy, Vite automaticky vytváří samostatné JavaScriptové soubory pro každý dynamicky importovaný modul.

Tag {asset 'app.js'} automaticky nepřednačítá tyto dynamické chunky. Toto je záměrné chování – nechceme stahovat kód, který by se nikdy nemusel použít. Chunky se stahují pouze při provedení dynamického importu.

Pokud však víte, že určité dynamické importy jsou kritické a budou brzy potřeba, můžete je přednačíst:

{* Hlavní vstupní bod *}
{asset 'app.js'}

{* Přednačíst kritické dynamické importy *}
{preload 'components/chart.js'}

To říká prohlížeči, aby stáhl komponentu grafu na pozadí, takže je okamžitě připravena, když je potřeba.

Podpora TypeScriptu

TypeScript funguje ihned po instalaci:

// assets/main.ts
interface User {
	name: string
	email: string
}

export function greetUser(user: User): void {
	console.log(`Hello, ${user.name}!`)
}

Odkazujte na soubory TypeScriptu normálně:

{asset 'main.ts'}

Pro plnou podporu TypeScriptu jej nainstalujte:

npm install -D typescript

Další konfigurace Vite

Zde jsou některé užitečné konfigurační možnosti Vite s podrobnými vysvětleními:

export default defineConfig({
	// Kořenový adresář obsahující zdrojové assety
	root: 'assets',

	// Složka, jejíž obsah je kopírován do výstupního adresáře tak, jak je
	// Výchozí: 'public' (relativně k 'root')
	publicDir: 'public',

	build: {
		// Kam umístit zkompilované soubory (relativně k 'root')
		outDir: '../www/assets',

		// Vyprázdnit výstupní adresář před sestavením?
		// Užitečné pro odstranění starých souborů z předchozích buildů
		emptyOutDir: true,

		// Podadresář uvnitř outDir pro generované chunky a assety
		// To pomáhá organizovat výstupní strukturu
		assetsDir: 'static',

		rollupOptions: {
			// Vstupní bod(y) – může být jeden soubor nebo pole souborů
			// Každý vstupní bod se stane samostatným balíčkem
			input: [
				'app.js',      // hlavní aplikace
				'admin.js',    // administrační panel
			],
		},
	},

	server: {
		// Hostitel, na který se má dev server navázat
		// Použijte '0.0.0.0' pro vystavení do sítě
		host: 'localhost',

		// Port pro dev server
		port: 5173,

		// Konfigurace CORS pro cross-origin požadavky
		cors: {
			origin: 'http://myapp.local',
		},
	},

	css: {
		// Povolit CSS source mapy ve vývoji
		devSourcemap: true,
	},

	plugins: [
		nette(),
	],
});

To je vše! Nyní máte moderní build systém integrovaný s Nette Assets.

verze: 1.0