public-ui / kolibri

The accessible HTML-Standard
https://public-ui.github.io
European Union Public License 1.2
174 stars 34 forks source link

Bug: Wenn mehrere Kolibri's in der gleichen Version registriert werden. #6775

Closed deleonio closed 1 month ago

deleonio commented 3 months ago

Input: Im Projekt wird der TabNameTransformer verwendet. In mehreren Micro-Frontends wird aber unbewusst, die gleiche KoliBri-Version verwendet. Bei der Komposition soll das nicht mehr zum Fehlerfall führen. Es gibt eine Dauerschleife mit einem ToastService-Fehler.


User Story: Fehlerbehebung für TabNameTransformer und KoliBri-Versionen in Micro-Frontends


Als Entwickler,
möchte ich sicherstellen, dass der TabNameTransformer korrekt funktioniert, selbst wenn in mehreren Micro-Frontends unbewusst dieselbe KoliBri-Version verwendet wird,
damit bei der Komposition von Micro-Frontends keine Fehler mehr auftreten und der ToastService-Fehler, der eine Dauerschleife verursacht, behoben wird.


Akzeptanzkriterien:

  1. Fehleranalyse und Behebung:

    • Der bestehende Fehler, der auftritt, wenn mehrere Micro-Frontends dieselbe KoliBri-Version verwenden, wird analysiert.
    • Es wird eine Lösung implementiert, die sicherstellt, dass die gleiche KoliBri-Version in mehreren Micro-Frontends keinen Konflikt mit dem TabNameTransformer verursacht.
    • Der ToastService-Fehler, der zu einer Dauerschleife führt, wird identifiziert und behoben.
  2. Komposition ohne Fehler:

    • Bei der Komposition von mehreren Micro-Frontends soll das Vorhandensein derselben KoliBri-Version keinen Fehlerfall mehr darstellen.
    • Das System muss in der Lage sein, mehrere Instanzen der gleichen KoliBri-Version ohne Konflikte zu verarbeiten.
  3. Fehlerbehandlung:

    • Es wird sichergestellt, dass bei zukünftigen Problemen mit dem TabNameTransformer oder dem ToastService keine endlosen Dauerschleifen mehr entstehen, sondern ordentliche Fehlerbehandlungsmechanismen greifen.
    • Eine passende Toast-Nachricht oder eine Fehlerlogik wird eingebaut, die den Fehler auf verständliche Weise kommuniziert, ohne das System in eine Endlosschleife zu versetzen.

Stakeholder: @Chrisdo82

sdvg commented 1 month ago

Related: https://github.com/public-ui/kolibri/issues/6545

sdvg commented 1 month ago

Ich habe hier versucht, das Problem zu reproduzieren: https://github.com/public-ui/lab-micro-frontends/pull/193

Im PR verwenden beide KoliBri-Provider die selbe, aktuelle KoliBri-Version. Beide Module verwenden den Toast-Service. Lösen musste ich lediglich die Probleme, die in https://github.com/public-ui/kolibri/issues/6545 schon dokumentiert sind. Ein neues Problem kann ich nicht nachstellen und benötige hierzu mehr Informationen zur Umgebung bzw. den genauen Umständen und der Fehlermeldung.

screenshot 2024-10-09-11 20 21@2x


Unabhängig vom Ticket ist aufgefallen, dass wenn zwei KoliBri-Instanzen gleichzeitig Toasts rendern, dies zwei Toast-Container erzeugt, die einander überlagern. Hier wäre zu bewerten, ob das in der Praxis ein reales Problem ist, das wir ggf. behandeln sollten.

sdvg commented 1 month ago

Noch zu testen: Beide Versionen verwenden den selben tag-name-transformer (suffix)

sdvg commented 1 month ago

@deleonio Beide Module bzw. Provider verwenden jetzt einen -v2-Suffix, einen Fehler können wir leider trotzdem nicht produzieren.

Chrisdo82 commented 1 month ago

