⚡ Gabriel Caiana
imagem principal do site

Nuxt 4: Nova Estrutura de Diretórios e Guia de Migração


O Nuxt 4 traz uma das mudanças mais significativas de sua história: uma reorganização completa da estrutura de diretórios. A nova estrutura com o diretório app/ não é apenas uma mudança cosmética - é uma reformulação arquitetural que melhora a performance, organização e escalabilidade dos projetos.

🧭 Guia de Navegação Rápida

🏗️ Estrutura e Organização


🔄 Comparação Nuxt 3 vs Nuxt 4

Estrutura Antiga (Nuxt 3)

my-nuxt-app/
├── components/          # Componentes Vue
├── layouts/            # Layouts da aplicação
├── pages/              # Páginas/rotas
├── plugins/            # Plugins Vue
├── middleware/         # Middleware de rotas
├── composables/        # Composables Vue
├── utils/              # Funções utilitárias
├── server/             # API e server handlers
├── public/             # Assets estáticos
├── .nuxt/              # Arquivos gerados
├── app.vue             # Componente raiz
└── nuxt.config.ts      # Configuração

Nova Estrutura (Nuxt 4)

my-nuxt-app/
├── app/                    # 🆕 Novo diretório principal
│   ├── components/         # Componentes Vue
│   ├── layouts/           # Layouts da aplicação
│   ├── pages/             # Páginas/rotas
│   ├── plugins/           # Plugins Vue
│   ├── middleware/        # Middleware de rotas
│   ├── composables/       # Composables Vue
│   ├── utils/             # Funções utilitárias
│   ├── assets/            # 🆕 Assets organizados
│   │   ├── css/           # Estilos
│   │   ├── images/        # Imagens
│   │   └── fonts/         # Fontes
│   └── app.vue           # Componente raiz
├── server/                # API e server handlers
├── shared/                # 🆕 Código compartilhado
├── public/               # Assets estáticos
├── .nuxt/               # Arquivos gerados
└── nuxt.config.ts       # Configuração

🎯 Benefícios da Nova Estrutura

1. Melhor Performance de File Watching

A nova estrutura otimiza as capacidades de file watching do Chokidar, proporcionando uma distinção clara entre código que executa na aplicação.

// nuxt.config.ts - Configuração otimizada
export default defineNuxtConfig({
  // 🆕 Ativa automaticamente a nova estrutura
  future: {
    compatibilityVersion: 4
  },
  
  // 🆕 Melhor organização de assets
  css: [
    '~/app/assets/css/main.css',
    '~/app/assets/css/components.css'
  ],
  
  // 🆕 Auto-imports mais eficientes
  imports: {
    dirs: [
      'app/composables',
      'app/utils',
      'shared/utils'
    ]
  }
})

2. Separação Clara de Responsabilidades

  • app/: Código específico da aplicação
  • server/: Lógica do servidor e APIs
  • shared/: Código compartilhado entre cliente e servidor
  • public/: Assets estáticos públicos

3. Melhor Organização para Projetos Grandes

A estrutura facilita a organização em projetos com múltiplas equipes e funcionalidades complexas.

🚀 Migração Automática

Usando o Comando de Upgrade

# 🆕 Migração automática para Nuxt 4
npx nuxi@latest upgrade --force

# Verificar se a migração foi bem-sucedida
npx nuxi@latest info

O que o Comando Faz Automaticamente

  1. Move diretórios para a nova estrutura app/
  2. Atualiza configurações no nuxt.config.ts
  3. Ajusta imports e referências de caminhos
  4. Verifica compatibilidade de dependências

🔧 Migração Manual

Passo a Passo

# 1. Criar nova estrutura
mkdir app
mkdir shared

# 2. Mover diretórios principais
mv components app/
mv layouts app/
mv pages app/
mv plugins app/
mv middleware app/
mv composables app/
mv utils app/
mv app.vue app/

# 3. Mover assets (se existirem)
mkdir -p app/assets/css
mkdir -p app/assets/images
mkdir -p app/assets/fonts

