Ενσωμάτωση Vite

Οι σύγχρονες εφαρμογές JavaScript απαιτούν εξελιγμένα εργαλεία δημιουργίας. Το Nette Assets παρέχει ενσωμάτωση πρώτης κατηγορίας με το Vite, το εργαλείο δημιουργίας frontend επόμενης γενιάς. Αποκτήστε αστραπιαία ανάπτυξη με Hot Module Replacement (HMR) και βελτιστοποιημένες εκδόσεις παραγωγής χωρίς προβλήματα διαμόρφωσης.

  • Μηδενική διαμόρφωση – αυτόματη γέφυρα μεταξύ Vite και προτύπων PHP
  • Πλήρης διαχείριση εξαρτήσεων – μία ετικέτα χειρίζεται όλα τα assets
  • Hot Module Replacement – άμεσες ενημερώσεις JavaScript και CSS
  • Βελτιστοποιημένες εκδόσεις παραγωγής – code splitting και tree shaking

Το Nette Assets ενσωματώνεται απρόσκοπτα με το Vite, οπότε έχετε όλα αυτά τα οφέλη ενώ γράφετε τα πρότυπά σας ως συνήθως.

Ρύθμιση του Vite

Ας ρυθμίσουμε το Vite βήμα προς βήμα. Μην ανησυχείτε αν είστε νέοι στα εργαλεία δημιουργίας – θα εξηγήσουμε τα πάντα!

Βήμα 1: Εγκατάσταση του Vite

Πρώτα, εγκαταστήστε το Vite και το Nette plugin στο έργο σας:

npm install -D vite @nette/vite-plugin

Αυτό εγκαθιστά το Vite και ένα ειδικό plugin που βοηθά το Vite να λειτουργεί τέλεια με το Nette.

Βήμα 2: Δομή Έργου

Η τυπική προσέγγιση είναι να τοποθετήσετε τα αρχεία asset πηγής σε έναν φάκελο assets/ στον ριζικό κατάλογο του έργου σας και τις μεταγλωττισμένες εκδόσεις στο www/assets/:

web-project/
├── assets/                   ← αρχεία πηγής (SCSS, TypeScript, εικόνες πηγής)
│   ├── public/               ← στατικά αρχεία (αντιγράφονται ως έχουν)
│   │   └── favicon.ico
│   ├── images/
│   │   └── logo.png
│   ├── app.js                ← κύριο σημείο εισόδου
│   └── style.css             ← τα στυλ σας
└── www/                      ← δημόσιος κατάλογος (document root)
	├── assets/               ← τα μεταγλωττισμένα αρχεία θα πάνε εδώ
	└── index.php

Ο φάκελος assets/ περιέχει τα αρχεία πηγής σας – τον κώδικα που γράφετε. Το Vite θα επεξεργαστεί αυτά τα αρχεία και θα τοποθετήσει τις μεταγλωττισμένες εκδόσεις στο www/assets/.

Βήμα 3: Διαμόρφωση του Vite

Δημιουργήστε ένα αρχείο vite.config.ts στον ριζικό κατάλογο του έργου σας. Αυτό το αρχείο λέει στο Vite πού να βρει τα αρχεία πηγής σας και πού να τοποθετήσει τα μεταγλωττισμένα.

Το Nette Vite plugin έρχεται με έξυπνες προεπιλογές που κάνουν τη διαμόρφωση απλή. Υποθέτει ότι τα αρχεία πηγής frontend βρίσκονται στον κατάλογο assets/ (επιλογή root) και τα μεταγλωττισμένα αρχεία πηγαίνουν στο www/assets/ (επιλογή outDir). Χρειάζεται μόνο να καθορίσετε το σημείο εισόδου:

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

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

Εάν θέλετε να καθορίσετε άλλο όνομα καταλόγου για να δημιουργήσετε τα assets σας, θα χρειαστεί να αλλάξετε μερικές επιλογές:

export default defineConfig({
	root: 'assets', // root directory of source assets

	build: {
		outDir: '../www/assets',  // where compiled files go
	},

	// ... other config ...
});

Η διαδρομή outDir θεωρείται σχετική με το root, γι' αυτό υπάρχει το ../ στην αρχή.

Βήμα 4: Διαμόρφωση του Nette

Ενημερώστε το Nette Assets για το Vite στο common.neon σας:

assets:
	mapping:
		default:
			type: vite      # tells Nette to use the ViteMapper
			path: assets

