Blog

Verwenden Sie benutzerdefinierte React-Hooks, um neue Funktionen über Microfrontends hinweg zu aktivieren

Jackson Boehman
November 25, 2024

✨ Lass uns über Abhängigkeiten sprechen! ✨ Manchmal muss ein Kunde Artikel in verschiedenen Teilen von FloQast verfolgen, und eine Lösung, die wir hatten, bestand darin, die Priorität und Reihenfolge dieser Artikel zu verfolgen.

In diesem Beitrag werde ich Ihnen erklären, wie wir es verwendet haben Reagieren Sie auf benutzerdefinierte Hooks um eine skalierbare, wiederverwendbare und domänenübergreifende Funktion „Abhängigkeiten“ das umfasst mehrere Microfrontends (MFEs), von denen jedes eine eigene Seite der App darstellt.

Einführung

Während des Financial Close Process stehen die Nutzer vor zahlreichen Herausforderungen:

  • Beziehungen zwischen Ressourcen erstellen: Aufgabe A ist „Blockiert von“ Aufgabe B.
  • Durchsetzen der Reihenfolge, in der die Aufgabe abgeschlossen wird: Abhängigkeiten sorgen für lineare Arbeitsabläufe (z. B. kann Aufgabe B erst abgeschlossen werden, wenn Aufgabe A abgeschlossen ist).
  • Abhängigkeiten visualisieren: Benutzer können alle Abhängigkeiten, die sich auf eine Ressource beziehen, und ihren Status auf einen Blick sehen.
  • Domänenübergreifende Abhängigkeiten: Ressourcen aus verschiedenen Bereichen (wie Checklisten und Abstimmungen) können vom jeweiligen Abschlussstatus abhängen.

In diesem Zusammenhang ist ein Domäne bezieht sich auf eine bestimmte MFE (oder Seite) innerhalb der Anwendung, jede mit ihrer eigenen MongoDB-Sammlung für die Datenverwaltung.

Durch die Implementierung von Abhängigkeiten wurden zahlreiche technische Ansätze eingeführt, von denen jeder seine eigenen Kompromisse hatte. Wir haben eine geschaffen Modul Abhängigkeiten (Nanofrontend) das erweitert die Funktionalität auf React-MFEs und gewährleistet so eine konsistente Handhabung von Abhängigkeiten in allen Workflows.

  • Was sind Nanofrontends? Nanofrontends bieten einen gehosteten Mechanismus für die gemeinsame Nutzung von Kernfunktionen auf verschiedene Kunden, ohne die Paketgröße von Microfrontends zu erhöhen. Ein anderer passender Name für Nanofrontends wäre Gehostete Abhängigkeiten oder immergrüne Abhängigkeiten. Das Exportieren einer Komponente/eines Hooks aus einem Nanofrontend (NFE) ermöglicht es Ingenieuren, diese Komponente zu importieren und in Frontend-Clients zu verwenden.

Zusammenfassung des Projekts

Das Ziel war es, eine zu schaffen Funktion „Abhängigkeiten“ das könnte:

  • Kann in mehreren Domänen (wie Checklisten oder Abstimmungen) wiederverwendet werden, wobei jede Domain einer MFE/-Seite und ihren Daten entspricht.
  • Rufen Sie mithilfe eines gemeinsamen Hooks Abhängigkeitsdaten für Ressourcen in verschiedenen Domänen ab und verwalten Sie sie.
  • Ermöglichen Sie die nahtlose Integration neuer MFEs mit minimalem Aufwand für jeden neuen Kunden, der Abhängigkeiten nutzen möchte.

Dies haben wir erreicht, indem wir eine gebaut haben dediziertes Nanofrontend für das Abhängigkeitsmanagement und die Enthüllung eines React-benutzerdefinierter Hook das könnte domänenübergreifend wiederverwendet werden. Da der Hook so konzipiert wurde, dass er mit jeder Domain funktioniert, umfasste die Erweiterung der Funktion auf neue MFEs das Importieren und Verwenden gemeinsam genutzter Hooks, anstatt redundanten Code und API-Aufrufe von mehreren Clients zu erstellen. (Wenn Sie mit Microfrontend-Clients nicht vertraut sind, hier ist ein weiterer Blogbeitrag von FQ Engineering zu diesem Thema)

Überblick über die Architektur auf hoher Ebene

Das Abhängigkeitsmodul lässt sich in Client-MFEs integrieren und seine Abhängigkeiten_API. So funktioniert das:

  1. Abhängigkeitsmodul (NFE): Exportiert React-Hooks, die Abhängigkeitsdaten abrufen und verwalten.
  2. Kunde MfES: Senden Sie Ereignisse für neue Ressourcen an den NFE und rufen Sie Abhängigkeiten mithilfe von NFE-Hooks ab.
  3. Abhängigkeiten_API: Behandelt CRUD-Operationen, zirkuläre Abhängigkeitsprüfungen und MongoDB-Interaktionen.
Dependencies diagram

Wie benutzerdefinierte Hooks eine domänenübergreifende Erweiterbarkeit ermöglichen

Der Kern dieser Lösung ist die Verwenden Sie FetchBatchDependenciesData benutzerdefinierter Hook, der das domänenübergreifende Abhängigkeitsmanagement vereinfacht, indem alle Abhängigkeiten und Ressourcen, die mit diesen Abhängigkeiten verbunden sind, von einer einzigen Funktion zurückgegeben werden.

Die wichtigsten Funktionen

  • Ruft Abhängigkeiten für jede Ressource mit ihrer ab Dokument-ID.
  • Gibt Daten über verwandte Abhängigkeiten zurück, einschließlich ihres Status und ihrer Domäne.
  • Ruft Abhängigkeiten automatisch erneut ab, wenn sie durch Ereignisse wie Aktualisierungen oder den Abschluss von Aufgaben ausgelöst werden.

