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:
{
"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.
{
"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:
/**
* 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.
/**
* 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.
/* 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:
# 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/web-hello@0.1.0/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/web-hello@0.1.0/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/web-hello@0.1.0/assets/main/logo.svg"
# The production output: minified, without the development runtime. Production is minified only.
curl -s "<endpoint>/m/@testbed/web-hello@0.1.0/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/web-hello@0.1.0/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:
<!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/web-hello@0.1.0/styles/main?target=browser&format=esm&env=production&min=true&sourcemap=none&types=false&css=false">
<script type="module" src="<origin>/m/@testbed/web-hello@0.1.0/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.