Bei uns wurde das Problem mit der KoliBri Version 2.1.3 festgestellt. Wurde denn seitdem etwas am initialize (siehe https://github.com/public-ui/kolibri/blob/develop/packages/components/src/core/bootstrap.ts) geändert?

Ich weiß nicht, ob dein Testrepo unter den gleichen Bedingungen läuft wie bei uns, daher beschreibe ich mal grob wie es bei uns aufgebaut ist:

Unsere Vermutung ist, dass das initialize zwar im jeweiligen Microfrontend auf true gesetzt wird, aber dass andere Microfrontend davon gar nichts weiß, da es sich um eine Variable im lokalen Scope handelt. Also beim 2. Microfrontend das geladen wird, ist das initialize ebenso false und nicht true.

Müsstet ihr das nicht entweder global setzen oder aber über einen anderen Weg prüfen ob Kolibri bereits initialisiert wurde?

sdvg commented 1 month ago

Hallo @Chrisdo82

Danke für die Beschreibung!

Ein paar Rückfragen hätte ich noch, um euer Setup bestmöglich nachstellen zu können:

1) Was verwendet ihr (z.B. Webpack, Rollup, etc.), um die einzelnen Apps in jeweils eine JS-Datei zu bundeln? 2) Was genau ist die Fehlermeldung, die ihr seht? 3) Wie stellt ihr sicher, dass KoliBri fertig initialisiert wurde, bevor ihr das Micro-Frontend rendered?

Letzteres ist ein Problem, auf das ich selber gestoßen bin, als ich versucht habe, euer Setup nachzubauen. Ich habe es bei mir jetzt mit einer "Provider" Komponente gelöst, die Teil des Microfrontend ist. Löst ihr das ähnlich, oder fehlt so etwas bei euch möglicherweise?

```tsx // main.tsx import React from 'react'; import {Module} from './Module.tsx'; import {KoliBriProvider} from "./KoliBriProvider.tsx"; export default () => { return }; ``` ```tsx // KoliBriProvider.tsx import React, {useEffect, useState, FC} from "react"; import {registerKolibri} from "./bootstrap.ts"; type KoliBriProviderProps = { children?: React.ReactNode } export const KoliBriProvider: FC = ({children}) => { const [kolibriReady, setKoliBriReady] = useState(false); useEffect(() => { (async () => { await registerKolibri(); setKoliBriReady(true) })(); }, []); return kolibriReady ?

App Loading...

: children; } ``` ```ts // bootstrap.ts import {bootstrap} from '@public-ui/components'; import {defineCustomElements} from '@public-ui/components/dist/loader'; import {DEFAULT} from '@public-ui/theme-default'; import {setTagNameTransformer} from "@public-ui/react"; const transformTagName = (tagName: string) => `${tagName}-2_1_3`; setTagNameTransformer(transformTagName); export async function registerKolibri() { await bootstrap(DEFAULT, [], { transformTagName, }).then(() => { void defineCustomElements(window, { transformTagName, } as any); // https://github.com/ionic-team/stencil/issues/2847 }); } ``` ```tsx // Module.tsx import React, {FC, useState} from 'react'; import {KolButton, KolLinkGroup} from '@public-ui/react'; import {ToasterService} from '@public-ui/components'; export const Module: FC = () => { const toaster = ToasterService.getInstance(document); const [counter, setCounter] = useState(0); return (

Micro One

setCounter(counter + 1)}}> { toaster.enqueue({ label: 'Toast label', type: 'info', }); }, }} />
); }; ```

Müsstet ihr das nicht entweder global setzen oder aber über einen anderen Weg prüfen ob Kolibri bereits initialisiert wurde?

Möglich! Bei meinen bisherigen Versuchen war es aber auch kein Problem, wenn es mehrere KoliBri-Instanzen gab. Daher möchte ich zunächst euer Setup nachstellen, um sicherzustellen, dass so eine Änderung wirklich eine Lösung für das Problem wäre.

Chrisdo82 commented 1 month ago

Hi @sdvg,

nicht so einfach zu beschreiben. Ein Call wäre hier wirklich einfacher. Aber ich versuche dir zu morgen dazu Input zu liefern.

Chrisdo82 commented 1 month ago

Hi @sdvg,

ich habe heute das Problem versucht mit der 2.1.8 zu reproduzieren und es ist mir nicht gelungen. Das Problem trat mit der 2.1.3 jedoch noch auf.

Ich würde vorschlagen, dass wir dieses Issue erstmal wieder schließen. Sollte das Problem wieder auftauchen, würde ich ein neues Issue erstellen und auf dieses dann referenzieren.

sdvg commented 1 month ago

@Chrisdo82 Danke für die Rückmeldung. Ich würde vorschlagen, dass wir dann nächstes mal direkt einen Call vereinbaren und das Problem gemeinsam anschauen.