Una aplicación web pequeña ya no necesita siempre infraestructura compleja. Los módulos ES y las CDN permiten ejecutar código directamente en el navegador: se publica una página estática y las bibliotecas llegan por red. Veámoslo con un ejemplo.
La aplicación de
demostración es un
chat que vive en el cliente, carga bibliotecas desde
jsDelivr y se comunica con una API externa.
Su index.html está en GitHub Pages.
Una vez publicado un paquete en npm, el navegador puede recibirlo mediante una CDN como jsDelivr o unpkg.
De qué se compone el ejemplo
La interfaz utiliza Vue, Vue Router y Quasar. La navegación es mínima: chat, configuración e información.
En la configuración se eligen modelo e instrucción de sistema. Una clave secreta introducida en el navegador debe considerarse accesible desde ese dispositivo y sus extensiones; para un producto real es preferible un intermediario de servidor con credenciales limitadas, no entregar una clave API permanente al cliente.
index.html
El punto de entrada es muy compacto: enlaza estilos, fuentes, un
importmap y el módulo principal.
<script type="importmap">
{ "imports": {
"vue": "https://cdn.jsdelivr.net/npm/vue@3.4.31/dist/vue.esm-browser.prod.js",
"openai/core": "https://cdn.jsdelivr.net/npm/openai@4.52.2/core.mjs"
} }
</script>
<script type="module">
import app from 'https://cdn.jsdelivr.net/npm/@flancer64/demo-wa-esm-openai@0.1.0/src/App.mjs';
app.mount('#app');
</script>
El importmap ofrece al navegador nombres de importación parecidos a
los de Node. El documento también carga recursos y monta la aplicación
en el elemento de la página.
El paquete de la aplicación
@flancer64/demo-wa-esm-openai
está compuesto por módulos ES. Mod/ contiene modelos de acciones y
Ui/, componentes Vue.
En App.mjs, las versiones ESM de Vue y Vue Router se importan de forma
estática. La versión mostrada de Quasar era una biblioteca UMD, así que
antes de importarla dinámicamente recibe Vue por el objeto global:
import * as Vue from 'https://cdn.jsdelivr.net/npm/vue@3.4.31/dist/vue.esm-browser.prod.js';
window.Vue = Vue;
await import('https://cdn.jsdelivr.net/npm/quasar@2.16.4/dist/quasar.umd.prod.js');
const Quasar = window.Quasar;
Las rutas cargan componentes de forma diferida: el navegador descarga un componente solo al visitar su pantalla.
const routes = [
{ path: '/', component: () => import('./Ui/Route/Chat.mjs') },
{ path: '/config', component: () => import('./Ui/Route/Config.mjs') },
];
Lo que ve el navegador
La pestaña Sources revela que el alojamiento estático entrega únicamente
index.html y estilos; el paquete y las dependencias llegan desde la
CDN. Las rutas no visitadas no cargan sus componentes. Las fuentes e
imágenes también pueden estar en orígenes públicos, y la configuración
del usuario, en almacenamiento local.
Conclusión
El stack actual permite crear y distribuir aplicaciones pequeñas sin servidores virtuales propios: el código y las dependencias pueden publicarse en servicios abiertos. Las CDN aportan buena velocidad y caché en los siguientes arranques.
Los módulos se pueden descargar con la granularidad de la acción de la persona usuaria, sin construir bundles específicos ni hacer tree-shaking de antemano. La contraparte es una cadena de suministro abierta: aumenta el riesgo de código malicioso o cambiado inesperadamente. Fije versiones, evalúe la confianza en paquetes y CDN, use CSP y no guarde secretos importantes en el cliente. Para una aplicación abierta y pequeña este enfoque es práctico; con datos sensibles, los mismos principios ESM se pueden usar desde infraestructura propia.