Dos formas de servir el frontend
En desarrollo, tu página llega de un servidor local; en producción, de un protocolo interno. Esa única diferencia es el origen de casi todos los fallos que aparecen solo en la versión compilada.
Las dos vías
El origen, que es lo que cambia de verdad
Un motor de navegador organiza casi toda su seguridad alrededor del origen: el trío de esquema, dominio y puerto del que viene una página. Y ese origen es distinto en los dos modos.
En desarrollo tu página viene de http://localhost:1420. En producción, de un esquema propio del framework. Para el motor son dos orígenes distintos, y de ahí salen tres consecuencias concretas:
El almacenamiento no se comparte. Lo que guardes en el almacenamiento local o en la base de datos del navegador durante el desarrollo no está ahí en producción, y viceversa. No es un fallo: son orígenes distintos, y cada origen tiene el suyo. Si tu aplicación guarda algo en el navegador, hay que probarlo en los dos modos.
Las peticiones a otros dominios se comportan distinto. El origen desde el que sale una petición cambia, y con él lo que un servidor remoto ve en la cabecera correspondiente. Una API que acepte peticiones de localhost para desarrollo puede rechazarlas desde el esquema de producción. Es una de las sorpresas más habituales, y es también un argumento más para el nivel 48: haz las peticiones desde Rust, donde no hay origen ni política de mismo origen que valga.
La política de contenido tiene que cubrir los dos. Una política escrita mirando solo el modo de desarrollo puede bloquear en producción, y al revés. El framework añade lo que hace falta para su propio protocolo —esa es la corrección que el nivel 7.4 mencionaba— y el resto es tuyo.
Por qué una ruta absoluta puede fallar
Es el fallo número tres del nivel 5.4, y ahora tiene explicación completa.
<!-- funciona en desarrollo, puede fallar en producción --><img src="/logo.png"><script src="/assets/app.js"></script>Con un servidor HTTP detrás, una barra inicial significa «la raíz de este servidor», y el servidor la resuelve. Con el protocolo interno la raíz existe también, pero la resolución depende del esquema y de la plataforma, y la forma en que muchas herramientas de compilación generan esas rutas asume un despliegue web.
La solución es decirle a tu herramienta que genere rutas relativas. En la mayoría es una sola opción de configuración:
// vite.config.jsexport default { base: './', // rutas relativas, no absolutas build: { outDir: 'dist' },};Y la comprobación de que está bien es directa: abre el HTML compilado y mira si los src y los href empiezan por barra. Si empiezan, todavía no está.
Lo que NO cambia
Vale la pena decirlo explícitamente, porque la gente sospecha de más:
- Los comandos son los mismos. Un comando que funciona en desarrollo funciona compilado.
- Los permisos son los mismos. El manifiesto se genera al compilar en los dos casos.
- El core es el mismo, salvo por el perfil de compilación, que es el nivel siguiente.
- La webview es la misma. El mismo motor del sistema, en los dos modos.
Es decir: cuando algo falla solo en producción, la sospecha correcta es el frontend y su forma de llegar, no el core. Esa heurística sola ahorra la mitad del tiempo de diagnóstico.