Интеграция с Vite
Современные JavaScript-приложения требуют сложных инструментов сборки. Nette Assets обеспечивает первоклассную интеграцию с Vite, инструментом сборки фронтенда нового поколения. Получите молниеносную разработку с горячей заменой модулей (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/ ← исходные файлы (SCSS, TypeScript, исходные изображения) │ ├── public/ ← статические файлы (копируются как есть) │ │ └── favicon.ico │ ├── images/ │ │ └── logo.png │ ├── app.js ← основная точка входа │ └── style.css ← ваши стили └── www/ ← публичный каталог (корневой каталог документа) ├── assets/ ← сюда будут помещены скомпилированные файлы └── 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
– запустить сервер разработки с горячей перезагрузкой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 обслуживает ваш код непосредственно в браузере во время разработки, что означает мгновенный запуск сервера независимо от размера вашего проекта и молниеносные обновления.
Запуск сервера разработки
Запустите сервер разработки:
npm run dev
Вы увидите:
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
Держите этот терминал открытым во время разработки.
Плагин Nette Vite автоматически определяет, когда:
- Сервер разработки Vite запущен
- Ваше приложение Nette находится в режиме отладки
Когда оба условия выполнены, Nette Assets загружает файлы с сервера разработки 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> *}
Никакой настройки не требуется – просто работает!
Работа на разных доменах
Если ваш сервер разработки работает на чем-то другом, кроме
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', // your PHP app URL
},
},
});
Вариант 2: Запустите Vite на своем домене
Другое решение – запустить Vite на том же домене, что и ваше PHP-приложение.
export default defineConfig({
// ... other config ...
server: {
host: 'myapp.local', // same as your PHP app
},
});
На самом деле, даже в этом случае вам нужно настроить CORS, потому что сервер разработки работает на том же имени хоста, но на другом порту. Однако в этом случае CORS автоматически настраивается плагином Nette Vite.
Разработка HTTPS
Если вы разрабатываете по HTTPS, вам нужны сертификаты для вашего сервера разработки 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)
})
Динамические импорты создают отдельные чанки, которые загружаются только при необходимости. Это называется “разделением кода”, и это одна из самых мощных функций 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.