Warum die Unterstützung verschiedener Domains entscheidend ist

Jede Domain (wie Checklisten oder Abstimmungen) ist eine eigene MFE/-Seite mit einer eigenen MongoDB-Sammlung und eigenen Workflows. Abhängigkeiten erstrecken sich oft über mehrere Domänen, sodass der Hook eine einheitliche Methode bietet, um:

  1. Ruft Abhängigkeiten für jede Ressource ab, unabhängig von Domäne/Client.
  2. Verwalten Sie domänenübergreifende Abhängigkeiten konsistent.

Die Zentralisierung der Abhängigkeitsverwaltung im Nanofrontend gewährleistet die Synchronisation über alle Workflows und Domänen hinweg.

Hook-Beispiel in Aktion

So funktioniert der Checklisten-Client MFE verwendet den benutzerdefinierten Hook, um Abhängigkeiten abzurufen und auf Updates zu reagieren (Der recs-Kunde hat den gleichen Code implementiert, um den Hook (/event-emitting) zu nutzen:

useEffect(() => {
    const handleDependenciesUpdated = () => {
        setDependencyUpdateTrigger((prev) => prev + 1);
    };

    window.addEventListener('dependenciesUpdated', handleDependenciesUpdated);

    return () => {
        window.removeEventListener('dependenciesUpdated', handleDependenciesUpdated);
    };
}, []);

const resourceIds = useMemo(
    () => checklists.map((checklist) => checklist._id),
    [checklists]
);

const { data, isLoading, error } = useFetchBatchDependenciesData({
    resourceIds,
    canViewDependencies: userCanViewDependencies,
    trigger: dependencyUpdateTrigger,
});

Implementierung des Hooks in der NFE

Hier ist die Implementierung des Verwenden Sie FetchBatchDependenciesData Hook aus dem Abhängigkeitsmodul:

export default function useFetchBatchDependenciesData({
    resourceIds,
    canViewDependencies,
    trigger,
}) {
    const [responseState, setResponseState] = useState({
        dependencies: [],
        isLoading: false,
        error: null,
    });

    useEffect(() => {
        if (!resourceIds.length || !canViewDependencies) {
            setResponseState((prevState) => ({
                ...prevState,
                isLoading: false,
            }));
            return;
        }

        setResponseState((prevState) => ({
            ...prevState,
            isLoading: true,
        }));

        const fetchDependencies = async () => {
            try {
                const dependencies = await DependenciesAPI.getDependenciesBatch(resourceIds);
                setResponseState({
                    dependencies,
                    error: null,
                    isLoading: false,
                });
            } catch (err) {
                setResponseState({
                    error: err,
                    isLoading: false,
                });
            }
        };

        fetchDependencies();
    }, [resourceIds, canViewDependencies, trigger]);

    return {
        data: responseState.dependencies,
        isLoading: responseState.isLoading,
        error: responseState.error,
    };
}

Vorteile der Verwendung von Hooks aus dem FQ-Dependencies-Nanofrontend:

  1. Wiederverwendbarkeit: Abstrakt das Abrufen von Abhängigkeitsdaten und erleichtert so die Integration für jedes MFE.
  2. Erweiterbarkeit: Hinzufügen einer neuen Domain (wie recs-Kunde) erfordert nur minimalen Arbeitsaufwand — einfach den Haken einstecken und die vorgefertigten Bauteile herstellen!
  3. Zentralisierte Updates: Alle Änderungen am Umgang mit Abhängigkeiten werden im Nanofrontend vorgenommen und an alle MFEs weitergegeben.
  4. Kohärenz: Stellt sicher, dass alle MFEs Abhängigkeiten auf die gleiche Weise anzeigen und verwalten, wodurch eine einheitliche Benutzererfahrung entsteht.

Entwicklung und Kundenorientierung

Als wir die Abhängigkeitsfunktion von erweitert haben Checklisten-Client zu recs-Kunde, es dauerte weniger als einen Sprint. Warum? Weil der wiederverwendbare Hook und die zentralisierte Nanofrontend-Logik die schwere Arbeit bewältigten.
Dieser Ansatz ermöglichte es uns, neue Funktionen schneller bereitzustellen, Codeduplizierung zu reduzieren und ein konsistentes Abhängigkeitsmanagement über alle Domänen hinweg sicherzustellen. Wie wirkt sich diese technische Strategie auf den Kunden aus? - Das bedeutet, dass wir in der Lage sind, eine bestehende Funktion in einem effizienten „Plug-and-Play“ -Ansatz auf mehrere angeforderte Teile der App auszurollen, sodass der Kunde schneller das bekommt, was er will.

Reflexion + Blick nach vorne

Die Entwicklung der Abhängigkeitsfunktion als modulares Nanofrontend war nicht nur eine technische Entscheidung — es war eine Geschäftsentscheidung.

Durch die Zentralisierung des Abhängigkeitsmanagements und die Bereitstellung wiederverwendbarer Hooks haben wir ein skalierbares System geschaffen, das Workflows über verschiedene Clients/Teile der App hinweg integriert. Die Möglichkeit, Abhängigkeitsaktualisierungen mit Hooks und Ereignissen abzurufen, anzuzeigen und darauf zu reagieren, hat die Art und Weise, wie wir domänenübergreifende Workflows handhaben, grundlegend verändert.

Und das Beste daran? Wenn neue Domains auftauchen, können sie sich schnell in dieses Ökosystem integrieren, sodass Abhängigkeiten eine Funktion sind, die mit nur wenigen Codezeilen in neue FloqAST-MFEs implementiert werden kann.