Integrare Vite

Aplicațiile JavaScript moderne necesită instrumente de construire sofisticate. Nette Assets oferă o integrare de primă clasă cu Vite, instrumentul de construire frontend de ultimă generație. Obțineți o dezvoltare ultra-rapidă cu Hot Module Replacement (HMR) și build-uri de producție optimizate, fără bătăi de cap legate de configurare.

  • Zero configurare – punte automată între Vite și șabloanele PHP
  • Gestionare completă a dependențelor – un singur tag gestionează toate asset-urile
  • Hot Module Replacement – actualizări instantanee JavaScript și CSS
  • Build-uri de producție optimizate – împărțirea codului și tree shaking

Nette Assets se integrează perfect cu Vite, astfel încât obțineți toate aceste beneficii în timp ce scrieți șabloanele ca de obicei.

Configurarea Vite

Să configurăm Vite pas cu pas. Nu vă faceți griji dacă sunteți nou în lumea instrumentelor de construire – vom explica totul!

Pasul 1: Instalarea Vite

Mai întâi, instalați Vite și plugin-ul Nette în proiectul dumneavoastră:

npm install -D vite @nette/vite-plugin

Aceasta instalează Vite și un plugin special care ajută Vite să funcționeze perfect cu Nette.

Pasul 2: Structura Proiectului

Abordarea standard este de a plasa fișierele asset sursă într-un folder assets/ în rădăcina proiectului, iar versiunile compilate în www/assets/:

web-project/
├── assets/                   ← fișiere sursă (SCSS, TypeScript, imagini sursă)
│   ├── public/               ← fișiere statice (copiate ca atare)
│   │   └── favicon.ico
│   ├── images/
│   │   └── logo.png
│   ├── app.js                ← punct de intrare principal
│   └── style.css             ← stilurile dumneavoastră
└── www/                      ← director public (rădăcina documentului)
	├── assets/               ← fișierele compilate vor ajunge aici
	└── index.php

Folderul assets/ conține fișierele dumneavoastră sursă – codul pe care îl scrieți. Vite va procesa aceste fișiere și va plasa versiunile compilate în www/assets/.

Pasul 3: Configurarea Vite

Creați un fișier vite.config.ts în rădăcina proiectului dumneavoastră. Acest fișier îi spune lui Vite unde să găsească fișierele sursă și unde să plaseze cele compilate.

Plugin-ul Nette Vite vine cu setări implicite inteligente care simplifică configurarea. Presupune că fișierele dumneavoastră sursă de frontend se află în directorul assets/ (opțiunea root) și că fișierele compilate ajung în www/assets/ (opțiunea outDir). Trebuie doar să specificați punctul de intrare:

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

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

Dacă doriți să specificați un alt nume de director pentru a construi asset-urile, va trebui să modificați câteva opțiuni:

export default defineConfig({
	root: 'assets', // directorul rădăcină al asset-urilor sursă

	build: {
		outDir: '../www/assets',  // unde ajung fișierele compilate
	},

	// ... alte configurații ...
});

Calea outDir este considerată relativă la root, de aceea există ../ la început.

Pasul 4: Configurarea Nette

Spuneți Nette Assets despre Vite în fișierul dumneavoastră common.neon:

assets:
	mapping:
		default:
			type: vite      # îi spune lui Nette să utilizeze ViteMapper
			path: assets

Pasul 5: Adăugați scripturi

Adăugați aceste scripturi în package.json:

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

Acum puteți:

  • npm run dev – pornește serverul de dezvoltare cu reîncărcare la cald
  • npm run build – creează fișiere de producție optimizate

Puncte de Intrare

Un punct de intrare este fișierul principal de unde pornește aplicația dumneavoastră. Din acest fișier, importați alte fișiere (CSS, module JavaScript, imagini), creând un arbore de dependențe. Vite urmărește aceste importuri și le grupează pe toate împreună.

Exemplu de punct de intrare assets/app.js:

// Importă stiluri
import './style.css'

// Importă module JavaScript
import netteForms from 'nette-forms';
import naja from 'naja';

// Inițializează aplicația dumneavoastră
netteForms.initOnLoad();
naja.initialize();

În șablon puteți insera un punct de intrare după cum urmează:

{asset 'app.js'}

Nette Assets generează automat toate tag-urile HTML necesare – JavaScript, CSS și orice alte dependențe.

Puncte de Intrare Multiple

Aplicațiile mai mari necesită adesea puncte de intrare separate:

export default defineConfig({
	plugins: [
		nette({
			entry: [
				'app.js',      // pagini publice
				'admin.js',    // panou de administrare
			],
		}),
	],
});

Utilizați-le în diferite șabloane:

{* În pagini publice *}
{asset 'app.js'}

