Estilos
Cómo Beyond Packages compila y entrega las hojas de estilos de un módulo público: CSS y SCSS con parciales y un tema, Tailwind escaneando solo las fuentes que un módulo declara, seleccionar la hoja de estilos de otro módulo con .css, la hoja de estilos global compartida de un paquete, qué hace una hoja que falla y cómo un cambio llega a una página.
- Disponibilidad: Experimental
- Evidencia: Ejecución registrada
- Guía práctica
Una hoja de estilos por módulo público
Un módulo público compilado por el bundler ts tiene como máximo una hoja de estilos: cada archivo .css y .scss del directorio del módulo se compila dentro de ella, en orden de archivo, con un mapa de código. El código del módulo no los importa. La hoja se entrega junto al código, en /styles/<subpath> del módulo, y la página la enlaza o un widget la adopta en su raíz. Un módulo compilado en el modo de empaquetado de esbuild, en cambio, importa su hoja desde su código y recibe la misma entrega: consulta Tu primera interfaz.
CSS y SCSS, parciales y un tema
Un archivo SCSS se compila con Sass. Un @use o @import relativo se resuelve contra el archivo que importa, así que un parcial del directorio del módulo (_tokens.scss, que no produce hoja propia) o un tema en otro lugar del paquete se vuelve una dependencia del módulo: editarlo recompila la hoja de ese módulo y de ningún otro.
{
"platforms": ["web"],
"entry": "index.ts"
}// The stylesheet of the module: a partial of the module and a theme elsewhere in the package
@use "./tokens";
@use "../theme/palette";
.card {
border: 1px solid palette.$line;
padding: tokens.$space;
}// A partial: included by the stylesheets that use it, it produces no stylesheet of its own
$space: 16px;// The stylesheet of the module is not imported by its code: every .css and .scss file of the module
// directory is compiled into the stylesheet of the module, which a page links or a widget adopts
export const card = (text: string): string => `<div class="card">${text}</div>`;Las referencias url() se dejan como están escritas: declara el archivo en assets del manifiesto para que se sirva con el módulo, y direcciónalo de forma relativa a la fuente.
Un archivo CSS simple pasa por Sass como CSS, que resuelve las importaciones relativas de fuentes Sass e informa errores de sintaxis. Un @import "./file.css" de CSS a un archivo .css se deja al navegador, como hace el propio CSS.
Tailwind, escaneando solo lo que declaras
Una hoja de estilos que importa Tailwind (@import "tailwindcss") se compila con Tailwind CSS 4. Tailwind no escanea nada por sí mismo: el manifiesto del módulo declara las fuentes cuyas clases son candidatas, relativas al módulo, y solo esos archivos se leen.
{
"platforms": ["web", "node"],
"entry": "index.ts",
"widget": {
"element": { "name": "hello-widget", "attrs": ["subject"] }
},
"tailwind": { "sources": ["view.tsx"] }
}/* The stylesheet of the widget: Tailwind utilities for the classes in view.tsx, the theme, and its own rules */
@import "tailwindcss";
@theme {
--color-brand: rgb(30, 64, 175);
}
.greeting {
font-size: 28px;
margin: 0 0 8px;
}
.counter {
background-color: rgb(30, 64, 175);
color: rgb(255, 255, 255);
border: 0;
padding: 8px 12px;
}Agregar una clase como underline a una fuente declarada emite su utilidad; quitar la clase elimina la utilidad de la hoja. Un tema (@theme) puede declararse en la propia hoja o importarse desde un archivo del paquete, que entonces también se vigila. Una utilidad de Tailwind vive en una capa de CSS, así que una regla sin capa de otra hoja para la misma propiedad gana sobre ella, como define la cascada.
La hoja de estilos compartida de un paquete
Un paquete publica una hoja compartida por todos sus widgets exportándola como un módulo público sin código:
{ "exports": { "./global": "./global.css" } }/* The shared stylesheet of the package: every widget of the package adopts it in its own root */
:host {
font-family: system-ui, sans-serif;
}
.card {
border: 1px solid rgb(203, 213, 225);
border-radius: 8px;
}Sus fuentes son el archivo de entrada y lo que importa, compilados por el bundler predeterminado del paquete. Cada widget del paquete la adopta primero en su propio shadow root, antes de su hoja y de las hojas de sus dependencias; el registro del widget lo indica (global: true). No se inyecta en el documento de la página.
Publicar ./global es toda la declaración: no hay otra marca. Preparar un solo widget del paquete para su entrega prepara también la hoja, un widget de otro paquete no la adopta, y un paquete que no la publica no produce ninguna solicitud de ella.
Qué llega a un widget y qué llega a la página
- Un widget adopta, dentro de su shadow root: la hoja compartida de su paquete, su propia hoja y la hoja de cada módulo público que importa y que no es a su vez un widget, de forma transitiva. Un widget anidado es dueño de su propia raíz: el recorrido se detiene en él.
- El documento enlaza las hojas de los módulos a los que llega sin cruzar un widget, como el módulo de entrada de una página. Una hoja alcanzada solo a través de un widget nunca es enlazada por el documento.
- Ninguna regla de un widget llega a la página, y ninguna regla de la página llega a un widget.
Seleccionar la hoja de estilos de otro módulo público
Un import selecciona el JavaScript de un módulo público. Para usar solo la hoja de estilos de otro módulo público, nómbralo con .css:
import '@example/ui/theme.css';Esto selecciona la hoja de estilos del módulo público ./theme de @example/ui, o la subruta literal ./theme.css cuando ese paquete la publica, como hacen los paquetes npm que exportan archivos CSS. Es una relación de estilo, no un import de código: el módulo compilado no importa el código de ./theme, y la hoja de estilos se aplica donde está el módulo, adoptada dentro de la raíz del widget que lo importa, o enlazada por el documento para un módulo fuera de cualquier widget. Nada se aplica por la extensión.
| Diagnóstico | Cuándo |
|---|---|
OUTPUT_NOT_FOUND |
Un módulo que solo es una hoja de estilos importado sin .css (el mensaje nombra el especificador que hay que escribir), o .css de un módulo que no produce hoja de estilos |
OUTPUT_AMBIGUOUS |
El especificador nombra dos módulos públicos distintos: una subruta literal ./theme.css y un módulo ./theme con su propia hoja de estilos |
STYLE_BINDING_UNSUPPORTED |
Se pidió un valor a una hoja de estilos: import sheet from '…css', un import con nombre, o with { type: 'css' } |
Una hoja que falla conserva la página
Un error de sintaxis en una hoja de estilos hace fallar la compilación de su módulo: el módulo queda invalid, su hoja responde 422 BUILD_FAILED con un STYLE_ERROR que nombra el archivo y la posición, y no se publica nada más. Una página que ya cargó el módulo conserva su último estilo bueno; un widget conserva su última hoja adoptada. Corregir el archivo publica la hoja de nuevo y la página la aplica.
Un cambio llega a la página
Cuando una compilación cambia la hoja de estilos de un módulo, el servicio anuncia su nuevo hash. El runtime de desarrollo en la página solicita la nueva hoja y la reemplaza: el documento reemplaza su enlace, y cada widget que había adoptado la hoja adopta la nueva en su raíz, conservando su estado. Dos ediciones guardadas en rápida sucesión terminan en la última. El código de un módulo compilado en el modo de empaquetado de esbuild no se actualiza en el lugar; su hoja de estilos sí.
Siguiente
Dale a un widget sus propios estilos y una dependencia con estilos: Crear un widget Beyond.