Documentation
/

Dépannage

/

Éviter les collisions d'identifiants

Éviter les collisions d'identifiants entre fichiers obfusqués

Lorsque plusieurs fichiers obfusqués par VM se retrouvent dans le même bundle, ils peuvent déclarer le même identifiant de premier niveau et faire planter la page dès l'analyse syntaxique. Voici pourquoi cela se produit et comment y remédier.

Le symptôme

Votre build se déroule sans problème, mais le navigateur lève une erreur à l'analyse syntaxique, avant même le démarrage de l'application :

Text

Pour savoir combien de chunks déclarent le nom indiqué dans l'erreur, comptez les fichiers qui en contiennent une déclaration :

Text

-l liste chaque fichier correspondant une seule fois et -w ne retient que les mots entiers : vmdX n'est donc pas compté. var est laissé de côté, car répéter une déclaration var n'est pas une erreur en soi. Un résultat supérieur à 1 signifie que le nom est déclaré dans plus d'un chunk. Remplacez vmd par le nom figurant dans votre message d'erreur.

Les collisions d'identifiants ne posent problème que lorsque les déclarations partagent une même portée. Un même nom répété dans des modules ou des closures distincts ne prouve pas une collision ; l'erreur d'analyse ci-dessus, si.

Pourquoi cela se produit

Les préréglages VM utilisent mangled-shuffled comme Identifier Names Generator. Il parcourt un petit alphabet dans un ordre mélangé, et avec l'obfuscation VM chaque globale renommée reçoit un préfixe vm (l'identifiersPrefix par défaut). L'ordre mélangé est mis en cache par processus : les fichiers obfusqués dans le même processus, ou avec le même seed fixe, puisent dans la même séquence - la première globale de chaque fichier porte donc le même nom, la deuxième un autre nom commun, et ainsi de suite.

Chaque fichier est obfusqué indépendamment, et le générateur repart du début de sa séquence pour chacun d'eux. Lorsque deux fichiers se retrouvent dans la même portée, les noms entrent en collision. Deux déclarations const vmd = … de premier niveau atterrissent dans la même portée, et l'analyseur rejette la seconde.

Les options qui introduisent davantage d'identifiants de premier niveau augmentent les chances que deux fichiers atteignent le même nom généré. vmWrapTopLevelInitializers en fait partie, et tous les préréglages VM l'activent déjà ; des options comme vmDynamicOpcodes ou vmBytecodeEncoding en ajoutent davantage.

Solutions

Privilégiez le regroupement d'abord, puis une seule obfuscation du bundle. Si vous obfusquez malgré tout séparément et que les scripts partagent une portée globale, choisissez l'une des options suivantes :

  • Activer randomIdentifiersPrefix (recommandé)

    Chaque exécution de l'obfuscation reçoit un préfixe aléatoire ajouté devant chaque identifiant global (avec l'obfuscation VM, il remplace le préfixe vm par défaut). Les noms issus de fichiers différents ne partagent plus d'espace de noms : les collisions disparaissent sans que vous ayez à coordonner les préfixes à la main.

  • Définir un identifiersPrefix unique par fichier

    Passez manuellement un préfixe différent lors de l'obfuscation de chaque fichier (par exemple identifiersPrefix: 'auth_' pour l'un, checkout_ pour un autre). Efficace, mais source d'erreurs si vous avez de nombreux fichiers - préférez l'option aléatoire ci-dessus.

    JavaScript

  • Passer identifierNamesGenerator à hexadecimal

    Les noms hexadécimaux utilisent un espace de clés bien plus vaste : deux fichiers ont donc beaucoup moins de chances de produire le même identifiant - mais l'unicité n'est pas garantie. Contrepartie : les identifiants sont plus longs que ceux de mangled-shuffled, et le bundle est donc légèrement plus gros.

  • Utiliser l'interface d'obfuscation multifichier, ou vérifier votre plugin de bundler

    Le tableau de bord ajoute un préfixe distinct par fichier lorsque vous utilisez l'obfuscation multifichier par lot, disponible avec les forfaits payants. Si vous utilisez un plugin de bundler, vérifiez son comportement au lieu de supposer qu'il fait de même. Si vous branchez l'obfuscation manuellement avec l'API npm, c'est à vous d'activer un préfixe.

Pour vérifier la correction, reconstruisez et rechargez l'application complète, et assurez-vous que la SyntaxError a disparu. Le nom de l'ancien message d'erreur ne doit plus être déclaré dans plus d'un chunk ; un préfixe change chaque nom généré : la commande grep ci-dessus ne renseigne donc que sur ce nom précis, pas sur les nouveaux.

Options associées