{* În panoul de administrare *}
{asset 'admin.js'}

Important: Fișiere Sursă vs. Fișiere Compilate

Este crucial să înțelegeți că în producție puteți încărca doar:

  1. Puncte de intrare definite în entry
  2. Fișiere din directorul assets/public/

Nu puteți încărca utilizând {asset} fișiere arbitrare din assets/ – doar asset-uri referențiate de fișiere JavaScript sau CSS. Dacă fișierul dumneavoastră nu este referențiat nicăieri, nu va fi compilat. Dacă doriți ca Vite să fie conștient de alte asset-uri, le puteți muta în folderul public.

Vă rugăm să rețineți că, implicit, Vite va încorpora toate asset-urile mai mici de 4KB, deci nu veți putea referenția aceste fișiere direct. (Vezi documentația Vite).

{* ✓ Acesta funcționează - este un punct de intrare *}
{asset 'app.js'}

{* ✓ Acesta funcționează - este în assets/public/ *}
{asset 'favicon.ico'}

{* ✗ Acesta nu va funcționa - fișier aleatoriu în assets/ *}
{asset 'components/button.js'}

Modul de Dezvoltare

Modul de dezvoltare este complet opțional, dar oferă beneficii semnificative atunci când este activat. Principalul avantaj este Hot Module Replacement (HMR) – vedeți modificările instantaneu fără a pierde starea aplicației, făcând experiența de dezvoltare mult mai fluidă și mai rapidă.

Vite este un instrument modern de construire care face dezvoltarea incredibil de rapidă. Spre deosebire de bundler-ele tradiționale, Vite servește codul dumneavoastră direct browserului în timpul dezvoltării, ceea ce înseamnă pornire instantanee a serverului indiferent de mărimea proiectului și actualizări ultra-rapide.

Pornirea Serverului de Dezvoltare

Rulați serverul de dezvoltare:

npm run dev

Veți vedea:

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

Țineți acest terminal deschis în timpul dezvoltării.

Plugin-ul Nette Vite detectează automat când:

  1. Serverul de dezvoltare Vite rulează
  2. Aplicația dumneavoastră Nette este în modul de depanare

Când ambele condiții sunt îndeplinite, Nette Assets încarcă fișierele de la serverul de dezvoltare Vite în loc de directorul compilat:

{asset 'app.js'}
{* În dezvoltare: <script src="http://localhost:5173/app.js" type="module"></script> *}
{* În producție: <script src="/assets/app-4a8f9c7.js" type="module"></script> *}

Nu este necesară configurare – pur și simplu funcționează!

Lucrul pe Domenii Diferite

Dacă serverul dumneavoastră de dezvoltare rulează pe altceva decât localhost (cum ar fi myapp.local), s-ar putea să întâmpinați probleme CORS (Cross-Origin Resource Sharing). CORS este o funcționalitate de securitate în browserele web care blochează implicit cererile între domenii diferite. Când aplicația dumneavoastră PHP rulează pe myapp.local, dar Vite rulează pe localhost:5173, browserul le consideră domenii diferite și blochează cererile.

Aveți două opțiuni pentru a rezolva acest lucru:

Opțiunea 1: Configurați CORS

Cea mai simplă soluție este să permiteți cererile cross-origin din aplicația dumneavoastră PHP:

export default defineConfig({
	// ... alte configurații ...

	server: {
		cors: {
			origin: 'http://myapp.local',  // URL-ul aplicației dumneavoastră PHP
		},
	},
});

Opțiunea 2: Rulați Vite pe domeniul dumneavoastră

Cealaltă soluție este să faceți Vite să ruleze pe același domeniu ca aplicația dumneavoastră PHP.

export default defineConfig({
	// ... alte configurații ...

	server: {
		host: 'myapp.local',  // la fel ca aplicația dumneavoastră PHP
	},
});

De fapt, chiar și în acest caz, trebuie să configurați CORS deoarece serverul de dezvoltare rulează pe același hostname, dar pe un port diferit. Totuși, în acest caz, CORS este configurat automat de plugin-ul Nette Vite.

Dezvoltare HTTPS

Dacă dezvoltați pe HTTPS, aveți nevoie de certificate pentru serverul dumneavoastră de dezvoltare Vite. Cel mai simplu mod este utilizarea unui plugin care generează certificate automat:

npm install -D vite-plugin-mkcert

Iată cum să-l configurați în vite.config.ts:

import mkcert from 'vite-plugin-mkcert';

export default defineConfig({
	// ... alte configurații ...

	plugins: [
		mkcert(),  // generează certificate automat și activează https
		nette(),
	],
});

Rețineți că dacă utilizați configurația CORS (Opțiunea 1 de mai sus), trebuie să actualizați URL-ul de origine pentru a utiliza https:// în loc de http://.

