Vite Integration

Moderne JavaScript-Anwendungen erfordern ausgeklügelte Build-Tools. Nette Assets bietet erstklassige Integration mit Vite, dem Frontend-Build-Tool der nächsten Generation. Erhalten Sie blitzschnelle Entwicklung mit Hot Module Replacement (HMR) und optimierte Produktions-Builds mit null Konfigurationsaufwand.

  • Keine Konfiguration – automatische Brücke zwischen Vite und PHP-Templates
  • Vollständiges Abhängigkeitsmanagement – ein Tag verarbeitet alle Assets
  • Hot Module Replacement – sofortige JavaScript- und CSS-Updates
  • Optimierte Produktions-Builds – Code-Splitting und Tree Shaking

Nette Assets integriert sich nahtlos in Vite, sodass Sie all diese Vorteile nutzen können, während Sie Ihre Templates wie gewohnt schreiben.

Vite einrichten

Lassen Sie uns Vite Schritt für Schritt einrichten. Keine Sorge, wenn Sie neu bei Build-Tools sind – wir erklären alles!

Schritt 1: Vite installieren

Installieren Sie zuerst Vite und das Nette-Plugin in Ihrem Projekt:

npm install -D vite @nette/vite-plugin

Dies installiert Vite und ein spezielles Plugin, das Vite hilft, perfekt mit Nette zusammenzuarbeiten.

Schritt 2: Projektstruktur

Der Standardansatz ist, Quell-Asset-Dateien in einem assets/-Ordner im Projekt-Root zu platzieren und die kompilierten Versionen in www/assets/:

web-project/
├── assets/                   ← Quell-Dateien (SCSS, TypeScript, Quell-Bilder)
│   ├── public/               ← statische Dateien (unverändert kopiert)
│   │   └── favicon.ico
│   ├── images/
│   │   └── logo.png
│   ├── app.js                ← Haupt-Einstiegspunkt
│   └── style.css             ← Ihre Styles
└── www/                      ← öffentliches Verzeichnis (Dokument-Root)
	├── assets/               ← kompilierte Dateien werden hier abgelegt
	└── index.php

Der Ordner assets/ enthält Ihre Quelldateien – den Code, den Sie schreiben. Vite wird diese Dateien verarbeiten und die kompilierten Versionen in www/assets/ ablegen.

Schritt 3: Vite konfigurieren

Erstellen Sie eine Datei vite.config.ts im Projekt-Root. Diese Datei teilt Vite mit, wo Ihre Quelldateien zu finden sind und wohin die kompilierten Dateien abgelegt werden sollen.

Das Nette Vite-Plugin kommt mit intelligenten Standardeinstellungen, die die Konfiguration vereinfachen. Es geht davon aus, dass Ihre Frontend-Quelldateien im Verzeichnis assets/ (Option root) liegen und kompilierte Dateien nach www/assets/ (Option outDir) gehen. Sie müssen nur den Einstiegspunkt angeben:

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

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

Wenn Sie einen anderen Verzeichnisnamen zum Erstellen Ihrer Assets angeben möchten, müssen Sie einige Optionen ändern:

export default defineConfig({
	root: 'assets', // Root-Verzeichnis der Quell-Assets

	build: {
		outDir: '../www/assets',  // wohin kompilierte Dateien gehen
	},

	// ... andere Konfiguration ...
});

Der outDir-Pfad wird relativ zu root betrachtet, weshalb am Anfang ../ steht.

Schritt 4: Nette konfigurieren

Informieren Sie Nette Assets über Vite in Ihrer common.neon:

assets:
	mapping:
		default:
			type: vite      # weist Nette an, den ViteMapper zu verwenden
			path: assets

Schritt 5: Skripte hinzufügen

Fügen Sie diese Skripte zu Ihrer package.json hinzu:

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

Jetzt können Sie:

  • npm run dev – Entwicklungs-Server mit Hot Reloading starten
  • npm run build – optimierte Produktionsdateien erstellen