Βήμα 5: Προσθήκη σεναρίων

Προσθέστε αυτά τα σενάρια στο package.json σας:

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

Τώρα μπορείτε:

  • npm run dev – εκκίνηση του development server με hot reloading
  • npm run build – δημιουργία βελτιστοποιημένων αρχείων παραγωγής

Σημεία Εισόδου

Ένα σημείο εισόδου είναι το κύριο αρχείο από όπου ξεκινά η εφαρμογή σας. Από αυτό το αρχείο, εισάγετε άλλα αρχεία (CSS, μονάδες JavaScript, εικόνες), δημιουργώντας ένα δέντρο εξαρτήσεων. Το Vite ακολουθεί αυτές τις εισαγωγές και ομαδοποιεί τα πάντα μαζί.

Παράδειγμα σημείου εισόδου assets/app.js:

// Import styles
import './style.css'

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

// Initialize your application
netteForms.initOnLoad();
naja.initialize();

Στο πρότυπο μπορείτε να εισάγετε ένα σημείο εισόδου ως εξής:

{asset 'app.js'}

Το Nette Assets δημιουργεί αυτόματα όλες τις απαραίτητες ετικέτες HTML – JavaScript, CSS και οποιεσδήποτε άλλες εξαρτήσεις.

Πολλαπλά Σημεία Εισόδου

Μεγαλύτερες εφαρμογές συχνά χρειάζονται ξεχωριστά σημεία εισόδου:

export default defineConfig({
	plugins: [
		nette({
			entry: [
				'app.js',      // public pages
				'admin.js',    // admin panel
			],
		}),
	],
});

Χρησιμοποιήστε τα σε διαφορετικά πρότυπα:

{* In public pages *}
{asset 'app.js'}

{* In admin panel *}
{asset 'admin.js'}

Σημαντικό: Αρχεία Πηγής έναντι Μεταγλωττισμένων Αρχείων

Είναι κρίσιμο να κατανοήσετε ότι στην παραγωγή μπορείτε να φορτώσετε μόνο:

  1. Σημεία εισόδου που ορίζονται στο entry
  2. Αρχεία από τον κατάλογο assets/public/

Δεν μπορείτε να φορτώσετε χρησιμοποιώντας {asset} αυθαίρετα αρχεία από το assets/ – μόνο assets που αναφέρονται από αρχεία JavaScript ή CSS. Εάν το αρχείο σας δεν αναφέρεται πουθενά, δεν θα μεταγλωττιστεί. Εάν θέλετε να κάνετε το Vite να γνωρίζει άλλα assets, μπορείτε να τα μετακινήσετε στον δημόσιο φάκελο.

Λάβετε υπόψη ότι από προεπιλογή, το Vite θα ενσωματώσει όλα τα assets μικρότερα από 4KB, οπότε δεν θα μπορείτε να αναφέρετε αυτά τα αρχεία απευθείας. (Δείτε την τεκμηρίωση του Vite).

