Estrategias por entorno
Un modelo de resolución y entrega, consumido de cuatro maneras: navegadores con módulos ES nativos o SystemJS, Node.js mediante BEE Node y Deno mediante su import map, con las actualizaciones de desarrollo que funcionan en todos ellos y las mediciones locales que respaldan los valores predeterminados.
- Disponibilidad: Experimental
- Evidencia: Ejecución registrada
- Explicación
Un modelo
Todo origen del contrato de entrega responde las mismas dos cosas: los módulos en sus direcciones /m/…, y la resolución que indica qué dirección entrega cada especificador público, en /resolution.json y /importmap.json. Un origen es un servidor de desarrollo, un entorno de Workspace o la base de un release del CDN (/_r/<release number>).
Un entorno no necesita una entrega propia. Necesita una forma de consumir esos dos documentos: convertir un especificador simple en una dirección, obtenerla de ese origen y ejecutarla. Esa es la única parte que cambia de un entorno a otro.
Las estrategias
| Entorno | Cómo resuelve | Qué salidas |
|---|---|---|
| Navegador, módulos ES nativos (predeterminado) | Un import map en línea en la página; los módulos inmediatos se precargan | target=browser&format=esm |
| Navegador, SystemJS | SystemJS 6.15.1, guardado con el release como loader.js, que lee un systemjs-importmap |
target=browser&format=system |
| Node.js | El adaptador resolution de BEE Node lee resolution.json de la base |
target=node&format=esm |
| Deno | Deno lee importmap.json de la base de forma nativa |
target=node&format=esm, o salidas de navegador neutrales respecto de la plataforma mediante el mapa de navegador |
Un release elige su cargador de navegador cuando se prepara (loader de la aplicación: esm o system). Node.js y Deno usan el target de backend de la aplicación, cuyas salidas y cuya resolución también guarda un release. Consulta Targets de backend.
Navegadores
Los módulos ES nativos son el predeterminado. El shell de un release incluye en línea su import map con direcciones ligadas al release y anuncia los módulos inmediatos con <link rel="modulepreload">, para que el navegador los obtenga en paralelo. Consulta ESM nativo e import maps.
SystemJS es el modo para entornos sin import maps. El release guarda SystemJS como su propio loader.js, así que ninguna página llega a un origen de terceros. Consulta SystemJS.
En ambos, las hojas de estilos se aplican de forma explícita: el documento las enlaza, un widget las adopta en su shadow root. Consulta Quién aplica una hoja de estilos.
Node.js
BEE Node carga módulos de Beyond en Node.js mediante hooks de módulos. Su adaptador resolution recibe una base, lee <base>resolution.json?target=node&format=esm una vez al iniciar el proceso y resuelve con él cada especificador simple de un módulo servido, ámbitos incluidos:
BEE_URL=https://<application host>/_r/12/ BEE_ADAPTER=resolution BEE_CACHE=.beyond/cache \
node --import @beyond-js/bee-node/register app.mjs- Un módulo se obtiene solo de debajo de la base. Un especificador que el documento no resuelve es un error que nombra el especificador y el importador; un módulo integrado de Node va a Node.
- Tu propio script conserva la resolución de Node para tus paquetes instalados; el documento responde primero.
- Las respuestas se conservan durante el proceso. Con
BEE_CACHE, las respuestasimmutabletambién se guardan en disco y se reutilizan sin solicitud, que es lo que responde la base de un release: un proceso que vuelve a iniciar con la caché caliente no hace ninguna solicitud. Un servidor de desarrollo respondeno-store, así que se le pregunta en cada inicio. - Un saludo inicial que falla detiene el proceso, nombrando el adaptador. Nada recurre a otro adaptador.
Deno
Deno lee directamente el import map de la base:
deno run --allow-import=<application host> \
--import-map='https://<application host>/_r/12/importmap.json?target=node&format=esm' app.mjsSus direcciones son relativas a la URL del mapa, así que Deno solicita cada módulo a la base. Las salidas de target Node se ejecutan, módulos integrados node: incluidos; un módulo neutral respecto de la plataforma de un target de navegador se ejecuta mediante el mapa de navegador (?target=browser&format=esm). Deno necesita --allow-import para el host de entrega.
Durante el desarrollo
Un servidor de desarrollo responde los mismos /resolution.json y /importmap.json, calculados a partir del workspace, y también format=system. Por eso las mismas estrategias funcionan contra él, con las opciones de desarrollo.
El runtime de desarrollo (@beyond-js/local-2026, un nombre provisional) aplica las actualizaciones con un solo mecanismo en los cuatro entornos: reemplaza los módulos internos cuyo hash cambió y conserva el estado de los demás. Cada entorno solo aporta cómo importa una actualización (import() nativo, o el import propio de SystemJS en una página SystemJS) y si tiene un documento para las hojas de estilos.
- De dónde vienen las notificaciones. Por defecto, del flujo de eventos del servicio,
<origin>/events. Cualquier emisor que hable el mismo protocolo de eventos puede reemplazarlo, en otra URL o como un objeto en el mismo proceso; Workspace es uno de esos emisores.local.hmr.notify(event)entrega una notificación a mano. Las actualizaciones en sí siempre se solicitan al origen. - Los fallos conservan el último estado válido. Una fuente que no compila no cambia nada y su corrección se aplica; un código que lanza al evaluarse hace fallar esa actualización y la siguiente lo vuelve a evaluar; una hoja de estilos inválida o que no carga conserva la última válida.
- Un consumidor que perdió eventos queda desactualizado. Después de que el servicio se reinicia, el runtime informa
staley no aplica nada más: reinicia el consumidor, o recarga la página.
Esto se ejecutó en Chrome con módulos ES nativos y con SystemJS, en Node.js mediante BEE Node y en Deno, con el flujo propio del servicio, un emisor externo y notify().
Mediciones
Medido el 2026-09-23 en una máquina de desarrollo con mucha carga compartida, en una red de loopback, con releases preparados por el pipeline real; medianas de cinco ejecuciones. En Chrome se emuló un viaje de ida y vuelta de 40 ms en cada solicitud. Compara las variantes entre sí; no son cifras de un servicio alojado.
| Caso, Chrome, inicio en frío | Listo, sin precarga | Listo, con precarga | Transferido |
|---|---|---|---|
| React, ESM nativo | 244 ms | 147 ms | 233.9 kB |
| React, SystemJS | 247 ms | 148 ms | 453.2 kB |
| Cuatro familias de widgets, ESM nativo | 429 ms | 335 ms | 577.4 kB |
| Cuatro familias de widgets, SystemJS | 432 ms | 345 ms | 981.3 kB |
| Caso, un renderizador de servidor de React | En frío | En caliente |
|---|---|---|
Node.js 22, adaptador resolution de BEE Node |
89 ms, 5 solicitudes | 41 ms, ninguna solicitud |
Deno 2.9.7, --import-map |
55 ms, 5 solicitudes | 19 ms, ninguna solicitud |
Los valores predeterminados se desprenden de ellas:
- La precarga está activada. Anunciar los módulos inmediatos hizo que una página en frío iniciara entre un 23 y un 40 % antes cuando existe un viaje de ida y vuelta; en loopback no costó nada medible.
- Los módulos ES nativos siguen siendo el predeterminado. SystemJS fue igual de rápido aquí, pero transfirió entre 1.7 y 1.9 veces los bytes, porque su conversión reimprime la salida minificada.
- Los import maps van en línea en el shell: de 1.1 a 6.1 kB en estos casos, una solicitud menos que un mapa cargado con
src. - Los procesos de Node.js que inician a menudo usan
BEE_CACHE: una caché caliente inicia sin ninguna solicitud y en la mitad del tiempo.
Otro entorno
Un entorno nuevo es un consumidor nuevo de los mismos dos documentos, no una entrega nueva. Necesita leer resolution.json o importmap.json de un origen, obtener módulos solo de ese origen y ejecutar módulos ES o módulos System.register. Para las actualizaciones de desarrollo, le da al runtime su función de import y, si lo tiene, un documento.