Integracja z Vite
Nowoczesne aplikacje JavaScript wymagają zaawansowanych narzędzi do budowania. Nette Assets zapewnia pierwszorzędną integrację z Vite, narzędziem do budowania frontendowego nowej generacji. Uzyskaj błyskawiczne środowisko deweloperskie z Hot Module Replacement (HMR) i zoptymalizowane kompilacje produkcyjne bez problemów z konfiguracją.
- Zero konfiguracji – automatyczny most między Vite a szablonami PHP
- Kompletne zarządzanie zależnościami – jeden tag obsługuje wszystkie zasoby
- Hot Module Replacement – natychmiastowe aktualizacje JavaScript i CSS
- Zoptymalizowane kompilacje produkcyjne – dzielenie kodu i tree shaking
Nette Assets integruje się bezproblemowo z Vite, dzięki czemu uzyskujesz wszystkie te korzyści, pisząc swoje szablony jak zwykle.
Konfigurowanie Vite
Skonfigurujmy Vite krok po kroku. Nie martw się, jeśli jesteś nowy w narzędziach do budowania – wyjaśnimy wszystko!
Krok 1: Zainstaluj Vite
Najpierw zainstaluj Vite i wtyczkę Nette w swoim projekcie:
npm install -D vite @nette/vite-plugin
To instaluje Vite i specjalną wtyczkę, która pomaga Vite doskonale współpracować z Nette.
Krok 2: Struktura projektu
Standardowe podejście to umieszczenie plików źródłowych zasobów w folderze assets/
w katalogu głównym
projektu, a skompilowanych wersji w www/assets/
:
web-project/ ├── assets/ ← pliki źródłowe (SCSS, TypeScript, obrazy źródłowe) │ ├── public/ ← pliki statyczne (kopiowane bez zmian) │ │ └── favicon.ico │ ├── images/ │ │ └── logo.png │ ├── app.js ← główny punkt wejścia │ └── style.css ← Twoje style └── www/ ← katalog publiczny (root dokumentu) ├── assets/ ← tutaj trafią skompilowane pliki └── index.php
Folder assets/
zawiera Twoje pliki źródłowe – kod, który piszesz. Vite przetworzy te pliki i umieści
skompilowane wersje w www/assets/
.
Krok 3: Skonfiguruj Vite
Utwórz plik vite.config.ts
w katalogu głównym projektu. Ten plik informuje Vite, gdzie znaleźć Twoje pliki
źródłowe i gdzie umieścić skompilowane.
Wtyczka Nette Vite ma inteligentne wartości domyślne, które upraszczają konfigurację. Zakłada, że Twoje pliki
źródłowe front-end znajdują się w katalogu assets/
(opcja root
), a skompilowane pliki trafiają do
www/assets/
(opcja outDir
). Musisz tylko określić punkt wejścia:
import { defineConfig } from 'vite';
import nette from '@nette/vite-plugin';
export default defineConfig({
plugins: [
nette({
entry: 'app.js',
}),
],
});
Jeśli chcesz określić inną nazwę katalogu do budowania swoich zasobów, będziesz musiał zmienić kilka opcji:
export default defineConfig({
root: 'assets', // katalog główny zasobów źródłowych
build: {
outDir: '../www/assets', // gdzie trafiają skompilowane pliki
},
// ... inna konfiguracja ...
});
Ścieżka outDir
jest traktowana jako względna do root
, dlatego na początku znajduje
się ../
.
Krok 4: Skonfiguruj Nette
Poinformuj Nette Assets o Vite w swoim common.neon
:
assets:
mapping:
default:
type: vite # informuje Nette, aby użyło ViteMapper
path: assets
Krok 5: Dodaj skrypty
Dodaj te skrypty do swojego package.json
:
{
"scripts": {
"dev": "vite",
"build": "vite build"
}
}
Teraz możesz:
npm run dev
– uruchom serwer deweloperski z hot reloadingiemnpm run build
– utwórz zoptymalizowane pliki produkcyjne
Punkty wejścia
Punkt wejścia to główny plik, w którym uruchamia się Twoja aplikacja. Z tego pliku importujesz inne pliki (CSS, moduły JavaScript, obrazy), tworząc drzewo zależności. Vite śledzi te importy i łączy wszystko razem.
Przykładowy punkt wejścia assets/app.js
:
// Importuj style
import './style.css'
// Importuj moduły JavaScript
import netteForms from 'nette-forms';
import naja from 'naja';
// Zainicjuj swoją aplikację
netteForms.initOnLoad();
naja.initialize();
W szablonie możesz wstawić punkt wejścia w następujący sposób:
{asset 'app.js'}
Nette Assets automatycznie generuje wszystkie niezbędne tagi HTML – JavaScript, CSS i wszelkie inne zależności.
Wiele punktów wejścia
Większe aplikacje często potrzebują oddzielnych punktów wejścia:
export default defineConfig({
plugins: [
nette({
entry: [
'app.js', // strony publiczne
'admin.js', // panel administracyjny
],
}),
],
});
Używaj ich w różnych szablonach:
{* Na stronach publicznych *}
{asset 'app.js'}
{* W panelu administracyjnym *}
{asset 'admin.js'}
Ważne: Pliki źródłowe vs skompilowane
Kluczowe jest zrozumienie, że w środowisku produkcyjnym możesz ładować tylko:
- Punkty wejścia zdefiniowane w
entry
- Pliki z katalogu
assets/public/
Nie możesz ładować za pomocą {asset}
dowolnych plików z assets/
– tylko zasoby, do
których odwołują się pliki JavaScript lub CSS. Jeśli Twój plik nie jest nigdzie odwołany, nie zostanie skompilowany. Jeśli
chcesz, aby Vite był świadomy innych zasobów, możesz przenieść je do folderu
publicznego.
Należy pamiętać, że domyślnie Vite wbuduje wszystkie zasoby mniejsze niż 4KB, więc nie będziesz mógł odwoływać się do tych plików bezpośrednio. (Zobacz dokumentację Vite).
{* ✓ To działa - to punkt wejścia *}
{asset 'app.js'}
{* ✓ To działa - to jest w assets/public/ *}
{asset 'favicon.ico'}
{* ✗ To nie zadziała - losowy plik w assets/ *}
{asset 'components/button.js'}
Tryb deweloperski
Tryb deweloperski jest całkowicie opcjonalny, ale zapewnia znaczące korzyści po włączeniu. Główną zaletą jest Hot Module Replacement (HMR) – natychmiastowe widzenie zmian bez utraty stanu aplikacji, co sprawia, że doświadczenie deweloperskie jest znacznie płynniejsze i szybsze.
Vite to nowoczesne narzędzie do budowania, które sprawia, że rozwój jest niewiarygodnie szybki. W przeciwieństwie do tradycyjnych bundlerów, Vite serwuje Twój kod bezpośrednio do przeglądarki podczas developmentu, co oznacza natychmiastowe uruchomienie serwera niezależnie od wielkości projektu i błyskawiczne aktualizacje.
Uruchamianie serwera deweloperskiego
Uruchom serwer deweloperski:
npm run dev
Zobaczysz:
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
Pozostaw ten terminal otwarty podczas developmentu.
Wtyczka Nette Vite automatycznie wykrywa, kiedy:
- Serwer deweloperski Vite jest uruchomiony
- Twoja aplikacja Nette jest w trybie debugowania
Gdy oba warunki są spełnione, Nette Assets ładuje pliki z serwera deweloperskiego Vite zamiast z katalogu skompilowanego:
{asset 'app.js'}
{* W trybie deweloperskim: <script src="http://localhost:5173/app.js" type="module"></script> *}
{* W trybie produkcyjnym: <script src="/assets/app-4a8f9c7.js" type="module"></script> *}
Nie potrzeba konfiguracji – po prostu działa!
Praca na różnych domenach
Jeśli Twój serwer deweloperski działa na czymś innym niż localhost
(np. myapp.local
), możesz
napotkać problemy z CORS (Cross-Origin Resource Sharing). CORS to funkcja bezpieczeństwa w przeglądarkach internetowych,
która domyślnie blokuje żądania między różnymi domenami. Gdy Twoja aplikacja PHP działa na myapp.local
, a
Vite na localhost:5173
, przeglądarka traktuje je jako różne domeny i blokuje żądania.
Masz dwie opcje rozwiązania tego problemu:
Opcja 1: Skonfiguruj CORS
Najprostszym rozwiązaniem jest zezwolenie na żądania cross-origin z Twojej aplikacji PHP:
export default defineConfig({
// ... inna konfiguracja ...
server: {
cors: {
origin: 'http://myapp.local', // URL Twojej aplikacji PHP
},
},
});
Opcja 2: Uruchom Vite na swojej domenie
Innym rozwiązaniem jest uruchomienie Vite na tej samej domenie co Twoja aplikacja PHP.
export default defineConfig({
// ... inna konfiguracja ...
server: {
host: 'myapp.local', // to samo co Twoja aplikacja PHP
},
});
W rzeczywistości, nawet w tym przypadku, musisz skonfigurować CORS, ponieważ serwer deweloperski działa na tej samej nazwie hosta, ale na innym porcie. Jednak w tym przypadku CORS jest automatycznie konfigurowany przez wtyczkę Nette Vite.
Development HTTPS
Jeśli rozwijasz na HTTPS, potrzebujesz certyfikatów dla swojego serwera deweloperskiego Vite. Najprostszym sposobem jest użycie wtyczki, która automatycznie generuje certyfikaty:
npm install -D vite-plugin-mkcert
Oto jak skonfigurować to w vite.config.ts
:
import mkcert from 'vite-plugin-mkcert';
export default defineConfig({
// ... inna konfiguracja ...
plugins: [
mkcert(), // automatycznie generuje certyfikaty i włącza https
nette(),
],
});
Zauważ, że jeśli używasz konfiguracji CORS (Opcja 1 powyżej), musisz zaktualizować adres URL źródła, aby używał
https://
zamiast http://
.
Kompilacje produkcyjne
Utwórz zoptymalizowane pliki produkcyjne:
npm run build
Vite będzie:
- Minifikować cały JavaScript i CSS
- Dzielić kod na optymalne części
- Generować nazwy plików z hashami dla unieważniania pamięci podręcznej
- Tworzyć plik manifestu dla Nette Assets
Przykładowe wyjście:
www/assets/
├── app-4f3a2b1c.js # Twój główny JavaScript (zminifikowany)
├── app-7d8e9f2a.css # Wyodrębniony CSS (zminifikowany)
├── vendor-8c4b5e6d.js # Wspólne zależności
└── .vite/
└── manifest.json # Mapowanie dla Nette Assets
Nazwy plików z hashami zapewniają, że przeglądarki zawsze ładują najnowszą wersję.
Folder publiczny
Pliki w katalogu assets/public/
są kopiowane do wyjścia bez przetwarzania:
assets/
├── public/
│ ├── favicon.ico
│ ├── robots.txt
│ └── images/
│ └── og-image.jpg
├── app.js
└── style.css
Odwołuj się do nich normalnie:
{* Te pliki są kopiowane bez zmian *}
<link rel="icon" href={asset 'favicon.ico'}>
<meta property="og:image" content={asset 'images/og-image.jpg'}>
Dla plików publicznych możesz użyć funkcji FilesystemMapper:
assets:
mapping:
default:
type: vite
path: assets
extension: [webp, jpg, png] # Spróbuj najpierw WebP
versioning: true # Dodaj unieważnianie pamięci podręcznej
W konfiguracji vite.config.ts
możesz zmienić folder publiczny za pomocą opcji publicDir
.
Dynamiczne importy
Vite automatycznie dzieli kod dla optymalnego ładowania. Dynamiczne importy pozwalają ładować kod tylko wtedy, gdy jest faktycznie potrzebny, zmniejszając początkowy rozmiar pakietu:
// Ładuj ciężkie komponenty na żądanie
button.addEventListener('click', async () => {
let { Chart } = await import('./components/chart.js')
new Chart(data)
})
Dynamiczne importy tworzą oddzielne części kodu, które są ładowane tylko wtedy, gdy są potrzebne. Nazywa się to “dzieleniem kodu” i jest to jedna z najpotężniejszych funkcji Vite. Kiedy używasz dynamicznych importów, Vite automatycznie tworzy oddzielne pliki JavaScript dla każdego dynamicznie importowanego modułu.
Tag {asset 'app.js'}
nie ładuje automatycznie tych dynamicznych części kodu. Jest to zamierzone
zachowanie – nie chcemy pobierać kodu, który może nigdy nie zostać użyty. Części kodu są pobierane tylko wtedy, gdy
dynamiczny import jest wykonywany.
Jednakże, jeśli wiesz, że pewne dynamiczne importy są krytyczne i będą potrzebne wkrótce, możesz je wstępnie załadować:
{* Główny punkt wejścia *}
{asset 'app.js'}
{* Wstępnie załaduj krytyczne dynamiczne importy *}
{preload 'components/chart.js'}
To instruuje przeglądarkę, aby pobrała komponent wykresu w tle, dzięki czemu jest on natychmiast gotowy, gdy będzie potrzebny.
Obsługa TypeScript
TypeScript działa od razu po wyjęciu z pudełka:
// assets/main.ts
interface User {
name: string
email: string
}
export function greetUser(user: User): void {
console.log(`Hello, ${user.name}!`)
}
Odwołuj się do plików TypeScript normalnie:
{asset 'main.ts'}
Dla pełnej obsługi TypeScript, zainstaluj go:
npm install -D typescript
Dodatkowa konfiguracja Vite
Oto kilka przydatnych opcji konfiguracyjnych Vite ze szczegółowymi wyjaśnieniami:
export default defineConfig({
// Katalog główny zawierający zasoby źródłowe
root: 'assets',
// Folder, którego zawartość jest kopiowana do katalogu wyjściowego bez zmian
// Domyślnie: 'public' (względnie do 'root')
publicDir: 'public',
build: {
// Gdzie umieścić skompilowane pliki (względnie do 'root')
outDir: '../www/assets',
// Opróżnić katalog wyjściowy przed budowaniem?
// Przydatne do usuwania starych plików z poprzednich kompilacji
emptyOutDir: true,
// Podkatalog w outDir dla generowanych części kodu i zasobów
// Pomaga to zorganizować strukturę wyjściową
assetsDir: 'static',
rollupOptions: {
// Punkt(y) wejścia - może być pojedynczym plikiem lub tablicą plików
// Każdy punkt wejścia staje się oddzielnym pakietem
input: [
'app.js', // główna aplikacja
'admin.js', // panel administracyjny
],
},
},
server: {
// Host do powiązania serwera deweloperskiego
// Użyj '0.0.0.0', aby udostępnić w sieci
host: 'localhost',
// Port dla serwera deweloperskiego
port: 5173,
// Konfiguracja CORS dla żądań cross-origin
cors: {
origin: 'http://myapp.local',
},
},
css: {
// Włącz mapy źródłowe CSS w trybie deweloperskim
devSourcemap: true,
},
plugins: [
nette(),
],
});
To wszystko! Masz teraz nowoczesny system budowania zintegrowany z Nette Assets.