Tu primera interfaz

Construye una página web a partir de un módulo público declarado por un module.json, con su propia hoja de estilos, un SVG declarado y mapas de código; sírvela con la línea de comandos de Beyond, mírala en un navegador, cambia su CSS sin recargar y solicita su salida de producción.

  • Disponibilidad: Experimental
  • Evidencia: Ejecución registrada
  • Tutorial

Qué construyes

Una página que dice Hello Beyond! en un encabezado con estilo y un pequeño logotipo. Es un módulo público, @testbed/web-hello/main, declarado por un module.json y compilado en el modo de empaquetado de esbuild. Sin widget, sin framework de vistas, sin compilador propio: un manifiesto, un punto de entrada TypeScript, una hoja de estilos y un recurso declarado.

Declara el paquete y el módulo

El paquete selecciona el bundler esbuild para todos sus módulos y nombra el compilador que ejecuta, el esbuild instalado con la cadena de herramientas:

JSONpackage.json
{
	"name": "@testbed/web-hello",
	"version": "0.1.0",
	"private": true,
	"description": "A manifest-first web module with its own stylesheet and a declared asset, compiled in the esbuild packaging mode",
	"beyond": {
		"modules": ".",
		"bundler": "esbuild"
	},
	"bundlers": {
		"esbuild": {
			"specifier": "@beyond-js/packages/bundlers/esbuild",
			"processors": {
				"bundle": {
					"compiler": "esbuild"
				}
			}
		}
	}
}

El módulo lo declara su manifiesto: dónde se ejecuta, su punto de entrada y los archivos estáticos que puede servir. Nada más lo declara; no hace falta exports.

JSONmodule.json
{
	"platforms": ["web"],
	"entry": "index.ts",
	"assets": ["logo.svg"]
}

Escribe el punto de entrada, la hoja de estilos y el recurso

El punto de entrada importa la hoja de estilos y el logotipo, y pone el saludo en la página. Una vista previa importa el módulo y no llama a nada, así que este código de nivel superior es lo que monta la página:

TypeScriptindex.ts
/**
 * The entry point of `@testbed/web-hello/main`. Importing it puts the greeting on the page: the preview
 * document imports the entry module and calls nothing. The stylesheet the module imports is delivered as a
 * separate resource beside the code, and the logo is a declared static file addressed from the module.
 */
import './styles.css';
import logo from './logo.svg';
import { greeting } from './greeting';

const article = document.createElement('article');
article.className = 'hello';

const title = document.createElement('h1');
title.className = 'greeting';
title.textContent = greeting('Beyond');

const image = document.createElement('img');
image.className = 'logo';
image.alt = 'Beyond';
image.src = logo;

article.append(title, image);
document.body.append(article);

greeting.ts es un archivo interno: se empaqueta dentro del artefacto y no es un módulo público.

TypeScriptgreeting.ts
/**
 * An internal file of the module: it is bundled into the artifact and is not a public module
 */
export const greeting = (subject: string): string => `Hello ${subject}!`;

La hoja de estilos es un archivo CSS común. No se incrusta en el código: se entrega como un recurso aparte junto al módulo, y la página la enlaza.

CSSstyles.css
/* The stylesheet of the module: delivered beside its code, linked by the page, replaced without a reload */
.hello {
	font-family: system-ui, sans-serif;
	padding: 16px;
}

.greeting {
	color: rgb(12, 74, 110);
	font-size: 32px;
}

.logo {
	width: 48px;
	height: 48px;
	display: block;
}

logo.svg es cualquier SVG. Como el manifiesto lo declara en assets, se sirve junto al módulo, e import logo from './logo.svg' da su dirección, relativa al módulo.

Sírvela y mírala

Inicia el servidor de desarrollo desde el directorio del workspace y abre la vista previa:

Shellrun.sh
# From the workspace directory (the one with beyond.json). The toolchain that provides `beyond` is not in a
# public registry: use the installation your Beyond Workspace environment or your team provides.
BEYOND_SERVICE_EXTENSIONS=@beyond-js/packages/development beyond run
# <endpoint> is the address the development server printed when it started. Open <endpoint>/preview/ in a browser.

# The compiled module, with an inline source map that names index.ts and greeting.ts
curl -s "<endpoint>/m/@testbed/[email protected]/modules/main?target=browser&format=esm&env=development&min=false&sourcemap=inline&types=false&css=false"

# Its stylesheet, delivered beside the code and linked by the page
curl -s "<endpoint>/m/@testbed/[email protected]/styles/main?target=browser&format=esm&env=development&min=false&sourcemap=inline&types=false&css=false"

# The declared asset; a file the module does not declare answers 404 OUTPUT_NOT_AVAILABLE
curl -s "<endpoint>/m/@testbed/[email protected]/assets/main/logo.svg"

# The production output: minified, without the development runtime. Production is minified only.
curl -s "<endpoint>/m/@testbed/[email protected]/modules/main?target=browser&format=esm&env=production&min=true&sourcemap=none&types=false&css=false"

La vista previa muestra el encabezado en azul oscuro (rgb(12, 74, 110)) con el logotipo debajo. El documento enlaza la hoja de estilos del módulo en su cabecera, marcada data-beyond-styles="@testbed/[email protected]/main", y registra el runtime de desarrollo, así que lo que edites llega a la página.

Qué entrega cada dirección:

Recurso Qué recibes
El módulo El código compilado con un mapa de código en línea que nombra index.ts y greeting.ts, y el recurso direccionado de forma relativa (../assets/main/logo.svg)
La hoja de estilos El CSS con su propio mapa en línea, como text/css
El recurso El SVG, como image/svg+xml
Un archivo que el módulo no declara, como assets/main/index.ts 404 con el código OUTPUT_NOT_AVAILABLE: nunca se sirve nada no declarado

Cambia el CSS sin recargar

Edita el color de .greeting en styles.css y guarda. El encabezado cambia de color en la página abierta: el servicio anuncia la nueva hoja de estilos, el runtime reemplaza la hoja enlazada y la página no navega. Un valor que hayas puesto en la página (window.sentinel = 42 en la aceptación) sigue ahí, y el encabezado es el mismo nodo del DOM.

Ahora agrega @import "./missing.css"; al inicio del archivo. La compilación falla: el módulo queda invalid, la hoja de estilos responde 422 BUILD_FAILED con un BUNDLE_ERROR que nombra missing.css, y la página conserva el último estilo bueno. Quita la línea y el estilo vuelve.

Usa la salida de producción

El mismo servicio responde el condicional de producción del módulo: minificado, sin runtime de desarrollo y sin mapas de código. Es lo que carga una página que no fue construida con Beyond desde el origen que entrega el módulo:

HTMLproduction.html
<!doctype html>
<html>
<head>
	<meta charset="utf-8">
	<link rel="icon" href="data:,">
	<!-- The production stylesheet and module of the public module, from the origin that delivers it -->
	<link rel="stylesheet" href="<origin>/m/@testbed/[email protected]/styles/main?target=browser&format=esm&env=production&min=true&sourcemap=none&types=false&css=false">
	<script type="module" src="<origin>/m/@testbed/[email protected]/modules/main?target=browser&format=esm&env=production&min=true&sourcemap=none&types=false&css=false"></script>
</head>
<body></body>
</html>

La aceptación sirvió este documento desde un segundo origen y lo cargó en el navegador: el saludo se mostró con su estilo calculado y el logotipo decodificado, y no se solicitó nada del servicio de desarrollo (/events, /u/). Producción es solo minificado: pedir env=production&min=false se rechaza con OPTION_UNSUPPORTED.

Siguiente

Agrega SCSS, Tailwind y una hoja de estilos compartida: Estilos. Construye un widget cuya vista sea un componente React, Vue o Svelte: Crear un widget Beyond.