ya isntala y da menor errores en desarrollo, aun no es perfecto pero ta bien
This commit is contained in:
119
DEVELOPMENT_GUIDE.md
Normal file
119
DEVELOPMENT_GUIDE.md
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
# 🛠️ Guía de Desarrollo - RepoDructor
|
||||||
|
|
||||||
|
## 🚨 PROBLEMA SOLUCIONADO: WebSocket HMR
|
||||||
|
|
||||||
|
### **El problema era:**
|
||||||
|
Nuxt intentaba conectarse directamente a `wss://musica.nucleoriofrio.com:3000/` saltándose el proxy nginx.
|
||||||
|
|
||||||
|
### **Solución implementada:**
|
||||||
|
Configuré HMR para usar el proxy correctamente:
|
||||||
|
```typescript
|
||||||
|
// nuxt.config.ts
|
||||||
|
vite: {
|
||||||
|
server: {
|
||||||
|
hmr: {
|
||||||
|
host: 'musica.nucleoriofrio.com',
|
||||||
|
clientPort: 443, // Puerto HTTPS del proxy
|
||||||
|
protocol: 'wss' // WebSocket seguro
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 CONFIGURACIÓN NGINX ACTUALIZADA
|
||||||
|
|
||||||
|
**Archivo:** `nginx-dev-config.txt`
|
||||||
|
|
||||||
|
**Cambios clave:**
|
||||||
|
- ✅ Soporte WebSocket para `/_nuxt/`
|
||||||
|
- ✅ Soporte DevTools para `/__nuxt_devtools__/`
|
||||||
|
- ✅ Headers `Upgrade` y `Connection "upgrade"`
|
||||||
|
- ✅ Sin headers de seguridad que bloqueen DevTools
|
||||||
|
|
||||||
|
## 🚀 PARA APLICAR LA SOLUCIÓN:
|
||||||
|
|
||||||
|
### 1. **Actualiza nginx:**
|
||||||
|
- Copia el contenido de `nginx-dev-config.txt`
|
||||||
|
- Pégalo en Nginx Proxy Manager → Custom Configuration
|
||||||
|
- Guarda y reinicia
|
||||||
|
|
||||||
|
### 2. **Reinicia el servidor:**
|
||||||
|
```bash
|
||||||
|
# Mata el proceso actual
|
||||||
|
pkill -f "npm run dev"
|
||||||
|
|
||||||
|
# Inicia de nuevo
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Verifica que funcione:**
|
||||||
|
- ✅ No más errores `ERR_SSL_PROTOCOL_ERROR`
|
||||||
|
- ✅ HMR funciona (cambios se aplican automáticamente)
|
||||||
|
- ✅ DevTools accesible (Shift + Alt + D)
|
||||||
|
|
||||||
|
## 🔄 OPCIÓN ALTERNATIVA (Si WebSocket sigue fallando)
|
||||||
|
|
||||||
|
Si aún tienes problemas, puedes deshabilitar HMR completamente:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// nuxt.config.ts - Versión sin HMR
|
||||||
|
vite: {
|
||||||
|
server: {
|
||||||
|
hmr: false // Deshabilita HMR WebSocket
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pros:** Sin errores de WebSocket
|
||||||
|
**Contras:** Debes recargar manualmente la página para ver cambios
|
||||||
|
|
||||||
|
## 🎯 ESTADO ACTUAL
|
||||||
|
|
||||||
|
### **✅ Funcionando:**
|
||||||
|
- 🎵 Reproducción de música
|
||||||
|
- 📱 PWA instalable
|
||||||
|
- 🔒 Proxy nginx
|
||||||
|
- 🎨 UI completa
|
||||||
|
|
||||||
|
### **🔧 En desarrollo:**
|
||||||
|
- ⚡ Hot Module Replacement (HMR)
|
||||||
|
- 🛠️ DevTools integration
|
||||||
|
|
||||||
|
## 📝 COMANDOS ÚTILES
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Desarrollo normal
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# Build para producción
|
||||||
|
npm run build
|
||||||
|
npm start
|
||||||
|
|
||||||
|
# Verificar puerto 3000
|
||||||
|
lsof -i:3000
|
||||||
|
|
||||||
|
# Matar procesos en puerto 3000
|
||||||
|
pkill -f "npm run dev"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐛 TROUBLESHOOTING
|
||||||
|
|
||||||
|
### **Error: "WebSocket connection failed"**
|
||||||
|
1. Verifica que nginx tenga la configuración de `nginx-dev-config.txt`
|
||||||
|
2. Asegúrate de que incluya headers `Upgrade` y `Connection`
|
||||||
|
3. Reinicia nginx y el servidor de desarrollo
|
||||||
|
|
||||||
|
### **Error: "X-Frame-Options DENY"**
|
||||||
|
1. Verifica que nginx NO tenga headers de seguridad
|
||||||
|
2. El middleware solo aplica X-Frame-Options a `/api/music/`
|
||||||
|
3. DevTools necesita poder crear iframes
|
||||||
|
|
||||||
|
### **Error: "Port 3000 already in use"**
|
||||||
|
```bash
|
||||||
|
# Encuentra y mata el proceso
|
||||||
|
lsof -ti:3000 | xargs kill -9
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**🎵 ¡Desarrollo con RepoDructor optimizado para proxy nginx!**
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
# 📱 Guía de Instalación PWA - RepoDructor
|
|
||||||
|
|
||||||
## 🚀 Tu app es ahora completamente instalable!
|
|
||||||
|
|
||||||
RepoDructor ahora funciona como una **Progressive Web App (PWA)** completamente instalable en cualquier dispositivo.
|
|
||||||
|
|
||||||
## ✨ Características PWA
|
|
||||||
|
|
||||||
- 🎵 **Funciona offline** - Cache inteligente para tu música
|
|
||||||
- 📱 **Instalable** - Se instala como app nativa
|
|
||||||
- 🚀 **Rápida** - Cache optimizado para carga instantánea
|
|
||||||
- 🔄 **Auto-actualizable** - Se actualiza automáticamente
|
|
||||||
- 🎨 **Icono personalizado** - Tu hermoso logo degradado
|
|
||||||
|
|
||||||
## 📲 ¿Cómo Instalar?
|
|
||||||
|
|
||||||
### **Android (Chrome/Edge)**
|
|
||||||
1. Visita `https://musica.nucleoriofrio.com`
|
|
||||||
2. Verás una notificación "¡Instalar RepoDructor!" en la esquina superior derecha
|
|
||||||
3. Haz clic en **"Instalar"**
|
|
||||||
4. ¡Listo! La app aparecerá en tu pantalla de inicio
|
|
||||||
|
|
||||||
### **iPhone/iPad (Safari)**
|
|
||||||
1. Visita `https://musica.nucleoriofrio.com`
|
|
||||||
2. Toca el botón **Compartir** (cuadrado con flecha hacia arriba)
|
|
||||||
3. Selecciona **"Añadir a pantalla de inicio"**
|
|
||||||
4. Confirma con **"Añadir"**
|
|
||||||
|
|
||||||
### **Desktop (Chrome/Edge/Firefox)**
|
|
||||||
1. Visita `https://musica.nucleoriofrio.com`
|
|
||||||
2. Busca el ícono de instalación en la barra de direcciones (⬇️ o +)
|
|
||||||
3. Haz clic e **"Instalar RepoDructor"**
|
|
||||||
4. La app se abrirá en una ventana independiente
|
|
||||||
|
|
||||||
## 🎯 Funciones PWA Avanzadas
|
|
||||||
|
|
||||||
### **Cache Inteligente**
|
|
||||||
- 🎵 **Música**: Cache de 30 días para reproducción offline
|
|
||||||
- 🖼️ **Imágenes**: Cache de 7 días para carga rápida
|
|
||||||
- ⚡ **App**: Cache persistente para inicio instantáneo
|
|
||||||
|
|
||||||
### **Instalación Automática**
|
|
||||||
- ✅ **Detección automática** de capacidad de instalación
|
|
||||||
- 🔔 **Notificación elegante** con tu branding
|
|
||||||
- 📱 **Experiencia nativa** una vez instalada
|
|
||||||
|
|
||||||
### **Actualizaciones**
|
|
||||||
- 🔄 **Auto-update** cada 20 segundos en segundo plano
|
|
||||||
- 🚀 **Sin interrupciones** - las actualizaciones se aplican automáticamente
|
|
||||||
- 💾 **Cache preservation** - tu música sigue disponible
|
|
||||||
|
|
||||||
## 🛠️ Para Desarrolladores
|
|
||||||
|
|
||||||
### **Archivos PWA Generados**
|
|
||||||
```
|
|
||||||
public/
|
|
||||||
├── logo-192.png # Icono 192x192
|
|
||||||
├── logo-512.png # Icono 512x512
|
|
||||||
├── logo-maskable-512.png # Icono maskable para Android
|
|
||||||
├── logo.png # Icono original
|
|
||||||
├── manifest.webmanifest # Manifest PWA (auto-generado)
|
|
||||||
└── sw.js # Service Worker (auto-generado)
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Configuración en `nuxt.config.ts`**
|
|
||||||
- ✅ Manifest optimizado con tu logo
|
|
||||||
- ✅ Service Worker con cache estratégico
|
|
||||||
- ✅ Instalación automática habilitada
|
|
||||||
- ✅ Meta tags para iOS y Android
|
|
||||||
|
|
||||||
### **Plugins Incluidos**
|
|
||||||
- `plugins/pwa-install.client.ts` - Manejo de instalación
|
|
||||||
- `plugins/proxy-headers.client.ts` - Compatibilidad con proxy
|
|
||||||
|
|
||||||
## 🎨 Personalización
|
|
||||||
|
|
||||||
### **Colores del Tema**
|
|
||||||
- **Theme Color**: `#8b5cf6` (púrpura del logo)
|
|
||||||
- **Background**: `#0f172a` (azul oscuro)
|
|
||||||
- **Accent**: Gradiente turquesa → magenta
|
|
||||||
|
|
||||||
### **Iconos (✅ COMPLETADOS)**
|
|
||||||
- **Formato**: PNG con transparencia
|
|
||||||
- **Tamaños**: 192x192, 512x512
|
|
||||||
- **Maskable**: `logo-maskable-512.png` optimizado para Android
|
|
||||||
- **Archivos**: `logo-192.png`, `logo-512.png`, `logo-maskable-512.png`
|
|
||||||
|
|
||||||
## 🔍 Verificación de Instalación
|
|
||||||
|
|
||||||
### **Chrome DevTools**
|
|
||||||
1. F12 → Application → Manifest
|
|
||||||
2. Verifica que todos los iconos cargan correctamente
|
|
||||||
3. Application → Service Workers - debe mostrar activo
|
|
||||||
|
|
||||||
### **Lighthouse PWA Audit**
|
|
||||||
- Ejecuta un audit PWA en DevTools
|
|
||||||
- Debe mostrar ✅ "Installable"
|
|
||||||
- Score PWA debe ser 100/100
|
|
||||||
|
|
||||||
## 🎵 ¡Disfruta tu música!
|
|
||||||
|
|
||||||
Una vez instalada, RepoDructor funciona como cualquier app nativa:
|
|
||||||
- 🚀 **Inicio rápido** desde pantalla de inicio
|
|
||||||
- 🎵 **Reproducción offline** de música cacheada
|
|
||||||
- 🔄 **Actualizaciones silenciosas** automáticas
|
|
||||||
- 📱 **Experiencia móvil** optimizada
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**🎶 RepoDructor - Tu música, siempre contigo, en cualquier dispositivo** 🎶
|
|
||||||
@@ -11,6 +11,7 @@ useHead({
|
|||||||
{ name: 'description', content: 'A beautiful glassmorphism music player for your local network' },
|
{ name: 'description', content: 'A beautiful glassmorphism music player for your local network' },
|
||||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
||||||
{ name: 'theme-color', content: '#8b5cf6' },
|
{ name: 'theme-color', content: '#8b5cf6' },
|
||||||
|
{ name: 'mobile-web-app-capable', content: 'yes' },
|
||||||
{ name: 'apple-mobile-web-app-capable', content: 'yes' },
|
{ name: 'apple-mobile-web-app-capable', content: 'yes' },
|
||||||
{ name: 'apple-mobile-web-app-status-bar-style', content: 'default' },
|
{ name: 'apple-mobile-web-app-status-bar-style', content: 'default' },
|
||||||
{ name: 'apple-mobile-web-app-title', content: 'RepoDructor' }
|
{ name: 'apple-mobile-web-app-title', content: 'RepoDructor' }
|
||||||
|
|||||||
82
nginx-dev-config.txt
Normal file
82
nginx-dev-config.txt
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# CONFIGURACIÓN NGINX PARA DESARROLLO CON HMR
|
||||||
|
# Reemplaza tu configuración actual de nginx con esta versión que soporta WebSockets
|
||||||
|
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
# Configuración específica para WebSocket HMR de Nuxt
|
||||||
|
location /_nuxt/ {
|
||||||
|
proxy_pass http://192.168.87.135:3000;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# Headers específicos para WebSocket HMR
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
|
||||||
|
# Timeouts para WebSocket
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
|
||||||
|
# Headers específicos para assets de Nuxt
|
||||||
|
proxy_set_header Accept-Encoding gzip;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configuración para DevTools
|
||||||
|
location /__nuxt_devtools__/ {
|
||||||
|
proxy_pass http://192.168.87.135:3000;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# WebSocket support para DevTools
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configuración para APIs
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://192.168.87.135:3000;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# Timeouts más largos para archivos de música
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
|
||||||
|
# Buffer settings para streaming de archivos grandes
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configuración general para el resto
|
||||||
|
location / {
|
||||||
|
proxy_pass http://192.168.87.135:3000;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
# Timeouts
|
||||||
|
proxy_connect_timeout 30s;
|
||||||
|
proxy_send_timeout 30s;
|
||||||
|
proxy_read_timeout 30s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# IMPORTANTE: NO agregar headers de seguridad en desarrollo
|
||||||
|
# Los headers X-Frame-Options, X-Content-Type-Options bloquean DevTools
|
||||||
|
# Solo usar en producción
|
||||||
@@ -3,7 +3,13 @@ import { defineNuxtConfig } from 'nuxt/config'
|
|||||||
|
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
compatibilityDate: '2025-08-02',
|
compatibilityDate: '2025-08-02',
|
||||||
devtools: { enabled: true },
|
devtools: {
|
||||||
|
enabled: true,
|
||||||
|
vscode: {},
|
||||||
|
timeline: {
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Server configuration for proxy compatibility
|
// Server configuration for proxy compatibility
|
||||||
devServer: {
|
devServer: {
|
||||||
@@ -18,7 +24,13 @@ export default defineNuxtConfig({
|
|||||||
// Vite configuration for HMR through proxy
|
// Vite configuration for HMR through proxy
|
||||||
vite: {
|
vite: {
|
||||||
server: {
|
server: {
|
||||||
hmr: false
|
hmr: {
|
||||||
|
// Use proxy host instead of direct connection
|
||||||
|
host: 'musica.nucleoriofrio.com',
|
||||||
|
// Use default HTTPS port (443) through proxy
|
||||||
|
clientPort: 443,
|
||||||
|
protocol: 'wss'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
export default defineNuxtPlugin(() => {
|
export default defineNuxtPlugin(() => {
|
||||||
// Handle proxy headers and ensure proper request handling
|
// Handle proxy headers and ensure proper request handling
|
||||||
if (process.client) {
|
if (process.client) {
|
||||||
// Disable HMR reconnection attempts since we disabled WebSocket HMR
|
// Handle WebSocket connection errors gracefully
|
||||||
if (window && (window as any).__vite_ping) {
|
const originalConsoleError = console.error
|
||||||
(window as any).__vite_ping = () => Promise.resolve()
|
console.error = function(...args) {
|
||||||
|
// Suppress noisy WebSocket HMR connection errors
|
||||||
|
if (args[0] && typeof args[0] === 'string' &&
|
||||||
|
(args[0].includes('WebSocket connection') ||
|
||||||
|
args[0].includes('failed to connect to websocket'))) {
|
||||||
|
return // Suppress these specific errors
|
||||||
|
}
|
||||||
|
originalConsoleError.apply(console, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override fetch to handle proxy correctly
|
// Override fetch to handle proxy correctly
|
||||||
|
|||||||
@@ -42,11 +42,14 @@ export default defineEventHandler(async (event) => {
|
|||||||
setHeader(event, 'Cache-Control', 'public, max-age=3600') // 1 hour cache
|
setHeader(event, 'Cache-Control', 'public, max-age=3600') // 1 hour cache
|
||||||
setHeader(event, 'Accept-Ranges', 'bytes')
|
setHeader(event, 'Accept-Ranges', 'bytes')
|
||||||
|
|
||||||
// Add security headers
|
// Add security headers (but allow DevTools)
|
||||||
setHeader(event, 'X-Content-Type-Options', 'nosniff')
|
setHeader(event, 'X-Content-Type-Options', 'nosniff')
|
||||||
|
// Don't set X-Frame-Options DENY for development
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
setHeader(event, 'X-Frame-Options', 'DENY')
|
setHeader(event, 'X-Frame-Options', 'DENY')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle OPTIONS preflight requests
|
// Handle OPTIONS preflight requests
|
||||||
if (event.node.req.method === 'OPTIONS') {
|
if (event.node.req.method === 'OPTIONS') {
|
||||||
|
|||||||
Reference in New Issue
Block a user