Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Modul-Abhängigkeiten (module.xml sequence) sauber verwalten

Modul-Abhängigkeiten (module.xml sequence) sauber verwalten

~6 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026

Die <sequence> in module.xml ist über die ganze Serie hinweg fünfmal gewachsen - immer aus demselben Grund: ein Fremdschlüssel oder eine EAV-Abhängigkeit brauchte die Garantie, dass eine andere Tabelle bereits existiert, bevor db_schema.xml oder ein Data Patch darauf zugreift. Dieses Kapitel zieht die fünf Einzelentscheidungen aus Kapitel 2, 11, 19/20 und 22 zu einem einzigen, finalen module.xml zusammen - und erklärt ebenso genau, warum vier scheinbar naheliegende Kandidaten bewusst nicht in der Liste stehen.

Die finale sequence

app/code/Mironsoft/Loyalty/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Mironsoft_Loyalty">
        <sequence>
            <module name="Magento_Customer"/>
            <module name="Magento_Sales"/>
            <module name="Magento_Eav"/>
            <module name="Magento_Catalog"/>
            <module name="Magento_Company"/>
        </sequence>
    </module>
</config>

Warum jeder einzelne Eintrag

  • Magento_Customer (Kapitel 2): Fremdschlüssel customer_id im Punkte-Ledger (Kapitel 3) auf customer_entity.entity_id, außerdem das Ziel der Customer-Attribute loyalty_points_balance/loyalty_tier (Kapitel 21).
  • Magento_Sales (Kapitel 2): Fremdschlüssel order_id im Ledger auf sales_order.entity_id, außerdem Ziel der Sales-Attribute loyalty_points_earned/loyalty_points_redeemed (Kapitel 23/63).
  • Magento_Eav (Kapitel 11): die Prämien-Entity (Kapitel 10-18) hängt vom kompletten EAV-Tabellenwerk (eav_attribute, eav_attribute_set, eav_entity_type) ab, das erst Magento_Eav selbst anlegt.
  • Magento_Catalog (Kapitel 19/20): Produkt- und Kategorie-Attribute sowie - ab Block 9 - der eigene Produkttyp registrieren sich gegen catalog_product/catalog_category und gegen Core-Basisklassen wie Type\Virtual.
  • Magento_Company (Kapitel 22): das Company-Attribut loyalty_tier_override hängt sich per extension_attributes.xml an CompanyInterface - ohne dieses Modul im System schlägt bereits die XML-Validierung fehl, nicht erst setup:upgrade.

Was bewusst fehlt - und warum das kein Versehen ist

Vier weitere Module tauchen im Code auf, ohne je einen eigenen sequence-Eintrag zu bekommen: Magento_Quote (die neue Spalte loyalty_points_to_redeem, Kapitel 63), Magento_Checkout/Magento_Payment (die Zahlungsart, Kapitel 62-65), Magento_Shipping (die Versandart, Kapitel 66-69) sowie Magento_Widget/Magento_PageBuilder (Kapitel 55-61).

  • Widget und Page Builder binden sich ausschließlich über eigene, rein deklarative XML-Konfigurationsdateien ein (widget.xml, etc/pagebuilder/content_type.xml) - diese Mechanismen lesen zur Laufzeit, nicht beim Setup, es entsteht kein Wettlauf um eine noch nicht existierende Tabelle.
  • Payment, Checkout und Shipping werden klassisch über etc/config.xml (payment/*/model, carriers/*/model) und etc/di.xml registriert - ebenfalls zur Laufzeit aufgelöst, kein Schema-Zugriff beim Setup.
  • Quote ist der einzige wirklich diskussionswürdige Fall: loyalty_points_to_redeem (Kapitel 63) wird per db_schema.xml an die fremde Tabelle quote angehängt - dieselbe Art von Abhängigkeit wie beim Ledger. Kapitel 63 begründet den Verzicht auf einen eigenen Eintrag ausdrücklich damit, dass Magento_Quote selbst intern von Magento_Customer, Magento_Sales und Magento_Eav abhängt - alle drei stehen bereits in unserer eigenen sequence. Da Magentos Modul-Sortierer die sequence-Angaben aller installierten Module zu einer globalen Reihenfolge verrechnet, landet Magento_Quote dadurch schon transitiv vor Mironsoft_Loyalty.

Achtung: Diese transitive Argumentation ist ein bewusster, dokumentierter Kompromiss dieser Serie - keine allgemeine Regel für die eigene Praxis. Sie funktioniert nur, solange Magentos Core-Module ihre eigenen internen Abhängigkeiten nicht ändern, was außerhalb der eigenen Kontrolle liegt. Für ein echtes Produktivmodul ist die robustere Wahl fast immer ein expliziter, direkter sequence-Eintrag für jede Tabelle, auf die tatsächlich zugegriffen wird - auch wenn sie sich vermeintlich schon transitiv ergibt.

Was die sequence tatsächlich steuert - und was nicht

Eine häufige Fehlvorstellung: sequence steuert nicht, ob ein Plugin, Observer oder eine Preference eines fremden Moduls zur Laufzeit greift - das regeln allein di.xml/events.xml, unabhängig von der Modul-Reihenfolge. sequence wirkt ausschließlich beim Setup: der Reihenfolge, in der setup:upgrade db_schema.xml-Änderungen anwendet und Data Patches ausführt. Ein Plugin auf eine fremde Klasse braucht deshalb - anders als eine Fremdschlüssel-Spalte - grundsätzlich keinen eigenen sequence-Eintrag, nur weil das Zielmodul existieren muss (Composer-require reicht dafür bereits).

Tipp: Faustregel für die eigene Praxis: sequence genau dann ergänzen, wenn ein eigenes db_schema.xml oder ein Data Patch (EavSetup, SalesSetup, eine fremde Tabelle) auf Schema-Elemente eines anderen Moduls zugreift. Für reine Laufzeit-Erweiterungen (Plugin, Observer, Preference, Widget, Zahlungsart) reicht die Composer-Abhängigkeit.

Mit einer korrekten sequence steht auch die letzte offene Frage der Grundarchitektur - Kapitel 99 widmet sich als Nächstes der Reihenfolge, in der ein so großes Modul überhaupt produktiv ausgerollt wird.