Einstiegspunkte

Ein Einstiegspunkt ist die Hauptdatei, in der Ihre Anwendung startet. Von dieser Datei importieren Sie andere Dateien (CSS, JavaScript-Module, Bilder), wodurch ein Abhängigkeitsbaum entsteht. Vite folgt diesen Importen und bündelt alles zusammen.

Beispiel-Einstiegspunkt assets/app.js:

// Styles importieren
import './style.css'

// JavaScript-Module importieren
import netteForms from 'nette-forms';
import naja from 'naja';

// Ihre Anwendung initialisieren
netteForms.initOnLoad();
naja.initialize();

Im Template können Sie einen Einstiegspunkt wie folgt einfügen:

{asset 'app.js'}

Nette Assets generiert automatisch alle notwendigen HTML-Tags – JavaScript, CSS und alle anderen Abhängigkeiten.

Mehrere Einstiegspunkte

Größere Anwendungen benötigen oft separate Einstiegspunkte:

export default defineConfig({
	plugins: [
		nette({
			entry: [
				'app.js',      // öffentliche Seiten
				'admin.js',    // Admin-Panel
			],
		}),
	],
});

Verwenden Sie sie in verschiedenen Templates:

{* Auf öffentlichen Seiten *}
{asset 'app.js'}

{* Im Admin-Panel *}
{asset 'admin.js'}

Wichtig: Quell- vs. kompilierte Dateien

Es ist entscheidend zu verstehen, dass Sie in der Produktion nur laden können:

  1. Einstiegspunkte, die in entry definiert sind
  2. Dateien aus dem Verzeichnis assets/public/

Sie können nicht beliebige Dateien aus assets/ mit {asset} laden – nur Assets, die von JavaScript- oder CSS-Dateien referenziert werden. Wenn Ihre Datei nirgendwo referenziert wird, wird sie nicht kompiliert. Wenn Sie Vite auf andere Assets aufmerksam machen möchten, können Sie diese in den public folder verschieben.

Bitte beachten Sie, dass Vite standardmäßig alle Assets, die kleiner als 4KB sind, inline einfügt, sodass Sie diese Dateien nicht direkt referenzieren können. (Siehe Vite-Dokumentation).

{* ✓ Dies funktioniert - es ist ein Einstiegspunkt *}
{asset 'app.js'}

{* ✓ Dies funktioniert - es ist in assets/public/ *}
{asset 'favicon.ico'}

{* ✗ Dies funktioniert nicht - zufällige Datei in assets/ *}
{asset 'components/button.js'}

Entwicklungsmodus

Der Entwicklungsmodus ist völlig optional, bietet aber erhebliche Vorteile, wenn er aktiviert ist. Der Hauptvorteil ist Hot Module Replacement (HMR) – sehen Sie Änderungen sofort, ohne den Anwendungszustand zu verlieren, was die Entwicklungserfahrung viel reibungsloser und schneller macht.

Vite ist ein modernes Build-Tool, das die Entwicklung unglaublich schnell macht. Im Gegensatz zu traditionellen Bundlern serviert Vite Ihren Code während der Entwicklung direkt an den Browser, was einen sofortigen Serverstart unabhängig von der Größe Ihres Projekts und blitzschnelle Updates bedeutet.

Entwicklungs-Server starten

Starten Sie den Entwicklungs-Server:

npm run dev

Sie werden sehen:

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

Lassen Sie dieses Terminal während der Entwicklung geöffnet.

Das Nette Vite-Plugin erkennt automatisch, wann:

  1. Der Vite Dev-Server läuft
  2. Ihre Nette-Anwendung im Debug-Modus ist

Wenn beide Bedingungen erfüllt sind, lädt Nette Assets Dateien vom Vite Dev-Server anstelle des kompilierten Verzeichnisses:

