Documentazione
/

Risoluzione dei problemi

/

Evitare le collisioni di identificatori

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:

Text

Per vedere quanti chunk dichiarano il nome indicato nell'errore, conta i file che ne contengono una dichiarazione:

Text

-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 identifiersPrefix univoco per ogni file

    Passa 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.

    JavaScript

  • Imposta identifierNamesGenerator su hexadecimal

    I 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