La misma URL, en local y en el CDN

Escribe un consumidor una sola vez y apúntalo a un Dev Server local o al CDN cambiando un único origen base, y conoce las diferencias que debes esperar.

  • Disponibilidad: Experimental
  • Evidencia: Leído del código fuente
  • Guía práctica

Estado inicial

Desarrollas contra el Dev Server de Packages y publicas en el CDN. Quieres un solo cargador, un solo conjunto de URL y una sola forma de manejar los errores, no una variante de desarrollo y otra de producción.

La regla que lo hace posible: el mismo módulo es la misma ruta relativa y la misma consulta en ambos servicios. Solo cambia el origen base.

Mantén el origen en un solo lugar

Guarda el origen base en la configuración y construye todas las URL a partir de él:

JavaScript
const origin = process.env.MODULES_ORIGIN; // http://localhost:<port> or your CDN origin

const url = new URL('/m/@example/shared@1.0.0/modules/text?target=browser&format=esm', origin);

No bifurques según el entorno en ningún otro lugar. Si te encuentras escribiendo una ruta distinta para producción, detente: una diferencia en la ruta significa que cambió algo más que el origen.

Con un documento de resolución vale lo mismo para una aplicación completa. Sus valores son relativos al origen, así que un mismo documento alimenta un import map local y uno publicado:

JavaScript
resolution.importmap('http://localhost:<port>');
resolution.importmap('<your CDN origin>');

Ambos orígenes también responden la resolución por sí mismos: <origin>/resolution.json?target=…&format=… y <origin>/importmap.json?…. En el CDN el origen es la base de un release, /_r/<release number> en el host de la aplicación. Un proceso de Node.js, un programa de Deno o una página SystemJS que reciben una base o la otra ejecutan el mismo código; consulta Estrategias por entorno.

Durante el desarrollo, usa ambos a la vez

Las fuentes editadas, la File API y HMR se quedan en el Dev Server. Las dependencias externas publicadas vienen del CDN. Por eso un import map de desarrollo combina dos orígenes: tus propios paquetes apuntan al Dev Server, y las dependencias publicadas apuntan al CDN. Cada entrada sigue usando la misma URL relativa que usará después de publicar.

Diferencias que debes esperar

Son deliberadas. Ninguna cambia una URL.

Dev Server CDN
Un módulo cuya salida falta Se compila al solicitarlo 404 OUTPUT_NOT_AVAILABLE; nunca se compila
Fuentes que no compilan 422 BUILD_FAILED con diagnósticos Falla el trabajo de preparación; la entrega no se ve afectada
Salidas esm y system; env=development&min=false con mapa en línea o ninguno, y env=production&min=true para un módulo que compila un condicional de producción Lo que se haya preparado
/styles/, /assets/ Se sirven, compilados al solicitarlos Se sirven cuando se prepararon
/maps/ OUTPUT_NOT_AVAILABLE: los mapas van en línea Se sirven cuando se prepararon y lo permite la política de source maps
/resolution.json, /importmap.json Se calculan a partir del workspace en cada solicitud Se guardan con el release; ninguno en el origen de entrega compartido
Fuentes npm y otros registros, tal como los registró la instalación; las instalaciones desde Git y desde archivos comprimidos son SOURCE_UNSUPPORTED npm, otros registros, commits de Git y digests de archivos comprimidos
Cache-Control no-store public o private con max-age, opcionalmente immutable
Acceso Local Público, o privado con acceso
/session, File API, eventos de actualización No. Son endpoints de desarrollo y no existen en el CDN.

La consecuencia para las opciones: omitir env y min pide los valores predeterminados de publicación, que un Dev Server rechaza con OPTION_UNSUPPORTED. Envía todas las opciones de forma explícita, y haz que tu configuración elija el conjunto de opciones junto con el origen.

Compruébalo

El cliente del inicio rápido envía una solicitud relativa a ambos orígenes y muestra las dos respuestas. Para una comparación estructurada, las herramientas de conformidad de @beyond-js/artifact-api envían la misma solicitud relativa a dos orígenes e informan, aspecto por aspecto, si coinciden el estado, el tipo de medio, el código de error y la forma del validador:

JavaScript
import { Parity } from '@beyond-js/artifact-api/conformance';

const parity = new Parity([development, published], module, options);
const { ok, differences, same, sides } = await parity.compare();

Cache-Control se informa para cada lado y nunca se compara, y los cuerpos se comparan solo cuando lo pides, porque los artefactos de desarrollo y de producción difieren legítimamente.