{asset 'app.js'}
{* In der Entwicklung: <script src="http://localhost:5173/app.js" type="module"></script> *}
{* In der Produktion: <script src="/assets/app-4a8f9c7.js" type="module"></script> *}

Keine Konfiguration erforderlich – es funktioniert einfach!

Arbeiten auf verschiedenen Domains

Wenn Ihr Entwicklungs-Server auf etwas anderem als localhost läuft (z.B. myapp.local), könnten Sie auf CORS (Cross-Origin Resource Sharing)-Probleme stoßen. CORS ist eine Sicherheitsfunktion in Webbrowsern, die Anfragen zwischen verschiedenen Domains standardmäßig blockiert. Wenn Ihre PHP-Anwendung auf myapp.local läuft, Vite aber auf localhost:5173, betrachtet der Browser diese als verschiedene Domains und blockiert die Anfragen.

Sie haben zwei Optionen, um dies zu lösen:

Option 1: CORS konfigurieren

Die einfachste Lösung ist, Cross-Origin-Anfragen von Ihrer PHP-Anwendung zuzulassen:

export default defineConfig({
	// ... andere Konfiguration ...

	server: {
		cors: {
			origin: 'http://myapp.local',  // Ihre PHP-App-URL
		},
	},
});

Option 2: Vite auf Ihrer Domain ausführen

Die andere Lösung ist, Vite auf derselben Domain wie Ihre PHP-Anwendung laufen zu lassen.

export default defineConfig({
	// ... andere Konfiguration ...

	server: {
		host: 'myapp.local',  // wie Ihre PHP-App
	},
});

Tatsächlich müssen Sie auch in diesem Fall CORS konfigurieren, da der Dev-Server auf demselben Hostnamen, aber auf einem anderen Port läuft. In diesem Fall wird CORS jedoch automatisch vom Nette Vite-Plugin konfiguriert.

HTTPS-Entwicklung

Wenn Sie unter HTTPS entwickeln, benötigen Sie Zertifikate für Ihren Vite-Entwicklungs-Server. Der einfachste Weg ist die Verwendung eines Plugins, das Zertifikate automatisch generiert:

npm install -D vite-plugin-mkcert

So konfigurieren Sie es in vite.config.ts:

import mkcert from 'vite-plugin-mkcert';

export default defineConfig({
	// ... andere Konfiguration ...

	plugins: [
		mkcert(),  // generiert Zertifikate automatisch und aktiviert https
		nette(),
	],
});

Beachten Sie, dass Sie, wenn Sie die CORS-Konfiguration (Option 1 von oben) verwenden, die Ursprungs-URL aktualisieren müssen, um https:// anstelle von http:// zu verwenden.

Produktions-Builds

Erstellen Sie optimierte Produktionsdateien:

npm run build

Vite wird:

  • Alle JavaScript und CSS minifizieren
  • Code in optimale Chunks aufteilen
  • Gehashte Dateinamen für Cache-Busting generieren
  • Eine Manifest-Datei für Nette Assets erstellen

Beispielausgabe:

www/assets/
├── app-4f3a2b1c.js       # Ihr Haupt-JavaScript (minifiziert)
├── app-7d8e9f2a.css      # Extrahiertes CSS (minifiziert)
├── vendor-8c4b5e6d.js    # Gemeinsame Abhängigkeiten
└── .vite/
	└── manifest.json     # Mapping für Nette Assets

Die gehashten Dateinamen stellen sicher, dass Browser immer die neueste Version laden.

Public-Ordner

Dateien im Verzeichnis assets/public/ werden ohne Verarbeitung in die Ausgabe kopiert:

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

Referenzieren Sie sie normal:

{* Diese Dateien werden unverändert kopiert *}
<link rel="icon" href={asset 'favicon.ico'}>
<meta property="og:image" content={asset 'images/og-image.jpg'}>

Für öffentliche Dateien können Sie FilesystemMapper-Funktionen verwenden:

