kb.erickguedes.com
Vite: Build Tool do Futuro

Fundamentos e Configuração

Aula 1 de 4

Introdução ao Vite

Vite é uma build tool moderna que substitui Webpack. Seus pilares são:

  • HMR instantâneo: mudanças refletem em milissegundos (não segundos)
  • Dev server nativo em ES modules: sem bundle em desenvolvimento
  • Build otimizado: via Rollup, com treeshaking e code splitting
  • Zero config: funciona out-of-the-box para muitos frameworks
# Criar projeto
npm create vite@latest my-app -- --template react-ts
npm create vite@latest my-app -- --template vue-ts
npm create vite@latest my-app -- --template vanilla-ts

cd my-app
npm install
npm run dev

vite.config.ts

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  plugins: [react()],

  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components')
    }
  },

  css: {
    modules: {
      localsConvention: 'camelCase'
    },
    preprocessorOptions: {
      scss: {
        additionalData: `@import "@/styles/variables.scss";`
      }
    }
  },

  build: {
    outDir: 'dist',
    sourcemap: true,
    minify: 'terser',
    target: 'es2020'
  },

  server: {
    port: 3000,
    open: true,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        secure: false
      }
    }
  }
});

Resolve e Alias

export default defineConfig({
  resolve: {
    alias: {
      '@': '/src',
      '@components': '/src/components',
      '@utils': '/src/utils',
      '@assets': '/src/assets'
    },
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
  }
});
// Uso no código
import Button from '@components/Button';
import { formatDate } from '@utils/date';
import logo from '@assets/logo.svg';

CSS Config

export default defineConfig({
  css: {
    modules: {
      scopeBehaviour: 'local', // local | global
      generateScopedName: '[name]__[local]___[hash:base64:5]'
    },
    preprocessorOptions: {
      scss: {
        additionalData: `$primary-color: #646cff;`
      },
      less: {
        javascriptEnabled: true
      }
    },
    devSourcemap: true,
    lightningcss: false // Habilitar Lightning CSS (experimental)
  }
});

Server Config

export default defineConfig({
  server: {
    port: 3000,
    strictPort: true,  // Fechar se porta ocupada
    host: '0.0.0.0',   // Acessível na rede
    open: '/dashboard', // Abrir rota específica
    cors: true,
    hmr: {
      protocol: 'ws',
      host: 'localhost',
      port: 3001
    },
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      },
      '/ws': {
        target: 'ws://localhost:8080',
        ws: true
      }
    },
    watch: {
      usePolling: true, // Necessário para WSL/Docker
      interval: 100
    }
  }
});

Entry Points (index.html)

Diferente do Webpack, Vite usa o arquivo index.html como entry point.

<!-- index.html -->
<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>
// src/main.tsx
import { createRoot } from 'react-dom/client';
import App from './App';

createRoot(document.getElementById('root')!).render(<App />);

Dependency Pre-bundling

Vite pré-empacota dependências com esbuild para melhor performance.

export default defineConfig({
  optimizeDeps: {
    include: ['lodash-es', 'react-router-dom'],
    exclude: ['large-package'],
    force: true // Forçar re-otimização
  }
});
# Forçar re-otimização manual
npx vite optimize

HMR Instantâneo

Vite implementa HMR via ESM nativo, sem precisar re-empacotar todo o bundle.

// Componente com HMR (React)
import { hot } from 'react-hot-loader'; // Não necessário com @vitejs/plugin-react

// hmr.ts (aceitar HMR manualmente)
if (import.meta.hot) {
  import.meta.hot.accept(() => {
    console.log('Módulo atualizado!');
  });

  import.meta.hot.dispose(() => {
    console.log('Módulo será removido');
  });
}

Lab: Exercício - Configuração Completa

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },
  server: {
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true
      }
    }
  },
  build: {
    outDir: 'dist',
    sourcemap: true
  }
});
# Dev
npm run dev

# Build
npm run build

# Preview (testar build localmente)
npm run preview

Vite usa index.html como entry point, não arquivos JavaScript. O dev server é baseado em ESM nativo, sem bundle. O build usa Rollup com otimizações. HMR instantâneo via ESM + WebSocket.