Primeros pasos
Esta página construye una shell con dos micro apps: una página de inicio y un dashboard. Registrarás las apps, dejarás que el router las monte y enviarás nuevas props a una app montada.
Instalación
Instala el paquete paraguas. Contiene el orquestador, el router, el loader, el event bus y el sandbox:
pnpm add tuvix.jsAñade un adaptador por cada framework que usen tus micro apps:
pnpm add @tuvix.js/react react react-dom
pnpm add @tuvix.js/vue vue
pnpm add @tuvix.js/svelte svelte
pnpm add @tuvix.js/angular @angular/core @angular/common @angular/platform-browserGenera un proyecto
create-tuvix-app crea un proyecto de shell o de micro app que depende de los paquetes 0.5:
npx create-tuvix-app my-shell --template shell
npx create-tuvix-app my-dashboard --template react-appPlantillas: shell, react-app, vue-app, svelte-app, angular-app, vanilla-app. Pasa --example <name> para copiar en su lugar uno de los ejemplos del repositorio.
Construye una shell
La shell controla el layout de la página y decide qué app va en cada sitio. Dale un elemento contenedor:
<nav>
<a href="/">Home</a>
<a href="/dashboard">Dashboard</a>
</nav>
<main id="app"></main>
<script type="module" src="/src/main.ts"></script>Después crea el orquestador, registra las apps e inícialo:
// src/main.ts
import { createOrchestrator, interceptLinks, matchPath } from 'tuvix.js';
const orchestrator = createOrchestrator({
router: { mode: 'history', routes: [] },
});
orchestrator.register({
name: 'home',
entry: () => import('./apps/home'),
container: '#app',
// '/' alone would match every path; `end: true` makes it exact.
activeWhen: (path) => matchPath('/', path, { end: true }).matched,
});
orchestrator.register({
name: 'dashboard',
entry: {
scripts: ['https://cdn.example.com/dashboard/main.js'],
styles: ['https://cdn.example.com/dashboard/main.css'],
type: 'module',
},
container: '#app',
activeWhen: '/dashboard/*',
props: { user: 'Guest' },
});
// Turn <a href> clicks into router navigations instead of page loads.
interceptLinks({ navigate: (path) => orchestrator.navigateTo(path) });
await orchestrator.start();Qué ocurre:
start()lee la ruta actual y monta cada app cuyoactiveWhencoincide.- Un clic en
<a href="/dashboard">llama anavigateTo('/dashboard'). El router añade la URL al historial, y el orquestador desmontahomey después montadashboard. - El primer montaje de
dashboardcarga su script y su hoja de estilo. Los montajes posteriores reutilizan el módulo cargado.
El router nunca intercepta clics por sí solo. Sin interceptLinks, un clic en un enlace recarga la página, y el orquestador monta la app correcta en la nueva carga.
Escribe una micro app
Una micro app es un objeto con mount y unmount. defineMicroApp comprueba la forma y registra el módulo con su nombre, para que el loader pueda encontrarlo después de que se ejecute el script:
// apps/home.ts
import { defineMicroApp } from 'tuvix.js';
export default defineMicroApp({
name: 'home',
mount({ container, props }) {
const title = document.createElement('h1');
title.textContent = `Welcome, ${String(props?.user ?? 'Guest')}`;
container.replaceChildren(title);
},
update({ props, container }) {
const title = container?.querySelector('h1');
if (title) title.textContent = `Welcome, ${String(props.user ?? 'Guest')}`;
},
unmount({ container }) {
container.replaceChildren();
},
});El name que pasas a defineMicroApp debe ser igual al nombre que registras en la shell. El loader busca el módulo por ese nombre.
Usa un adaptador de framework
Los adaptadores crean el mismo módulo a partir de un componente raíz. Lo registran, mantienen una instancia del framework por contenedor y despachan eventos de ciclo de vida.
// dashboard/src/main.tsx
import { createReactMicroApp } from '@tuvix.js/react';
function Dashboard({ user }: { user: string }) {
return <h1>Dashboard for {user}</h1>;
}
export default createReactMicroApp({ name: 'dashboard', App: Dashboard });// settings/src/main.ts
import { createVueMicroApp } from '@tuvix.js/vue';
import Settings from './Settings.vue';
export default createVueMicroApp({ name: 'settings', App: Settings });Páginas por framework: React, Vue, Svelte, Angular.
Haz el build de cada micro app como un bundle de módulos ES y súbelo. Un build de librería de Vite funciona:
// dashboard/vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
build: {
lib: { entry: 'src/main.tsx', formats: ['es'], fileName: 'main' },
},
});La salida ES de Vite termina en .js, que el loader trata como un script clásico salvo que el entry indique type: 'module'. Mantén type: 'module' en el entry de la shell, como arriba.
Actualiza props en tiempo de ejecución
import { createOrchestrator } from 'tuvix.js';
const orchestrator = createOrchestrator();
await orchestrator.updateAppProps('dashboard', { user: 'Yasin' });updateAppProps fusiona las nuevas props con las registradas. Si la app está montada y tiene update, el orquestador la llama con las props fusionadas y la app se vuelve a renderizar en su sitio. Si la app no está montada, el orquestador guarda las props para el siguiente montaje.
Lo que la shell no hace
- No renderiza tu layout. El propio HTML de la shell contiene los contenedores.
- No comparte instancias de framework entre apps. Dos apps React obtienen dos raíces React.
- No aplica sandbox a JavaScript. Todas las apps se ejecutan en el
windowde la página.
Próximos pasos
- Arquitectura: el camino desde la navegación hasta
mount. - Enrutamiento: patrones de
activeWhen, el router integrado, guards. - Router externo: sigue a TanStack Router o React Router.
- Islas SSR: renderiza micro apps en el servidor dentro de una página React.