assets:
	mapping:
		default:
			type: vite
			path: assets
			extension: [webp, jpg, png]  # Zuerst WebP versuchen
			versioning: true             # Cache-Busting hinzufügen

In der vite.config.ts-Konfiguration können Sie den öffentlichen Ordner mit der Option publicDir ändern.

Dynamische Importe

Vite teilt Code automatisch für optimales Laden auf. Dynamische Importe ermöglichen es Ihnen, Code nur dann zu laden, wenn er tatsächlich benötigt wird, wodurch die anfängliche Bundle-Größe reduziert wird:

// Schwere Komponenten bei Bedarf laden
button.addEventListener('click', async () => {
	let { Chart } = await import('./components/chart.js')
	new Chart(data)
})

Dynamische Importe erstellen separate Chunks, die nur bei Bedarf geladen werden. Dies wird “Code-Splitting” genannt und ist eine der leistungsstärksten Funktionen von Vite. Wenn Sie dynamische Importe verwenden, erstellt Vite automatisch separate JavaScript-Dateien für jedes dynamisch importierte Modul.

Der Tag {asset 'app.js'} lädt diese dynamischen Chunks nicht automatisch vor. Dies ist beabsichtigtes Verhalten – wir möchten keinen Code herunterladen, der möglicherweise nie verwendet wird. Die Chunks werden nur heruntergeladen, wenn der dynamische Import ausgeführt wird.

Wenn Sie jedoch wissen, dass bestimmte dynamische Importe kritisch sind und bald benötigt werden, können Sie diese vorladen:

{* Haupt-Einstiegspunkt *}
{asset 'app.js'}

{* Kritische dynamische Importe vorladen *}
{preload 'components/chart.js'}

Dies weist den Browser an, die Chart-Komponente im Hintergrund herunterzuladen, sodass sie sofort bereit ist, wenn sie benötigt wird.

TypeScript-Unterstützung

TypeScript funktioniert sofort:

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

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

Referenzieren Sie TypeScript-Dateien normal:

{asset 'main.ts'}

Für vollständige TypeScript-Unterstützung installieren Sie es:

npm install -D typescript

Zusätzliche Vite-Konfiguration

Hier sind einige nützliche Vite-Konfigurationsoptionen mit detaillierten Erklärungen:

export default defineConfig({
	// Root-Verzeichnis mit Quell-Assets
	root: 'assets',

	// Ordner, dessen Inhalt unverändert in das Ausgabeverzeichnis kopiert wird
	// Standard: 'public' (relativ zu 'root')
	publicDir: 'public',

	build: {
		// Wohin kompilierte Dateien gelegt werden sollen (relativ zu 'root')
		outDir: '../www/assets',

		// Ausgabeverzeichnis vor dem Build leeren?
		// Nützlich, um alte Dateien von früheren Builds zu entfernen
		emptyOutDir: true,

		// Unterverzeichnis innerhalb von outDir für generierte Chunks und Assets
		// Dies hilft, die Ausgabestruktur zu organisieren
		assetsDir: 'static',

		rollupOptions: {
			// Einstiegspunkt(e) - kann eine einzelne Datei oder ein Array von Dateien sein
			// Jeder Einstiegspunkt wird zu einem separaten Bundle
			input: [
				'app.js',      // Hauptanwendung
				'admin.js',    // Admin-Panel
			],
		},
	},

	server: {
		// Host, an den der Dev-Server gebunden werden soll
		// Verwenden Sie '0.0.0.0', um im Netzwerk sichtbar zu sein
		host: 'localhost',

		// Port für den Dev-Server
		port: 5173,

		// CORS-Konfiguration für Cross-Origin-Anfragen
		cors: {
			origin: 'http://myapp.local',
		},
	},

	css: {
		// CSS-Sourcemaps in der Entwicklung aktivieren
		devSourcemap: true,
	},

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

Das war's! Sie haben jetzt ein modernes Build-System, das in Nette Assets integriert ist.

Version: 1.0