Dokumentation
/

Fehlerbehebung

/

Bezeichnerkollisionen vermeiden

Bezeichnerkollisionen zwischen obfuskierten Dateien vermeiden

Landen mehrere VM-obfuskierte Dateien im selben Bundle, können sie denselben Bezeichner auf oberster Ebene deklarieren und die Seite bereits beim Parsen zum Absturz bringen. Hier erfahren Sie, warum das passiert und wie Sie es beheben.

Das Symptom

Ihr Build läuft fehlerfrei, doch der Browser wirft beim Parsen einen Fehler, noch bevor die App startet:

Text

Um zu sehen, wie viele Chunks den Namen aus der Fehlermeldung deklarieren, zählen Sie die Dateien, die eine Deklaration davon enthalten:

Text

-l listet jede passende Datei einmal auf, und -w findet nur ganze Wörter, sodass vmdX nicht mitgezählt wird. var bleibt außen vor, weil eine wiederholte var-Deklaration für sich genommen kein Fehler ist. Ein Ergebnis über 1 bedeutet, dass der Name in mehr als einem Chunk deklariert wird. Ersetzen Sie vmd durch den Namen aus Ihrer Fehlermeldung.

Bezeichnerkollisionen spielen nur eine Rolle, wenn sich die Deklarationen einen Gültigkeitsbereich teilen. Derselbe Name in getrennten Modulen oder Closures ist noch kein Beweis für eine Kollision; der obige Parse-Fehler dagegen schon.

Warum das passiert

VM-Voreinstellungen setzen Identifier Names Generator auf mangled-shuffled. Dieser Generator durchläuft ein kleines Alphabet in einer gemischten Reihenfolge, und bei VM-Obfuskierung erhält jeder umbenannte globale Bezeichner das Präfix vm (der Standardwert von identifiersPrefix). Die gemischte Reihenfolge wird pro Prozess zwischengespeichert, daher schöpfen Dateien, die im selben Prozess oder mit demselben festen seed obfuskiert werden, aus derselben Folge: Der erste globale Bezeichner jeder Datei hat also denselben Namen, der zweite einen anderen gemeinsamen Namen und so weiter.

Jede Datei wird unabhängig obfuskiert, und der Generator beginnt für jede wieder am Anfang seiner Folge. Landen zwei Dateien im selben Gültigkeitsbereich, kollidieren die Namen. Zwei Deklarationen const vmd = … auf oberster Ebene landen im selben Gültigkeitsbereich, und der Parser weist die zweite zurück.

Optionen, die mehr Bezeichner auf oberster Ebene einführen, erhöhen die Wahrscheinlichkeit, dass zwei Dateien denselben generierten Namen erreichen. vmWrapTopLevelInitializers ist eine davon, und jede VM-Voreinstellung aktiviert sie bereits; Optionen wie vmDynamicOpcodes oder vmBytecodeEncoding fügen weitere hinzu.

Lösungen

Bündeln Sie vorzugsweise zuerst und obfuskieren Sie das Bundle dann einmal. Wenn Sie doch getrennt obfuskieren und sich die Skripte einen globalen Gültigkeitsbereich teilen, wählen Sie eine der folgenden Möglichkeiten:

  • randomIdentifiersPrefix aktivieren (empfohlen)

    Jeder Obfuskierungslauf erhält ein zufälliges Präfix, das jedem globalen Bezeichner vorangestellt wird (bei VM-Obfuskierung ersetzt es das Standardpräfix vm). Namen aus verschiedenen Dateien teilen sich keinen Namensraum mehr, sodass die Kollisionen verschwinden, ohne dass Sie Präfixe von Hand abstimmen müssen.

  • Pro Datei ein eindeutiges identifiersPrefix festlegen

    Übergeben Sie beim Obfuskieren jeder Datei manuell ein anderes Präfix (z. B. identifiersPrefix: 'auth_' für die eine, checkout_ für eine andere). Wirksam, aber fehleranfällig, wenn Sie viele Dateien haben; bevorzugen Sie die zufällige Variante oben.

    JavaScript

  • identifierNamesGenerator auf hexadecimal umstellen

    Hexadezimale Namen nutzen einen deutlich größeren Schlüsselraum, sodass zwei Dateien weit seltener denselben Bezeichner erzeugen, doch Eindeutigkeit ist nicht garantiert. Nachteil: Die Bezeichner sind länger als die Ausgabe von mangled-shuffled, das Bundle wird also etwas größer.

  • Die Stapelverarbeitung mehrerer Dateien in der Oberfläche nutzen oder Ihr Bundler-Plugin prüfen

    Das Dashboard fügt jeder Datei ein eigenes Präfix hinzu, wenn Sie mehrere Dateien im Stapel obfuskieren; diese Funktion ist in den kostenpflichtigen Tarifen verfügbar. Verwenden Sie ein Bundler-Plugin, prüfen Sie dessen Verhalten, statt anzunehmen, dass es dasselbe tut. Binden Sie die Obfuskierung manuell über die npm-API ein, müssen Sie ein Präfix selbst aktivieren.

Um die Lösung zu überprüfen, erstellen Sie die zusammengesetzte Anwendung neu, laden Sie sie erneut und vergewissern Sie sich, dass der SyntaxError verschwunden ist. Der Name aus der alten Fehlermeldung sollte nicht mehr in mehr als einem Chunk deklariert sein; ein Präfix ändert jeden generierten Namen, daher gibt der obige grep-Befehl nur Auskunft über diesen einen Namen, nicht über die neuen.

Verwandte Optionen