Інтеграція Vite
Сучасні JavaScript-додатки вимагають складних інструментів збірки. Nette Assets надає першокласну інтеграцію з Vite, інструментом збірки фронтенду нового покоління. Отримайте блискавично швидку розробку з Hot Module Replacement (HMR) та оптимізовані виробничі збірки без проблем з конфігурацією.
- Нульова конфігурація – автоматичний міст між Vite та PHP-шаблонами
- Повне управління залежностями – один тег обробляє всі активи
- Гаряча заміна модулів – миттєві оновлення JavaScript та CSS
- Оптимізовані виробничі збірки – розділення коду та tree shaking
Nette Assets бездоганно інтегрується з Vite, тому ви отримуєте всі ці переваги, пишучи свої шаблони як зазвичай.
Налаштування Vite
Давайте налаштуємо Vite крок за кроком. Не хвилюйтеся, якщо ви новачок в інструментах збірки – ми все пояснимо!
Крок 1: Встановіть Vite
Спершу встановіть Vite та плагін Nette у вашому проекті:
npm install -D vite @nette/vite-plugin
Це встановлює Vite та спеціальний плагін, який допомагає Vite ідеально працювати з Nette.
Крок 2: Структура проекту
Стандартний підхід полягає в розміщенні вихідних файлів активів у
папці assets/
у корені вашого проекту, а скомпільованих версій – у
www/assets/
:
web-project/ ├── assets/ ← source files (SCSS, TypeScript, source images) │ ├── public/ ← static files (copied as-is) │ │ └── favicon.ico │ ├── images/ │ │ └── logo.png │ ├── app.js ← main entry point │ └── style.css ← your styles └── www/ ← public directory (document root) ├── assets/ ← compiled files will go here └── index.php
Папка assets/
містить ваші вихідні файли – код, який ви пишете. Vite
обробить ці файли та помістить скомпільовані версії в www/assets/
.
Крок 3: Налаштуйте Vite
Створіть файл vite.config.ts
у корені вашого проекту. Цей файл вказує
Vite, де шукати ваші вихідні файли та куди поміщати скомпільовані.
Плагін Nette Vite поставляється з розумними значеннями за замовчуванням,
які спрощують конфігурацію. Він припускає, що ваші вихідні файли
фронтенду знаходяться в каталозі assets/
(опція root
), а
скомпільовані файли потрапляють до www/assets/
(опція outDir
).
Вам потрібно лише вказати точку входу:
import { defineConfig } from 'vite';
import nette from '@nette/vite-plugin';
export default defineConfig({
plugins: [
nette({
entry: 'app.js',
}),
],
});
Якщо ви хочете вказати іншу назву каталогу для збірки ваших активів, вам потрібно буде змінити кілька опцій:
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
– запустити dev-сервер з гарячою перезавантаженням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'}
Важливо: Вихідні проти скомпільованих файлів
Важливо розуміти, що на продакшені ви можете завантажувати лише:
- Точки входу, визначені в
entry
- Файли з каталогу
assets/public/
Ви не можете завантажувати за допомогою {asset}
довільні
файли з assets/
– лише активи, на які посилаються файли JavaScript або
CSS. Якщо на ваш файл ніде немає посилання, він не буде скомпільований.
Якщо ви хочете, щоб Vite знав про інші активи, ви можете перемістити їх до
публічної папки.
Зверніть увагу, що за замовчуванням Vite вбудовуватиме всі активи розміром менше 4 КБ, тому ви не зможете посилатися на ці файли безпосередньо. (Див. документацію 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'}
Режим розробки
Режим розробки є повністю необов'язковим, але надає значні переваги при увімкненні. Головна перевага – це Гаряча заміна модулів (HMR) – миттєве відображення змін без втрати стану програми, що робить процес розробки набагато плавніше та швидше.
Vite – це сучасний інструмент збірки, який робить розробку неймовірно швидкою. На відміну від традиційних бандлерів, Vite під час розробки подає ваш код безпосередньо в браузер, що означає миттєвий запуск сервера незалежно від розміру вашого проекту та блискавичні оновлення.
Запуск dev-сервера
Запустіть dev-сервер:
npm run dev
Ви побачите:
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
Залишайте цей термінал відкритим під час розробки.
Плагін Nette Vite автоматично виявляє, коли:
- Vite dev-сервер запущений
- Ваш Nette-додаток знаходиться в режимі налагодження
Коли обидві умови виконані, Nette Assets завантажує файли з dev-сервера Vite замість скомпільованого каталогу:
{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> *}
Конфігурація не потрібна – просто працює!
Робота на різних доменах
Якщо ваш dev-сервер працює не на localhost
(наприклад, myapp.local
),
ви можете зіткнутися з проблемами CORS (Cross-Origin Resource Sharing). CORS – це функція
безпеки у веб-браузерах, яка за замовчуванням блокує запити між
різними доменами. Коли ваш PHP-додаток працює на myapp.local
, а Vite – на
localhost:5173
, браузер розглядає їх як різні домени та блокує
запити.
У вас є два варіанти вирішення цієї проблеми:
Варіант 1: Налаштуйте CORS
Найпростіше рішення – дозволити крос-доменні запити з вашого PHP-додатку:
export default defineConfig({
// ... other config ...
server: {
cors: {
origin: 'http://myapp.local', // URL вашого PHP-додатку
},
},
});
Варіант 2: Запустіть Vite на вашому домені
Інше рішення – змусити Vite працювати на тому ж домені, що й ваш PHP-додаток.
export default defineConfig({
// ... other config ...
server: {
host: 'myapp.local', // те саме, що й ваш PHP-додаток
},
});
Насправді, навіть у цьому випадку вам потрібно налаштувати CORS, оскільки dev-сервер працює на тому ж хості, але на іншому порту. Однак у цьому випадку CORS автоматично налаштовується плагіном Nette Vite.
Розробка HTTPS
Якщо ви розробляєте на HTTPS, вам потрібні сертифікати для вашого dev-сервера Vite. Найпростіший спосіб – використовувати плагін, який автоматично генерує сертифікати:
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 зробить:
- Мініфікувати весь JavaScript та CSS
- Розділити код на оптимальні чанки
- Згенерувати хешовані імена файлів для обходу кешу
- Створити файл маніфесту для 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
Хешовані імена файлів гарантують, що браузери завжди завантажують найновішу версію.
Публічна папка
Файли в каталозі 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 автоматично розділяє код для оптимального завантаження. Динамічні імпорти дозволяють завантажувати код лише тоді, коли він дійсно потрібен, зменшуючи початковий розмір бандлу:
// Load heavy components on demand
button.addEventListener('click', async () => {
let { Chart } = await import('./components/chart.js')
new Chart(data)
})
Динамічні імпорти створюють окремі чанки, які завантажуються лише за потреби. Це називається “розділення коду” (code splitting) і є однією з найпотужніших функцій Vite. Коли ви використовуєте динамічні імпорти, Vite автоматично створює окремі файли JavaScript для кожного динамічно імпортованого модуля.
Тег {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.