# 4. Mover arquivos de estilo
mv assets/css/* app/assets/css/ 2>/dev/null || true
mv assets/images/* app/assets/images/ 2>/dev/null || true
mv assets/fonts/* app/assets/fonts/ 2>/dev/null || true

# 5. Limpar diretórios vazios
rmdir assets 2>/dev/null || true

Atualizar Imports

// ❌ Antes (Nuxt 3)
import { useMyComposable } from '~/composables/useMyComposable'
import { formatDate } from '~/utils/date'

// ✅ Depois (Nuxt 4)
import { useMyComposable } from '~/app/composables/useMyComposable'
import { formatDate } from '~/app/utils/date'

// 🆕 Ou usar auto-imports (recomendado)
// Os imports são automáticos baseados na configuração

⚙️ Configuração do Nuxt 4

Configuração Básica

// nuxt.config.ts
export default defineNuxtConfig({
  // 🆕 Ativa a nova estrutura
  future: {
    compatibilityVersion: 4
  },
  
  // 🆕 Configuração de diretórios
  dir: {
    // Diretórios padrão (opcional, já configurado automaticamente)
    pages: 'app/pages',
    components: 'app/components',
    layouts: 'app/layouts',
    plugins: 'app/plugins',
    middleware: 'app/middleware',
    composables: 'app/composables',
    utils: 'app/utils'
  },
  
  // 🆕 Auto-imports otimizados
  imports: {
    dirs: [
      'app/composables',
      'app/utils',
      'shared/utils'
    ]
  },
  
  // 🆕 CSS organizado
  css: [
    '~/app/assets/css/main.css',
    '~/app/assets/css/tailwind.css'
  ]
})

Configuração Avançada

// nuxt.config.ts - Configurações avançadas
export default defineNuxtConfig({
  future: {
    compatibilityVersion: 4
  },
  
  // 🆕 Melhor organização de assets
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@import "~/app/assets/scss/variables.scss";'
        }
      }
    }
  },
  
  // 🆕 Auto-imports com aliases
  imports: {
    dirs: [
      'app/composables',
      'app/utils',
      'shared/utils'
    ],
    global: true
  },
  
  // 🆕 Configuração de build otimizada
  build: {
    transpile: ['vue-toastification']
  }
})

💡 Exemplos Práticos

Exemplo de Organização Otimizada

// app/components/ui/Button.vue
<template>
  <button 
    :class="buttonClasses" 
    @click="handleClick"
  >
    <slot />
  </button>
</template>

<script setup lang="ts">
// 🆕 Auto-import de utils do app/
const { generateButtonClass } = useButtonUtils()

// 🆕 Auto-import de composables
const { trackButtonClick } = useAnalytics()

interface Props {
  variant: 'primary' | 'secondary' | 'danger'
  size: 'sm' | 'md' | 'lg'
  disabled?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  variant: 'primary',
  size: 'md',
  disabled: false
})

const buttonClasses = computed(() => 
  generateButtonClass(props.variant, props.size, props.disabled)
)

const handleClick = () => {
  if (!props.disabled) {
    trackButtonClick(props.variant)
  }
}
</script>

Exemplo de Estrutura de Projeto

// Estrutura recomendada para projetos grandes
my-nuxt-app/
├── app/
│   ├── components/
│   │   ├── ui/           # Componentes base (Button, Input, etc.)
│   │   ├── forms/        # Componentes de formulário
│   │   └── layout/       # Componentes de layout
│   ├── composables/
│   │   ├── useAuth.ts    # Autenticação
│   │   ├── useApi.ts     # API calls
│   │   └── useCache.ts   # Cache management
│   ├── utils/
│   │   ├── date.ts       # Utilitários de data
│   │   ├── validation.ts # Validações
│   │   └── formatting.ts # Formatação
│   └── assets/
│       ├── css/
│       │   ├── main.css
│       │   ├── variables.css
│       │   └── components.css
│       └── images/
├── shared/
│   ├── types/            # Tipos compartilhados
│   ├── constants/        # Constantes
│   └── utils/            # Utilitários compartilhados
└── server/
    ├── api/              # API routes
    ├── middleware/       # Server middleware
    └── plugins/          # Server plugins

🚨 Problemas Comuns e Soluções

1. Imports Quebrados

// ❌ Erro comum após migração
import { something } from '~/components/Something'

// ✅ Solução
import { something } from '~/app/components/Something'

// 🆕 Ou melhor ainda, usar auto-imports
// O componente será importado automaticamente

2. Assets Não Encontrados

// ❌ Caminho antigo
background-image: url('~/assets/images/hero.jpg')

// ✅ Novo caminho
background-image: url('~/app/assets/images/hero.jpg')

3. Configurações de Build

// ❌ Configuração antiga
css: ['~/assets/css/main.css']

// ✅ Nova configuração
css: ['~/app/assets/css/main.css']

🔍 Verificação da Migração

Checklist de Verificação

  • Todos os diretórios foram movidos para app/
  • Imports foram atualizados
  • Assets estão nos caminhos corretos
  • nuxt.config.ts foi atualizado
  • Aplicação inicia sem erros
  • Build funciona corretamente
  • Auto-imports funcionam

Comandos de Verificação

# Verificar estrutura
tree app/ -I node_modules

# Verificar build
npm run build

# Verificar dev
npm run dev

# Verificar tipos
npm run typecheck

🎯 Próximos Passos

Após migrar a estrutura de diretórios, você pode:

  1. Explorar o novo sistema de cache - Leia o artigo sobre Data Fetching e Cache
  2. Aprender sobre Type Safety - Leia o artigo sobre TypeScript
  3. Otimizar performance - Leia o artigo sobre Performance

✨ Conclusão

A nova estrutura de diretórios do Nuxt 4 representa uma evolução significativa na organização de projetos. Embora a migração possa parecer complexa inicialmente, os benefícios em termos de performance, organização e escalabilidade fazem valer a pena o esforço.

A estrutura app/ não é apenas uma mudança cosmética - é uma reformulação arquitetural que prepara seus projetos para o futuro do desenvolvimento web.


🔗 Recursos Oficiais: