Integração com Vite
Aplicações JavaScript modernas exigem ferramentas de construção sofisticadas. Nette Assets oferece integração de primeira classe com Vite, a ferramenta de construção frontend de próxima geração. Obtenha desenvolvimento ultrarrápido com Hot Module Replacement (HMR) e construções de produção otimizadas com zero complicações de configuração.
- Zero configuração – ponte automática entre Vite e templates PHP
- Gerenciamento completo de dependências – uma tag lida com todos os assets
- Hot Module Replacement – atualizações instantâneas de JavaScript e CSS
- Construções de produção otimizadas – code splitting e tree shaking
Nette Assets se integra perfeitamente com Vite, para que você obtenha todos esses benefícios enquanto escreve seus templates como de costume.
Configurando o Vite
Vamos configurar o Vite passo a passo. Não se preocupe se você é novo em ferramentas de construção – vamos explicar tudo!
Passo 1: Instalar o Vite
Primeiro, instale o Vite e o plugin Nette em seu projeto:
npm install -D vite @nette/vite-plugin
Isso instala o Vite e um plugin especial que ajuda o Vite a funcionar perfeitamente com o Nette.
Passo 2: Estrutura do Projeto
A abordagem padrão é colocar os arquivos de asset de origem em uma pasta assets/
na raiz do seu projeto, e as
versões compiladas em www/assets/
:
web-project/ ├── assets/ ← arquivos de origem (SCSS, TypeScript, imagens de origem) │ ├── public/ ← arquivos estáticos (copiados como estão) │ │ └── favicon.ico │ ├── images/ │ │ └── logo.png │ ├── app.js ← ponto de entrada principal │ └── style.css ← seus estilos └── www/ ← diretório público (document root) ├── assets/ ← arquivos compilados irão para cá └── index.php
A pasta assets/
contém seus arquivos de origem – o código que você escreve. O Vite processará esses
arquivos e colocará as versões compiladas em www/assets/
.
Passo 3: Configurar o Vite
Crie um arquivo vite.config.ts
na raiz do seu projeto. Este arquivo informa ao Vite onde encontrar seus arquivos
de origem e onde colocar os compilados.
O plugin Nette Vite vem com padrões inteligentes que simplificam a configuração. Ele assume que seus arquivos de origem
frontend estão no diretório assets/
(opção root
) e os arquivos compilados vão para
www/assets/
(opção outDir
). Você só precisa especificar o ponto de
entrada:
import { defineConfig } from 'vite';
import nette from '@nette/vite-plugin';
export default defineConfig({
plugins: [
nette({
entry: 'app.js',
}),
],
});
Se você quiser especificar outro nome de diretório para construir seus assets, precisará alterar algumas opções:
export default defineConfig({
root: 'assets', // diretório raiz dos assets de origem
build: {
outDir: '../www/assets', // onde os arquivos compilados vão
},
// ... outras configurações ...
});
O caminho outDir
é considerado relativo a root
, por isso há ../
no
início.
Passo 4: Configurar o Nette
Informe ao Nette Assets sobre o Vite em seu common.neon
:
assets:
mapping:
default:
type: vite # informa ao Nette para usar o ViteMapper
path: assets
Passo 5: Adicionar scripts
Adicione estes scripts ao seu package.json
:
{
"scripts": {
"dev": "vite",
"build": "vite build"
}
}
Agora você pode:
npm run dev
– iniciar o servidor de desenvolvimento com hot reloadingnpm run build
– criar arquivos de produção otimizados
Pontos de Entrada
Um ponto de entrada é o arquivo principal onde sua aplicação começa. A partir deste arquivo, você importa outros arquivos (CSS, módulos JavaScript, imagens), criando uma árvore de dependências. O Vite segue essas importações e agrupa tudo.
Exemplo de ponto de entrada assets/app.js
:
// Importa estilos
import './style.css'
// Importa módulos JavaScript
import netteForms from 'nette-forms';
import naja from 'naja';
// Inicializa sua aplicação
netteForms.initOnLoad();
naja.initialize();
No template você pode inserir um ponto de entrada da seguinte forma:
{asset 'app.js'}
Nette Assets gera automaticamente todas as tags HTML necessárias – JavaScript, CSS e quaisquer outras dependências.
Múltiplos Pontos de Entrada
Aplicações maiores geralmente precisam de pontos de entrada separados:
export default defineConfig({
plugins: [
nette({
entry: [
'app.js', // páginas públicas
'admin.js', // painel de administração
],
}),
],
});
Use-os em diferentes templates:
{* Em páginas públicas *}
{asset 'app.js'}
{* No painel de administração *}
{asset 'admin.js'}
Importante: Arquivos de Origem vs. Compilados
É crucial entender que em produção você só pode carregar:
- Pontos de entrada definidos em
entry
- Arquivos do diretório
assets/public/
Você não pode carregar usando {asset}
arquivos arbitrários de assets/
– apenas assets
referenciados por arquivos JavaScript ou CSS. Se seu arquivo não for referenciado em nenhum lugar, ele não será compilado. Se
você quiser que o Vite esteja ciente de outros assets, você pode movê-los para a pasta
pública.
Observe que, por padrão, o Vite incorporará todos os assets menores que 4KB, então você não poderá referenciar esses arquivos diretamente. (Consulte a documentação do Vite).
{* ✓ Isso funciona - é um ponto de entrada *}
{asset 'app.js'}
{* ✓ Isso funciona - está em assets/public/ *}
{asset 'favicon.ico'}
{* ✗ Isso não funcionará - arquivo aleatório em assets/ *}
{asset 'components/button.js'}
Modo de Desenvolvimento
O modo de desenvolvimento é completamente opcional, mas oferece benefícios significativos quando ativado. A principal vantagem é o Hot Module Replacement (HMR) – veja as mudanças instantaneamente sem perder o estado da aplicação, tornando a experiência de desenvolvimento muito mais suave e rápida.
Vite é uma ferramenta de construção moderna que torna o desenvolvimento incrivelmente rápido. Ao contrário dos bundlers tradicionais, o Vite serve seu código diretamente para o navegador durante o desenvolvimento, o que significa um início instantâneo do servidor, não importa o tamanho do seu projeto, e atualizações ultrarrápidas.
Iniciando o Servidor de Desenvolvimento
Execute o servidor de desenvolvimento:
npm run dev
Você verá:
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
Mantenha este terminal aberto durante o desenvolvimento.
O plugin Nette Vite detecta automaticamente quando:
- O servidor de desenvolvimento Vite está em execução
- Sua aplicação Nette está em modo de depuração
Quando ambas as condições são atendidas, o Nette Assets carrega os arquivos do servidor de desenvolvimento Vite em vez do diretório compilado:
{asset 'app.js'}
{* Em desenvolvimento: <script src="http://localhost:5173/app.js" type="module"></script> *}
{* Em produção: <script src="/assets/app-4a8f9c7.js" type="module"></script> *}
Nenhuma configuração necessária – simplesmente funciona!
Trabalhando em Diferentes Domínios
Se o seu servidor de desenvolvimento estiver sendo executado em algo diferente de localhost
(como
myapp.local
), você pode encontrar problemas de CORS (Cross-Origin Resource Sharing). CORS é um recurso de
segurança em navegadores da web que bloqueia solicitações entre diferentes domínios por padrão. Quando sua aplicação PHP é
executada em myapp.local
, mas o Vite é executado em localhost:5173
, o navegador os vê como domínios
diferentes e bloqueia as solicitações.
Você tem duas opções para resolver isso:
Opção 1: Configurar CORS
A solução mais simples é permitir solicitações cross-origin de sua aplicação PHP:
export default defineConfig({
// ... outras configurações ...
server: {
cors: {
origin: 'http://myapp.local', // URL da sua aplicação PHP
},
},
});
Opção 2: Executar o Vite em seu domínio
A outra solução é fazer com que o Vite seja executado no mesmo domínio da sua aplicação PHP.
export default defineConfig({
// ... outras configurações ...
server: {
host: 'myapp.local', // o mesmo da sua aplicação PHP
},
});
Na verdade, mesmo neste caso, você precisa configurar o CORS porque o servidor de desenvolvimento é executado no mesmo hostname, mas em uma porta diferente. No entanto, neste caso, o CORS é configurado automaticamente pelo plugin Nette Vite.
Desenvolvimento HTTPS
Se você desenvolve em HTTPS, precisa de certificados para o seu servidor de desenvolvimento Vite. A maneira mais fácil é usar um plugin que gera certificados automaticamente:
npm install -D vite-plugin-mkcert
Veja como configurá-lo em vite.config.ts
:
import mkcert from 'vite-plugin-mkcert';
export default defineConfig({
// ... outras configurações ...
plugins: [
mkcert(), // gera certificados automaticamente e habilita https
nette(),
],
});
Observe que, se você estiver usando a configuração CORS (Opção 1 acima), precisará atualizar a URL de origem para usar
https://
em vez de http://
.
Construções de Produção
Crie arquivos de produção otimizados:
npm run build
O Vite irá:
- Minificar todo o JavaScript e CSS
- Dividir o código em chunks ideais
- Gerar nomes de arquivo com hash para cache-busting
- Criar um arquivo de manifesto para Nette Assets
Exemplo de saída:
www/assets/
├── app-4f3a2b1c.js # Seu JavaScript principal (minificado)
├── app-7d8e9f2a.css # CSS extraído (minificado)
├── vendor-8c4b5e6d.js # Dependências compartilhadas
└── .vite/
└── manifest.json # Mapeamento para Nette Assets
Os nomes de arquivo com hash garantem que os navegadores sempre carreguem a versão mais recente.
Pasta Pública
Os arquivos no diretório assets/public/
são copiados para a saída sem processamento:
assets/
├── public/
│ ├── favicon.ico
│ ├── robots.txt
│ └── images/
│ └── og-image.jpg
├── app.js
└── style.css
Referencie-os normalmente:
{* Estes arquivos são copiados como estão *}
<link rel="icon" href={asset 'favicon.ico'}>
<meta property="og:image" content={asset 'images/og-image.jpg'}>
Para arquivos públicos, você pode usar os recursos do FilesystemMapper:
assets:
mapping:
default:
type: vite
path: assets
extension: [webp, jpg, png] # Tenta WebP primeiro
versioning: true # Adiciona cache-busting
Na configuração vite.config.ts
você pode alterar a pasta pública usando a opção publicDir
.
Importações Dinâmicas
O Vite divide automaticamente o código para carregamento ideal. As importações dinâmicas permitem que você carregue o código apenas quando ele é realmente necessário, reduzindo o tamanho inicial do bundle:
// Carrega componentes pesados sob demanda
button.addEventListener('click', async () => {
let { Chart } = await import('./components/chart.js')
new Chart(data)
})
As importações dinâmicas criam chunks separados que são carregados apenas quando necessário. Isso é chamado de “code splitting” e é um dos recursos mais poderosos do Vite. Quando você usa importações dinâmicas, o Vite cria automaticamente arquivos JavaScript separados para cada módulo importado dinamicamente.
A tag {asset 'app.js'}
não pré-carrega automaticamente esses chunks dinâmicos. Este é um comportamento
intencional – não queremos baixar código que talvez nunca seja usado. Os chunks são baixados apenas quando a importação
dinâmica é executada.
No entanto, se você souber que certas importações dinâmicas são críticas e serão necessárias em breve, você pode pré-carregá-las:
{* Ponto de entrada principal *}
{asset 'app.js'}
{* Pré-carrega importações dinâmicas críticas *}
{preload 'components/chart.js'}
Isso informa ao navegador para baixar o componente do gráfico em segundo plano, para que esteja pronto imediatamente quando necessário.
Suporte a TypeScript
TypeScript funciona de imediato:
// assets/main.ts
interface User {
name: string
email: string
}
export function greetUser(user: User): void {
console.log(`Hello, ${user.name}!`)
}
Referencie arquivos TypeScript normalmente:
{asset 'main.ts'}
Para suporte completo a TypeScript, instale-o:
npm install -D typescript
Configuração Adicional do Vite
Aqui estão algumas opções úteis de configuração do Vite com explicações detalhadas:
export default defineConfig({
// Diretório raiz contendo os assets de origem
root: 'assets',
// Pasta cujo conteúdo é copido para o diretório de saída como está
// Padrão: 'public' (relativo a 'root')
publicDir: 'public',
build: {
// Onde colocar os arquivos compilados (relativo a 'root')
outDir: '../www/assets',
// Esvaziar o diretório de saída antes de construir?
// Útil para remover arquivos antigos de construções anteriores
emptyOutDir: true,
// Subdiretório dentro de outDir para chunks e assets gerados
// Isso ajuda a organizar a estrutura de saída
assetsDir: 'static',
rollupOptions: {
// Ponto(s) de entrada - pode ser um único arquivo ou array de arquivos
// Cada ponto de entrada se torna um bundle separado
input: [
'app.js', // aplicação principal
'admin.js', // painel de administração
],
},
},
server: {
// Host para o qual o servidor de desenvolvimento deve se vincular
// Use '0.0.0.0' para expor à rede
host: 'localhost',
// Porta para o servidor de desenvolvimento
port: 5173,
// Configuração CORS para solicitações cross-origin
cors: {
origin: 'http://myapp.local',
},
},
css: {
// Habilitar sourcemaps CSS em desenvolvimento
devSourcemap: true,
},
plugins: [
nette(),
],
});
É isso! Agora você tem um sistema de construção moderno integrado com Nette Assets.