Types

MFEModule

Modulo MFE con lifecycle hooks. Definisce mount, unmount e gli hook opzionali onLoad, onBeforeUnmount, onRouteChange, getViewComponent.

Contratto

import type { Component } from 'vue'

interface MFEModule {
  /** Recupera manifest del microfrontend */
  getManifest(): MFEManifest | Promise<MFEManifest>

  /** Monta il microfrontend nel container DOM fornito */
  mount(container: HTMLElement, context: MFEContext): Promise<void>

  /** Smonta il microfrontend e pulisce risorse */
  unmount(): Promise<void>

  /** Hook opzionale chiamato dopo il caricamento, prima del mount */
  onLoad?(): Promise<void>

  /** Hook opzionale chiamato prima dello smontaggio */
  onBeforeUnmount?(): Promise<void>

  /** Hook opzionale chiamato quando la shell cambia rotta */
  onRouteChange?(path: string): void

  /** Ritorna il componente Vue per una specifica rotta */
  getViewComponent?(path: string): Promise<Component | null>
}

Metodi obbligatori

getManifest()

Ritorna il MFEManifest (sync o async). Viene chiamato dalla shell subito dopo il caricamento per registrare il MFE, costruire il menu e applicare gli stili Tailwind.

getManifest(): MFEManifest {
  return {
    name: 'crm-module',
    version: '1.0.0',
    description: 'Gestione CRM',
    routes: [{ path: '/crm', label: 'CRM' }],
  }
}

mount(container, context)

Monta l'applicazione Vue del MFE nell'elemento DOM container, ricevendo il MFEContext dalla shell.

async mount(container, context) {
  const router = createRouter({
    history: createMemoryHistory(context.basePath),
    routes,
  })

  router.afterEach((to) => context.onNavigate(to.path))

  app = createApp(AppRoot)
  app.use(router)
  app.provide(MFE_CONTEXT_KEY, context)
  app.mount(container)
}
Usa sempre createMemoryHistory, mai createWebHistory: il browser ha una sola History API già usata dalla shell. La navigazione browser-level avviene tramite context.onNavigate(path).

unmount()

Cleanup totale: app.unmount(), distruzione router, rimozione listener, clearInterval/clearTimeout.

async unmount() {
  app?.unmount()
  app = null
  router = null
  // cleanup ulteriore: intervalli, listener globali, ecc.
}
Side-effect non puliti dopo unmount() causano memory leak progressivi e bug di re-mount. Pulisci TUTTO ciò che hai allocato in mount().

Metodi opzionali

onLoad()

Chiamato dal MFELoader subito dopo l'import ESM, prima del primo mount(). Utile per:

  • caricare configurazione async
  • registrare componenti globali in un'app condivisa
  • inizializzare client di terze parti che vivono per tutta la sessione
async onLoad() {
  await preloadTranslations()
  await initAnalytics()
}

onBeforeUnmount()

Chiamato dalla shell immediatamente prima di unmount(). Utile per:

  • prompt "conferma uscita" se ci sono modifiche non salvate
  • flush di buffer / save automatico
  • comunicare la prossima rotta agli altri MFE
async onBeforeUnmount() {
  if (hasUnsavedChanges()) await autoSave()
}

onRouteChange(path)

Chiamato dalla shell quando l'URL cambia ma il MFE non viene smontato (es. SPA navigation interna). Permette al MFE di aggiornare la propria vista senza re-mount.

onRouteChange(path) {
  router?.push(path).catch(() => {/* race con unmount */})
}

getViewComponent(path)

Approccio alternativo al routing classico: la shell chiede al MFE quale componente Vue mostrare per un determinato path, e lo monta direttamente (senza che il MFE abbia un proprio router).

async getViewComponent(path) {
  if (path === '/dashboard') return (await import('./views/Dashboard.vue')).default
  if (path === '/clienti') return (await import('./views/ClientiList.vue')).default
  return null
}

Utile per MFE molto piccoli o per pattern "MFE come libreria di pagine".

Pattern di export

Il MFELoader accetta sia default export sia named exports:

// Pattern 1 — default export (consigliato)
const mfeModule: MFEModule = { /* ... */ }
export default mfeModule

// Pattern 2 — named exports
export const getManifest = () => ({ /* ... */ })
export const mount = async (el, ctx) => { /* ... */ }
export const unmount = async () => { /* ... */ }

Il _validateModule() del loader controlla che getManifest, mount, unmount esistano e siano funzioni; se gli hook opzionali sono presenti ma non sono funzioni, il caricamento fallisce con MFE "..." has invalid optional method "...".

Tipi correlati