Build-uri de Producție

Creați fișiere de producție optimizate:

npm run build

Vite va:

  • Minifica tot JavaScript-ul și CSS-ul
  • Împărți codul în bucăți optime
  • Genera nume de fișiere hash-uite pentru invalidarea cache-ului
  • Crea un fișier manifest pentru Nette Assets

Exemplu de ieșire:

www/assets/
├── app-4f3a2b1c.js       # JavaScript-ul dumneavoastră principal (minificat)
├── app-7d8e9f2a.css      # CSS extras (minificat)
├── vendor-8c4b5e6d.js    # Dependențe partajate
└── .vite/
	└── manifest.json     # Mapare pentru Nette Assets

Numele de fișiere hash-uite asigură că browserele încarcă întotdeauna cea mai recentă versiune.

Folder Public

Fișierele din directorul assets/public/ sunt copiate în ieșire fără procesare:

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

Referențiați-le în mod normal:

{* Aceste fișiere sunt copiate ca atare *}
<link rel="icon" href={asset 'favicon.ico'}>
<meta property="og:image" content={asset 'images/og-image.jpg'}>

Pentru fișierele publice, puteți utiliza funcționalitățile FilesystemMapper:

assets:
	mapping:
		default:
			type: vite
			path: assets
			extension: [webp, jpg, png]  # Încearcă WebP mai întâi
			versioning: true             # Adaugă invalidare cache

În configurația vite.config.ts puteți schimba folderul public utilizând opțiunea publicDir.

Importuri Dinamice

Vite împarte automat codul pentru o încărcare optimă. Importurile dinamice vă permit să încărcați codul doar atunci când este efectiv necesar, reducând dimensiunea inițială a bundle-ului:

// Încarcă componente grele la cerere
button.addEventListener('click', async () => {
	let { Chart } = await import('./components/chart.js')
	new Chart(data)
})

Importurile dinamice creează bucăți separate care sunt încărcate doar atunci când este necesar. Acesta se numește “code splitting” și este una dintre cele mai puternice funcționalități ale Vite. Când utilizați importuri dinamice, Vite creează automat fișiere JavaScript separate pentru fiecare modul importat dinamic.

Tag-ul {asset 'app.js'} nu preîncarcă automat aceste bucăți dinamice. Acesta este un comportament intenționat – nu dorim să descărcăm cod care s-ar putea să nu fie folosit niciodată. Bucățile sunt descărcate doar atunci când importul dinamic este executat.

Totuși, dacă știți că anumite importuri dinamice sunt critice și vor fi necesare în curând, le puteți preîncărca:

{* Punct de intrare principal *}
{asset 'app.js'}

{* Preîncarcă importuri dinamice critice *}
{preload 'components/chart.js'}

Acest lucru îi spune browserului să descarce componenta grafic în fundal, astfel încât să fie gata imediat când este necesar.

Suport TypeScript

TypeScript funcționează imediat:

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

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

Referențiați fișierele TypeScript în mod normal:

{asset 'main.ts'}

Pentru suport complet TypeScript, instalați-l:

npm install -D typescript

Configurație Suplimentară Vite

Iată câteva opțiuni utile de configurare Vite cu explicații detaliate:

export default defineConfig({
	// Directorul rădăcină care conține asset-urile sursă
	root: 'assets',

	// Folderul al cărui conținut este copiat în directorul de ieșire ca atare
	// Implicit: 'public' (relativ la 'root')
	publicDir: 'public',

	build: {
		// Unde să plasezi fișierele compilate (relativ la 'root')
		outDir: '../www/assets',

		// Golește directorul de ieșire înainte de construire?
		// Util pentru a elimina fișierele vechi din build-urile anterioare
		emptyOutDir: true,

		// Subdirector în outDir pentru bucățile și asset-urile generate
		// Acest lucru ajută la organizarea structurii de ieșire
		assetsDir: 'static',

		rollupOptions: {
			// Punct(e) de intrare - poate fi un singur fișier sau un array de fișiere
			// Fiecare punct de intrare devine un bundle separat
			input: [
				'app.js',      // aplicația principală
				'admin.js',    // panoul de administrare
			],
		},
	},

	server: {
		// Gazda la care să se lege serverul de dezvoltare
		// Utilizați '0.0.0.0' pentru a expune la rețea
		host: 'localhost',

		// Port pentru serverul de dezvoltare
		port: 5173,

		// Configurare CORS pentru cererile cross-origin
		cors: {
			origin: 'http://myapp.local',
		},
	},

	css: {
		// Activează hărțile sursă CSS în dezvoltare
		devSourcemap: true,
	},

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

Asta e tot! Acum aveți un sistem de construire modern integrat cu Nette Assets.

versiune: 1.0