{* ✓ This works - it's an entry point *}
{asset 'app.js'}

{* ✓ This works - it's in assets/public/ *}
{asset 'favicon.ico'}

{* ✗ This won't work - random file in assets/ *}
{asset 'components/button.js'}

Λειτουργία Ανάπτυξης

Η λειτουργία ανάπτυξης είναι εντελώς προαιρετική, αλλά παρέχει σημαντικά οφέλη όταν είναι ενεργοποιημένη. Το κύριο πλεονέκτημα είναι το Hot Module Replacement (HMR) – δείτε τις αλλαγές άμεσα χωρίς να χάσετε την κατάσταση της εφαρμογής, κάνοντας την εμπειρία ανάπτυξης πολύ πιο ομαλή και ταχύτερη.

Το Vite είναι ένα σύγχρονο εργαλείο δημιουργίας που κάνει την ανάπτυξη απίστευτα γρήγορη. Σε αντίθεση με τους παραδοσιακούς bundlers, το Vite εξυπηρετεί τον κώδικά σας απευθείας στο πρόγραμμα περιήγησης κατά την ανάπτυξη, πράγμα που σημαίνει άμεση εκκίνηση του server ανεξάρτητα από το μέγεθος του έργου σας και αστραπιαίες ενημερώσεις.

Εκκίνηση του Development Server

Εκτελέστε τον development server:

npm run dev

Θα δείτε:

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

Κρατήστε αυτό το τερματικό ανοιχτό κατά την ανάπτυξη.

Το Nette Vite plugin ανιχνεύει αυτόματα όταν:

  1. Ο Vite dev server εκτελείται
  2. Η εφαρμογή Nette σας είναι σε λειτουργία debug

Όταν πληρούνται και οι δύο προϋποθέσεις, το Nette Assets φορτώνει αρχεία από τον Vite dev server αντί από τον μεταγλωττισμένο κατάλογο:

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

Δεν απαιτείται διαμόρφωση – απλά λειτουργεί!

Εργασία σε Διαφορετικούς Τομείς (Domains)

Εάν ο development server σας εκτελείται σε κάτι άλλο εκτός από το localhost (όπως myapp.local), ενδέχεται να αντιμετωπίσετε προβλήματα CORS (Cross-Origin Resource Sharing). Το CORS είναι ένα χαρακτηριστικό ασφαλείας στα προγράμματα περιήγησης ιστού που μπλοκάρει τις αιτήσεις μεταξύ διαφορετικών τομέων από προεπιλογή. Όταν η εφαρμογή PHP σας εκτελείται στο myapp.local αλλά το Vite εκτελείται στο localhost:5173, το πρόγραμμα περιήγησης τα βλέπει ως διαφορετικούς τομείς και μπλοκάρει τις αιτήσεις.

Έχετε δύο επιλογές για να το λύσετε:

Επιλογή 1: Διαμόρφωση CORS

Η απλούστερη λύση είναι να επιτρέψετε αιτήσεις cross-origin από την εφαρμογή PHP σας:

export default defineConfig({
	// ... other config ...

	server: {
		cors: {
			origin: 'http://myapp.local',  // your PHP app URL
		},
	},
});

Επιλογή 2: Εκτελέστε το Vite στον τομέα σας

Η άλλη λύση είναι να κάνετε το Vite να εκτελείται στον ίδιο τομέα με την εφαρμογή PHP σας.

export default defineConfig({
	// ... other config ...

	server: {
		host: 'myapp.local',  // same as your PHP app
	},
});

Πράγματι, ακόμη και σε αυτή την περίπτωση, πρέπει να διαμορφώσετε το CORS επειδή ο dev server εκτελείται στον ίδιο hostname αλλά σε διαφορετικό port. Ωστόσο, σε αυτή την περίπτωση, το CORS διαμορφώνεται αυτόματα από το Nette Vite plugin.

Ανάπτυξη HTTPS

Εάν αναπτύσσετε σε HTTPS, χρειάζεστε πιστοποιητικά για τον Vite development server σας. Ο ευκολότερος τρόπος είναι να χρησιμοποιήσετε ένα plugin που δημιουργεί αυτόματα πιστοποιητικά:

npm install -D vite-plugin-mkcert

Δείτε πώς να το διαμορφώσετε στο vite.config.ts:

import mkcert from 'vite-plugin-mkcert';

export default defineConfig({
	// ... other config ...

	plugins: [
		mkcert(),  // generates certificates automatically and enables https
		nette(),
	],
});

Σημειώστε ότι εάν χρησιμοποιείτε τη διαμόρφωση CORS (Επιλογή 1 από παραπάνω), πρέπει να ενημερώσετε τη διεύθυνση URL προέλευσης για να χρησιμοποιήσετε https:// αντί για http://.

Εκδόσεις Παραγωγής

Δημιουργήστε βελτιστοποιημένα αρχεία παραγωγής:

npm run build

Το Vite θα:

  • Συμπιέσει (minify) όλα τα JavaScript και CSS
  • Χωρίσει τον κώδικα σε βέλτιστα τμήματα (chunks)
  • Δημιουργήσει ονόματα αρχείων με hash για cache-busting
  • Δημιουργήσει ένα αρχείο manifest για το Nette Assets

Παράδειγμα εξόδου:

www/assets/
├── app-4f3a2b1c.js       # Your main JavaScript (minified)
├── app-7d8e9f2a.css      # Extracted CSS (minified)
├── vendor-8c4b5e6d.js    # Shared dependencies
└── .vite/
	└── manifest.json     # Mapping for Nette Assets

Τα ονόματα αρχείων με hash διασφαλίζουν ότι τα προγράμματα περιήγησης φορτώνουν πάντα την τελευταία έκδοση.

Δημόσιος Φάκελος

Τα αρχεία στον κατάλογο assets/public/ αντιγράφονται στην έξοδο χωρίς επεξεργασία:

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

Αναφερθείτε σε αυτά κανονικά:

{* These files are copied as-is *}
<link rel="icon" href={asset 'favicon.ico'}>
<meta property="og:image" content={asset 'images/og-image.jpg'}>

Για δημόσια αρχεία, μπορείτε να χρησιμοποιήσετε τις λειτουργίες του FilesystemMapper:

assets:
	mapping:
		default:
			type: vite
			path: assets
			extension: [webp, jpg, png]  # Try WebP first
			versioning: true             # Add cache-busting

Στη διαμόρφωση vite.config.ts μπορείτε να αλλάξετε τον δημόσιο φάκελο χρησιμοποιώντας την επιλογή publicDir.

Δυναμικές Εισαγωγές

Το Vite χωρίζει αυτόματα τον κώδικα για βέλτιστη φόρτωση. Οι δυναμικές εισαγωγές σάς επιτρέπουν να φορτώνετε κώδικα μόνο όταν είναι πραγματικά απαραίτητος, μειώνοντας το αρχικό μέγεθος του bundle:

// Load heavy components on demand
button.addEventListener('click', async () => {
	let { Chart } = await import('./components/chart.js')
	new Chart(data)
})

Οι δυναμικές εισαγωγές δημιουργούν ξεχωριστά τμήματα (chunks) που φορτώνονται μόνο όταν χρειάζονται. Αυτό ονομάζεται “code splitting” και είναι μία από τις πιο ισχυρές λειτουργίες του Vite. Όταν χρησιμοποιείτε δυναμικές εισαγωγές, το Vite δημιουργεί αυτόματα ξεχωριστά αρχεία JavaScript για κάθε δυναμικά εισαγόμενη ενότητα (module).

Η ετικέτα {asset 'app.js'} δεν προφορτώνει αυτόματα αυτά τα δυναμικά τμήματα. Αυτή είναι σκόπιμη συμπεριφορά – δεν θέλουμε να κατεβάσουμε κώδικα που μπορεί να μην χρησιμοποιηθεί ποτέ. Τα τμήματα κατεβάζονται μόνο όταν εκτελείται η δυναμική εισαγωγή.

Ωστόσο, εάν γνωρίζετε ότι ορισμένες δυναμικές εισαγωγές είναι κρίτιμες και θα χρειαστούν σύντομα, μπορείτε να τις προφορτώσετε:

{* Main entry point *}
{asset 'app.js'}

{* Preload critical dynamic imports *}
{preload 'components/chart.js'}

Αυτό λέει στο πρόγραμμα περιήγησης να κατεβάσει το στοιχείο του γραφήματος στο παρασκήνιο, ώστε να είναι άμεσα διαθέσιμο όταν χρειαστεί.

Υποστήριξη TypeScript

Το TypeScript λειτουργεί άμεσα:

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

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

Αναφερθείτε στα αρχεία TypeScript κανονικά:

{asset 'main.ts'}

Για πλήρη υποστήριξη TypeScript, εγκαταστήστε το:

npm install -D typescript

Πρόσθετη Διαμόρφωση Vite

Ακολουθούν ορισμένες χρήσιμες επιλογές διαμόρφωσης Vite με λεπτομερείς επεξηγήσεις:

export default defineConfig({
	// Root directory containing source assets
	root: 'assets',

	// Folder whose contents are copied to output directory as-is
	// Default: 'public' (relative to 'root')
	publicDir: 'public',

	build: {
		// Where to put compiled files (relative to 'root')
		outDir: '../www/assets',

		// Empty output directory before building?
		// Useful to remove old files from previous builds
		emptyOutDir: true,

		// Subdirectory within outDir for generated chunks and assets
		// This helps organize the output structure
		assetsDir: 'static',

		rollupOptions: {
			// Entry point(s) - can be a single file or array of files
			// Each entry point becomes a separate bundle
			input: [
				'app.js',      // main application
				'admin.js',    // admin panel
			],
		},
	},

	server: {
		// Host to bind the dev server to
		// Use '0.0.0.0' to expose to network
		host: 'localhost',

		// Port for the dev server
		port: 5173,

		// CORS configuration for cross-origin requests
		cors: {
			origin: 'http://myapp.local',
		},
	},

	css: {
		// Enable CSS source maps in development
		devSourcemap: true,
	},

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

Αυτό είναι όλο! Έχετε τώρα ένα σύγχρονο σύστημα δημιουργίας ενσωματωμένο με το Nette Assets.

έκδοση: 1.0