Inicio › Llevarlo a producción
SSR y precompilación
Renderizado en servidor con hydrate() y compilación de plantillas en el build para enviar solo el runtime.
Renderizado en servidor#
@duvanjamid/angelite/tools/ssr.mjs renderiza un componente en Node (con jsdom, que ya es una dependencia de build): no hay una segunda implementación que mantener, la salida es la que construiría el navegador, con la misma sanitización de URL y el mismo escapado. Las peticiones se encolan, así que dos renderizados a la vez no se pisan.
// servidor (Node)
import { renderPage } from '@duvanjamid/angelite/tools/ssr.mjs';
import { provideRouter } from '@duvanjamid/angelite';
const html = await renderPage(App, {
shell: '<!doctype html><body><!--app--><!--state--><script type="module" src="/client.js"></script></body>',
url: req.url, // ruta y query
setup: () => provideRouter(rutas, { mode: 'history' }), // se ejecuta con el DOM ya disponible
ready: async app => { await app.usuarios.settled; }, // espera a tus datos
state: { usuarios } // llega al cliente como window.__STATE__
});// cliente
import { hydrate } from '@duvanjamid/angelite/hydrate';
hydrate(App, document.getElementById('app'));renderToString(Comp, opciones)devuelve solo el HTML del componente;renderPagerellena un shell (<!--app-->y<!--state-->);serializeState(obj)da JSON seguro para incrustar en un<script>(escapa<,>,&y los separadores de línea).setupcorre antes de montar, con las globales del DOM puestas: ahí se configura el router para que leaurl.readyrecibe la instancia y puede devolver una promesa: es donde esperas a tus datos.
hydrate() sustituye el HTML del servidor por la app viva en la misma tarea, así que no hay parpadeo. No adopta los nodos existentes: el cliente vuelve a renderizar. Ganas contenido visible antes de que llegue el JavaScript y SEO; no ahorras el trabajo de una hidratación completa. Tampoco hay streaming.
Precompilar plantillas#
Por defecto AngeLite compila las plantillas en el navegador: un solo script, sin build. Si te importa cada KB, conviértelas en JavaScript durante el build y envía solo el runtime (sin parser de expresiones ni compilador): unos 6 KB gzip para una app real, algo menos que Preact (6,2 KB).
<!-- counter.ng.html -->
<button (click)="inc()">Clics: {{ count() }}</button>// counter.js
import { signal, component, mount } from '@duvanjamid/angelite/runtime';
import aot from './counter.ng.html'; // compilada por el plugin
class Counter { count = signal(0); inc() { this.count.update(n => n + 1); } }
component(Counter, { aot }); // en lugar de template
mount(Counter, document.body);// build con esbuild
import { aotPlugin } from '@duvanjamid/angelite/tools/aot.mjs';
esbuild.build({ entryPoints: ['counter.js'], bundle: true, minify: true,
plugins: [aotPlugin({ components: ['ui-button'], members: 'auto', check: 'error' })] });
// o con Vite (recarga al editar una plantilla)
import angelite from '@duvanjamid/angelite/tools/vite.mjs';
export default { plugins: [angelite({ components: ['ui-button'], members: 'auto' })] };También hay una CLI: node tools/aot.mjs plantilla.html salida.js --components ui-button,ui-card. Una plantilla precompilada produce exactamente el mismo DOM que la compilada en el navegador (lo comprueban los tests).
El compilador también revisa tus plantillas#
- Elementos desconocidos (
<ui-buton>), pipes que no existen y, conmembers, nombres que el componente no tiene ({{ cuenta() }}cuando solo existecount). members: 'auto'lee los campos y métodos de la clase que está junto a la plantilla (x.ng.html+x.js); también puedes dar la lista.check: 'warn'(por defecto) avisa,'error'detiene el build,falselo desactiva. No comprueba tipos.
Con el runtime solo, importa @duvanjamid/angelite/pipes para los pipes, o usa @duvanjamid/angelite/runtime-plus, que trae portales, @defer y referencias sin el compilador. enableDevWarnings() te avisa si una plantilla necesita uno que falta.
Con la compilación en el navegador, una plantilla es código. Si una plantilla se construye con texto que no controlas, estás ejecutando ese texto. Precompilar elimina el problema por construcción: el navegador solo recibe el resultado.