Inicio rápido

Solicita un módulo público preparado desde un servidor de desarrollo local y desde el CDN con un único cliente, cambiando solo el origen base.

  • Disponibilidad: Experimental
  • Evidencia: Leído del código fuente
  • Tutorial

Objetivo

Vas a enviar una misma solicitud relativa a dos servicios y a comparar las respuestas. Al final habrás visto, en tu propia terminal, que un módulo conserva su dirección cuando pasa del desarrollo al CDN.

Qué necesitas

  • Node.js 22.12 o posterior.
  • Un Dev Server de Packages en ejecución que sirva el paquete que quieres solicitar. Muestra su endpoint cuando está listo; ese endpoint es tu origen de desarrollo.
  • El origen de un CDN, y un release de una aplicación que incluya la misma versión del paquete y esté en estado ready. Cómo preparar uno se explica en la referencia de administración. Este sitio no nombra ninguna dirección pública de CDN.
  • Una solicitud cuyas opciones puedan responder ambos servicios. Esto importa, así que lee primero la sección siguiente.

Elige una solicitud que ambos servicios puedan responder

La dirección de un módulo tiene la misma forma en todas partes:

http://localhost:<port>/m/@example/shared@1.0.0/modules/text?target=browser&format=esm&env=development&min=false&sourcemap=none

http://localhost:<port>
Origen base: lo único que cambias
/m/
Espacio de nombres
@example/shared
Paquete
@1.0.0
Versión exacta
/modules/
Familia de recursos
text
Subruta del módulo público
?target=browser&format=esm&env=development&min=false&sourcemap=none
Opciones

https://cdn.beyondjs.com/m/@example/shared@1.0.0/modules/text?target=browser&format=esm&env=development&min=false&sourcemap=none

https://cdn.beyondjs.com
Origen base: lo único que cambias
/m/
Espacio de nombres
@example/shared
Paquete
@1.0.0
Versión exacta
/modules/
Familia de recursos
text
Subruta del módulo público
?target=browser&format=esm&env=development&min=false&sourcemap=none
Opciones

Los dos servicios no tienen las mismas salidas, y el contrato lo dice abiertamente:

  • El servidor de desarrollo produce salida esm y system con env=development, min=false y un mapa en línea o ninguno, y salida de producción solo para un módulo que compila un condicional de producción. A cualquier otra cosa responde 400 OPTION_UNSUPPORTED. Si omites env y min, estás pidiendo los valores predeterminados de publicación (production, minificado, mapa externo), que un servidor de desarrollo rechaza porque nunca escribe mapas externos.
  • El CDN tiene los conjuntos de opciones que se prepararon para el release. Un conjunto de opciones válido que no se preparó responde 404 OUTPUT_NOT_AVAILABLE, y no se inicia ninguna compilación.

Por eso la misma URL relativa devuelve 200 en ambos orígenes solo cuando el release se preparó con el conjunto de opciones que acepta tu servidor de desarrollo. De lo contrario, uno de los dos responde con el error anterior, y ese es el comportamiento correcto. La referencia de opciones enumera todos los valores.

Ejecuta el cliente

Guarda este archivo como same-url.mjs:

JavaScriptsame-url.mjs
// One relative request, two base origins. Nothing but the origin changes between
// a local development server and the CDN.
const request = process.env.MODULE_REQUEST ?? '/m/@example/shared@1.0.0/modules/text?target=browser&format=esm';

const origins = { development: process.env.DEV_ORIGIN, published: process.env.CDN_ORIGIN };

for (const [name, origin] of Object.entries(origins)) {
	if (!origin) continue;

	const response = await fetch(new URL(request, origin));
	const type = response.headers.get('content-type');

	if (!response.ok) {
		const { error } = await response.json();
		console.log(`${name}: ${response.status} ${error.code}${error.message}`);
		process.exitCode = 1;
		continue;
	}

	const body = await response.text();
	console.log(`${name}: ${response.status} ${type}, ${body.length} characters`);
	console.log(`  ETag: ${response.headers.get('etag')}`);
	console.log(`  Cache-Control: ${response.headers.get('cache-control')}`);
}

Ejecútalo con tus dos orígenes y tu solicitud. Reemplaza el paquete, la versión y la subruta por un módulo público que realmente sirvas:

Shell
DEV_ORIGIN="http://localhost:<port>" \
CDN_ORIGIN="<your CDN origin>" \
MODULE_REQUEST="/m/@example/shared@1.0.0/modules/text?target=browser&format=esm&env=development&min=false&sourcemap=none" \
node same-url.mjs

Revisa el resultado

Cuando ambos servicios tienen la salida, ves dos respuestas 200 con el tipo de medio application/javascript.

Encabezado Desarrollo Publicado
ETag Fuerte, "sha256-…" del cuerpo Fuerte, "sha256-…" del cuerpo
Cache-Control no-store public o private, con max-age, e immutable mientras los bytes de la URL no cambien nunca

La política de caché es la diferencia intencional. Los bytes también pueden diferir, porque un artefacto de desarrollo y uno de producción no son la misma compilación; el contrato no exige cuerpos iguales para compilaciones distintas.

Si un servicio responde con un error, el cliente muestra el estado, el código y el mensaje. Busca el código en Errores.

Lo que no hiciste

No cambiaste la ruta ni la consulta entre las dos solicitudes, no te autenticaste (el módulo es público) y no provocaste ninguna compilación en el CDN. Pedir un módulo que el CDN no tiene habría devuelto OUTPUT_NOT_AVAILABLE las dos veces.

Siguiente paso