É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 :
Pour savoir combien de chunks déclarent le nom indiqué dans l'erreur, comptez les fichiers qui en contiennent une déclaration :
-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
vmpar 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
identifiersPrefixunique par fichierPassez 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.Passer
identifierNamesGeneratoràhexadecimalLes 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
randomIdentifiersPrefix- préfixe aléatoire par build (recommandé)identifiersPrefix- chaîne de préfixe expliciteidentifierNamesGenerator- forme des noms (mangled,hexadecimal, …)
