Evitare le collisioni di identificatori tra file offuscati
Quando più file offuscati con la VM finiscono nello stesso bundle, possono dichiarare lo stesso identificatore di primo livello e far fallire la pagina in fase di parsing. Ecco perché succede e come risolverlo.
Il sintomo
La build viene eseguita senza problemi, ma il browser genera un errore in fase di parsing, prima dell'avvio dell'app:
Per vedere quanti chunk dichiarano il nome indicato nell'errore, conta i file che ne contengono una dichiarazione:
-l elenca ogni file corrispondente una sola volta e -w trova solo parole intere, quindi vmdX non viene conteggiato. var è escluso perché ripetere una dichiarazione var di per sé non è un errore. Un risultato maggiore di 1
significa che il nome è dichiarato in più di un chunk. Sostituisci vmd con il nome presente nel tuo messaggio di errore.
Le collisioni di identificatori contano solo quando le dichiarazioni condividono uno scope. Lo stesso nome ripetuto in moduli o closure separati non prova una collisione; l'errore di parsing qui sopra sì.
Perché succede
I preset VM usano mangled-shuffled come Identifier Names Generator. Percorre un piccolo alfabeto in un ordine mescolato e,
con l'offuscamento VM, ogni variabile globale rinominata riceve un prefisso vm (il valore predefinito di identifiersPrefix). L'ordine mescolato viene
memorizzato in cache per processo, quindi i file offuscati nello stesso processo, o con lo stesso seed fisso, attingono alla stessa
sequenza: la prima variabile globale di ogni file ha lo stesso nome, la seconda ne condivide un altro, e così via.
Ogni file viene offuscato in modo indipendente e il generatore riparte dall'inizio della sua sequenza per ciascuno di essi. Quando
due file finiscono nello stesso scope, i nomi entrano in collisione. Due dichiarazioni di primo livello const vmd = … finiscono nello stesso
scope e il parser rifiuta la seconda.
Le opzioni che introducono più identificatori di primo livello aumentano la probabilità che due file arrivino allo stesso nome generato.
vmWrapTopLevelInitializers è una di queste, e tutti i preset VM la attivano già; opzioni come
vmDynamicOpcodes o vmBytecodeEncoding ne aggiungono altri.
Soluzioni
È preferibile eseguire prima il bundling e poi offuscare il bundle una sola volta. Se invece offuschi i file separatamente e gli script condividono uno scope globale, scegli una delle seguenti soluzioni:
Attiva
randomIdentifiersPrefix(consigliato)Ogni esecuzione dell'offuscamento riceve un prefisso casuale anteposto a ogni identificatore globale (con l'offuscamento VM sostituisce il prefisso predefinito
vm). I nomi di file diversi non condividono più uno spazio dei nomi, quindi le collisioni scompaiono senza che tu debba coordinare manualmente i prefissi.Imposta un
identifiersPrefixunivoco per ogni filePassa manualmente un prefisso diverso quando offuschi ciascun file (ad esempio
identifiersPrefix: 'auth_'per uno,checkout_per un altro). È efficace, ma soggetto a errori se hai molti file: preferisci l'opzione casuale descritta sopra.Imposta
identifierNamesGeneratorsuhexadecimalI nomi esadecimali usano uno spazio di chiavi molto più ampio, quindi è molto meno probabile che due file producano lo stesso identificatore, ma l'univocità non è garantita. Compromesso: gli identificatori sono più lunghi dell'output di
mangled-shuffled, quindi il bundle è leggermente più grande.Usa l'interfaccia di elaborazione multi-file o verifica il plugin del bundler
La dashboard aggiunge un prefisso distinto per ogni file quando usi l'offuscamento multi-file in batch, disponibile nei piani a pagamento. Se usi un plugin del bundler, verifica il suo comportamento invece di dare per scontato che faccia lo stesso. Se configuri l'offuscamento manualmente con l'API npm, devi attivare tu stesso un prefisso.
Per verificare la correzione, ricompila e ricarica l'applicazione combinata e conferma che il SyntaxError sia scomparso. Il nome presente
nel vecchio messaggio di errore non dovrebbe più essere dichiarato in più di un chunk; un prefisso cambia ogni nome generato, quindi
il comando grep qui sopra ti informa solo su quel nome specifico, non su quelli nuovi.
Opzioni correlate
randomIdentifiersPrefix- prefisso casuale per ogni build (consigliato)identifiersPrefix- stringa di prefisso esplicitaidentifierNamesGenerator- forma dei nomi (mangled,hexadecimal, …)
