Types

MFEManifest

Metadata descrittiva del microfrontend esposta alla shell. Nome, versione, descrizione, rotte, componenti, permessi e configurazione tema.

Contratto

interface MFEManifest {
  /** Nome identificativo univoco del microfrontend */
  name: string

  /** Versione semantic (es: "1.2.3") */
  version: string

  /** Descrizione breve del modulo (max 200 caratteri) */
  description: string

  /** Icona PrimeIcons per rappresentazione visiva (es: "pi-users") */
  icon?: string

  /** Rotte esposte dal microfrontend */
  routes: MFERoute[]

  /** Componenti riutilizzabili esposti alla shell e altri MFE */
  components?: MFEComponent[]

  /** Stili personalizzati Tailwind da applicare globalmente */
  tailwindStyles?: MFETailwindStyles

  /** Permessi richiesti per accesso al modulo */
  permissions?: string[]

  /** Configurazione aggiuntiva specifica del MFE */
  meta?: Record<string, unknown>
}

Campi

CampoTipoRequiredDescrizione
namestringID univoco (slug-style, es. crm-module). Usato come chiave cache nel MFELoader e come scope settings
versionstringSemVer (MAJOR.MINOR.PATCH)
descriptionstringEtichetta human-readable, mostrata nel menu settings della shell
iconstringClasse PrimeIcons (pi-...) o Lucide
routesMFERoute[]Rotte esposte (almeno una). Sezione default app; per settings → meta.section: 'settings'
componentsMFEComponent[]Componenti Vue riutilizzabili esposti ad altri MFE
tailwindStylesMFETailwindStylesEstensione tema Tailwind e CSS custom
permissionsstring[]Permessi necessari per accedere al MFE (logica OR)
metaRecord<string, unknown>Campi liberi specifici del progetto

Esempio completo

import type { MFEManifest } from '@pzeta/mfe-contracts'

const manifest: MFEManifest = {
  name: 'crm-module',
  version: '1.2.0',
  description: 'Gestione clienti, ticket e pipeline CRM',
  icon: 'pi-building',
  routes: [
    {
      path: '/crm/dashboard',
      label: 'Dashboard',
      icon: 'pi-chart-line',
      category: 'CRM',
      permission: 'crm.dashboard.read',
      meta: { requiresAuth: true, order: 1 },
    },
    {
      path: '/templates',
      label: 'Template CRM',
      icon: 'pi-file',
      meta: { section: 'settings', order: 5 },
    },
  ],
  components: [
    {
      name: 'ClienteCard',
      description: 'Card riassuntiva di un cliente',
      category: 'Cards',
      props: [{ name: 'cliente', type: 'Cliente', required: true }],
    },
  ],
  permissions: ['crm.read'],
  meta: { team: 'sales-engineering', repo: 'mfe-crm' },
}

Validazione runtime

I manifest provenienti da fonti non trusted (config remota, admin panel, JSON da API) devono essere validati prima dell'uso:

import { validateManifest, isValidManifest } from '@pzeta/mfe-contracts/helpers'

const { valid, errors } = validateManifest(payload)
if (!valid) {
  console.error('Manifest non valido:', errors)
}

// Type guard
if (isValidManifest(payload)) {
  // payload è ora typed come MFEManifest
}

Vedi validateManifest.

Costruzione menu dalla shell

import { buildMenuFromManifest } from '@pzeta/mfe-contracts/helpers'

const appMenu = buildMenuFromManifest(manifest, 'app')
// → MenuGroup[] (raggruppato per route.category, ordinato per route.meta.order)

Le route con meta.hidden: true vengono escluse. La sezione default è app; per il rail "Impostazioni" passa 'settings'.

Best practice

  • name: usa slug-kebab univoco. Evita spazi e caratteri speciali.
  • description: tieni sotto i 200 caratteri.
  • routes: dichiara tutte le rotte raggiungibili anche se nascoste (meta.hidden), così la shell può fare permission-check completi.
  • permissions a livello manifest: rappresentano l'accesso minimo al modulo; permessi più granulari vanno sulle singole route.
  • meta: campo libero ma non abusarne — preferisci sempre i campi tipizzati quando esistono.

Tipi correlati