Capítulo 59 de 456

Vite

Core Idea

Step-by-step migration of an existing Vite + React SPA into Next.js, following the same "SPA first, adopt features incrementally" strategy as the Create React App guide, plus Vite-specific TypeScript and import.meta handling.

Key Concepts

  • tsconfig.json adjustments: remove tsconfig.node.json reference, add ./dist/types/**/*.ts and ./next-env.d.ts to include, add { "name": "next" } to compilerOptions.plugins, set esModuleInterop, jsx: "react-jsx", allowJs, forceConsistentCasingInFileNames, incremental to true.
  • Optional catch-all route ([[...slug]]): same SPA bootstrapping pattern as the CRA guide, entrypoint mimics Vite's main.tsx.
  • import.meta.env support via Turbopack: MODE, DEV, PROD, BASE_URL, SSR work with no changes; BASE_URL reflects Next.js basePath and adds a trailing slash.
  • import.meta.glob: supported natively by Turbopack; Vite's deprecated { as: 'raw' } option must become { query: '?raw' }, matched by a turbopack.rules entry in next.config.ts.
  • Environment variable prefix change: VITE_NEXT_PUBLIC_.
  • Static image imports: same behavior as CRA guide — Vite returns a string URL, Next.js returns an object with .src.

Code Examples

// next.config.ts — handling Vite's ?raw imports under Turbopack
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  turbopack: {
    rules: {
      // Any file imported with `?raw` is loaded as a string
      '*': { condition: { query: '?raw' }, type: 'text' },
    },
  },
}

export default nextConfig
  • O que demonstra: como migrar queries especiais do Vite (?raw, ?url) para o sistema de regras do Turbopack.
// app/[[...slug]]/client.tsx — client-only entrypoint (same pattern as CRA)
'use client'

import React from 'react'
import dynamic from 'next/dynamic'

const App = dynamic(() => import('../../App'), { ssr: false })

export function ClientOnly() {
  return <App />
}
  • O que demonstra: reaproveitamento do app Vite inteiro como client-only durante a migração para SPA no Next.js.

Reference Tables

ViteNext.js equivalente
index.htmlapp/layout.tsx
main.tsxapp/[[...slug]]/page.tsx (+ client.tsx)
VITE_* env varsNEXT_PUBLIC_*
vite.config.ts basePathbasePath em next.config.mjs
import.meta.glob({ as: 'raw' })import.meta.glob({ query: '?raw' }) + regra Turbopack
vite-env.d.tsremovido, next-env.d.ts gerado automaticamente

Anti-patterns

  • Esquecer de remover tsconfig.node.json reference: causa incompatibilidade de tipos com o setup do Next.js.
  • Deixar ?raw/?url sem regra Turbopack: Turbopack não tem handling nativo para essas queries do Vite, precisa de config explícita.
  • Ignorar erros de tipo em .src durante a migração: o guia trata como esperado temporariamente, mas devem ser corrigidos ao final.

Key Takeaways

  1. Estratégia idêntica à migração do CRA: primeiro SPA (output: 'export'), depois App Router incrementalmente.
  2. import.meta.env e import.meta.glob do Vite são suportados nativamente pelo Turbopack, exceto queries ?raw/?url que exigem regra manual.
  3. Ajustes obrigatórios de tsconfig.json são mais extensos que no guia do CRA (9 mudanças específicas).
  4. next.config.mjs (ou .js) substitui vite.config.ts; scripts do package.json trocam para next dev/next build/next start.
  5. Ao final, apagar main.tsx, index.html, vite-env.d.ts, tsconfig.node.json, vite.config.ts e desinstalar dependências do Vite.

Connects To

  • Create React App (ch058): guia irmão, estrutura de passos praticamente idêntica.
  • App Router (ch057): próximo passo após estabilizar como SPA em Next.js.