Magento2 - setup: di: compile

12

Ich habe in einem Projekt mit benutzerdefiniertem Code gearbeitet ... dies ist unser erstes "mittleres" Magento 2-Projekt, also lernen wir (wie alle Leute hier denke) jeden Tag neue Dinge und müssen die Art und Weise ändern, wie wir damit umgehen mit dieser neuen Magento-Version

Der Grund für diese Frage ist die Frage nach dem Befehl setup:di:compile

Ich benutze es seit dem ersten Tag mit Magento 2, da bin / magento nach jedem setup:upgrademit der Meldung "Bitte führen Sie den Magento-Kompilierungsbefehl erneut aus" danach fragt.

Nun ... Ich habe festgestellt, dass setup:di:compilein diesem Projekt die Produktansichtseite für Pausen mit einem völlig mehrdeutigen schwerwiegenden Fehler ausgeführt wird. Ich habe ganze Arbeitstage damit verbracht, es zu debuggen und mit Codeänderungen ohne Ergebnis zu testen

Heute habe ich festgestellt, dass, wenn ich diesen Befehl weglasse, alles wie ein Zauber wirkt, auch im Produktionsmodus

Die Frage ist also ... was genau setup:di:compilebefiehlt dieser Befehl? Ist es erforderlich? Nur empfohlen? Oder ist es ein veralteter Befehl, der nicht ausgeführt werden muss?

AKTUALISIEREN

Wie einige Benutzer gefordert haben, ist dies der schwerwiegende Fehler, auf den ich verwiesen habe

Schwerwiegender PHP-Fehler: Die abstrakte Klasse Magento \ Catalog \ Block \ Product \ View \ AbstractView in *** / vendor / magento / framework / ObjectManager / Factory / AbstractFactory.php in Zeile 93 kann nicht instanziiert werden

Ich habe mit Magento \ Catalog \ Block \ Product \ View \ AbstractView nach einem benutzerdefinierten Block gesucht, aber ich habe ihn nur in Layoutdateien gefunden. Er ist in keinem Blockklassenkonstruktor vorhanden

Was ich nicht verstehen kann ist: Warum Magento diesen schwerwiegenden Fehler mit kompiliertem Code auslöst, aber es funktioniert wie ein Zauber ohne kompilierten Code

Raul Sanchez
quelle
Können Sie bestätigen, dass 'setup: di: compile' den Produktansichtsfehler auch im Entwicklungsmodus verursacht?
paj
Ja, schwerwiegender Fehler tritt in beiden Modi auf
Raul Sanchez
Können Sie den "völlig mehrdeutigen schwerwiegenden Fehler" posten?
paj
Ich habe die Frage mit Fehler aktualisiert. Vielen Dank
Raul Sanchez

Antworten:

20

Der Befehl setup:di:compilebefehl generiert den Inhalt des var/diOrdners in Magento <2.2 und generated für Magento> = 2.2

Laut Magento dient dies folgendem Zweck:

  • Generierung von Anwendungscode (Fabriken, Proxys usw.)
  • Bereichskonfigurationsaggregation (dh optimierte Abhängigkeitsinjektionskonfigurationen pro Bereich)
  • Interceptor-Generierung (dh optimierte Code-Generierung von Interceptors)
  • Interception-Cache-Generierung
  • Generierung von Repositorys-Code (dh generierter Code für APIs)
  • Generierung von Servicedatenattributen (dh generierte Erweiterungsklassen für Datenobjekte)

Quelle ( http://devdocs.magento.com/guides/v2.0/config-guide/cli/config-cli-subcommands-compiler.html )

Wenn Sie Magento jedoch in den Produktionsmodus versetzen, funktioniert es ohne Kompilierung tatsächlich immer noch. Laut Magento-Dokumenten ist dies also eher ein Optimierungsschritt ( dh eine optimierte Codegenerierung von Interceptors).

Wenn der setup:di:compileBefehl Fehler enthält , liegt dies hauptsächlich an Fehlern in einem der Konstruktoren benutzerdefinierter PHP-Klassen.

Tjitse
quelle
1
Vielen Dank! Es ist also völlig optional ... Nur ein Punkt, also ist es mir klarer. In unserem Fall gibt setup: di: compile keinen Fehler aus, der Befehl endet in Ordnung. Es ist, wenn Sie die Site durchsuchen, nachdem der Befehl beendet wurde, wenn ein schwerwiegender Fehler auf den Seiten der Produktansicht ausgelöst wird
Raul Sanchez
Vielleicht kannst du den Fehler posten? Das würde die Sache klarer machen.
Tjitse
Ich habe die Frage mit Fehler aktualisiert. Vielen Dank
Raul Sanchez
11

Es ist nicht zwingend erforderlich, den setup:di:compileBefehl jedes Mal auszuführen. Wenn Sie jedoch Codeänderungen speziell mit Factory-Methoden, Proxy, Hinzufügen von Plugins oder einer Codekompilierung vorgenommen haben, müssen Sie diesen Befehl ausführen.

Mehr Details

magento setup:di:compileum notwendige Dateien zu generieren. Beide Optionen führen zum Generieren von Klassen in MAGENTO_ROOT/var/generation directory(oder /generatedwenn Magento 2.2+).

Welche Klassen werden generiert?

  1. Fabriken
  2. Proxies
  3. Plugins

Fabriken

Fabriken werden verwendet, um Objekte zu instanziieren, die nicht automatisch injiziert werden können. Beispielsweise muss ein Produktobjekt aus der Datenbank geladen werden, aber der Abhängigkeitsinjektionscontainer verfügt nicht über genügend Informationen, um dieses Objekt zu erstellen. Deshalb benutzen wir Fabriken.

Proxies

Magento 2 verwendet die Konstruktorinjektion, bei der alle Abhängigkeiten erforderlich sind. Sie können ein Objekt nicht instanziieren, ohne alle Abhängigkeiten zu übergeben. Was ist, wenn Sie optionale Abhängigkeiten haben möchten? Deshalb gibt es Proxies.

Plugins (Interceptors)

Einfach ausgedrückt, Plugins sind die primären Anpassungsmechanismen für Magento 2. Keine Klassenumschreibungen mehr. Sie können sich vor, nach oder um eine öffentliche Methode der Anwendung anschließen und etwas tun.

Wenn Sie den Befehl setup: di: compile ausführen, wird Folgendes ausgeführt

Die Codekompilierung besteht aus allen folgenden Elementen in keiner bestimmten Reihenfolge:

  • Generierung von Anwendungscode (Fabriken, Proxys usw.)

  • Bereichskonfigurationsaggregation (dh optimierte Abhängigkeitsinjektionskonfigurationen pro Bereich)

  • Interceptor-Generierung (dh optimierte Code-Generierung von Interceptors)

  • Generierung des Interception-Cache Regeneritories-Codegenerierung (dh generierter Code für APIs)

  • Generierung von Servicedatenattributen (dh generierte Erweiterungsklassen für Datenobjekte)

In dieser Antwort erfahren Sie, wann wir welche Befehle ausführen sollten: /magento//a/184927/35758

Prinz Patel
quelle
Vielen Dank! Es ist also völlig optional ... Nur ein Punkt, also ist es mir klarer. In unserem Fall gibt setup: di: compile keinen Fehler aus, der Befehl endet in Ordnung. Es ist beim Durchsuchen der Site, nachdem der Befehl beendet wurde, wenn ein schwerwiegender Fehler auf den Seiten der Produktansicht ausgelöst wird. Ich verstehe also nicht wirklich, warum nicht kompilierter Code gut funktioniert, aber beim Kompilieren tritt ein schwerwiegender Fehler auf
Raul Sanchez
Dies kann passieren, wenn Ihre Unterklasse nach den vorhandenen optionalen Abhängigkeiten der übergeordneten Klasse neue Abhängigkeiten hinzugefügt hat. Sie können dies beheben, indem Sie alle neuen erforderlichen Parameter über die optionalen Parameter verschieben.
Prinz Patel
2

Magento wird weiterhin in Produktion und Entwicklung ohne den Befehl di: compile ausgeführt. Die Interceptors werden nach Bedarf kompiliert und im generatedOrdner gespeichert .

Selbst wenn es funktioniert, heißt das nicht, dass Sie diesen Schritt überspringen sollten! Wenn dies ausgeführt wird, sucht Magento auch nach doppelten Injektionen, Abhängigkeitsschleifen und anderen grundlegenden Schritten, die Ihre Site stabiler machen und weniger wahrscheinlich abstürzen und! Sterben.

Ich bin der festen Überzeugung, dass dieser Fehler auf die Verwendung einer Klasse zurückzuführen ist, die Magento aufgrund eines falschen Konstruktorarguments nicht kompilieren kann.

Der Fehler, den Sie gepostet haben, ist ziemlich vage, aber ich glaube, Sie haben eine Klasse, die die AbstractViewKlasse erweitert. 99% ist ein Block irgendwo in Ihren benutzerdefinierten Modulen, der nicht die richtigen Argumente an die parent::__construct()Methode übergibt . Daher schlägt es fehl, wenn es instanziiert wird.

Beachten Sie, dass alle Blöcke die AbstractView-Klasse erweitern, sodass Sie den Kompilierungsbefehl mit xdebugon ausführen und ein Protokoll für die Stapelverfolgung erstellen müssen, um festzustellen , welche Klasse sie zuletzt aufgerufen hat, bevor sie fehlgeschlagen ist.

Die Tatsache , dass die Website läuft , ohne dass Fehler bedeuten , dass Sie nicht tatsächlich die Verwendung von beschädigtem Block überall auf Ihrer Seite, aber Magento noch versuchen , es zu kompilieren , wenn den Lauf compileBefehl, daher scheitert es.

zog7721
quelle
Vielen Dank, dass Sie sich die Zeit genommen haben, eine ältere Frage wie diese mit anderen validierten Antworten zu beantworten. Tatsächlich habe ich dieses Problem behoben, indem ich die falschen Blöcke in benutzerdefinierten Layouts behoben habe, wie Sie bereits angedeutet haben
Raul Sanchez,