Evitando colisões de identificadores
Quando vários arquivos ofuscados por VM acabam no mesmo bundle, eles podem declarar o mesmo identificador de nível superior e derrubar a página no momento do parse. Veja por que isso acontece e como resolver.
O sintoma
O seu build roda sem problemas, mas o navegador lança um erro no parse, antes de o app iniciar:
Para ver quantos chunks declaram o nome do erro, conte os arquivos que contêm uma declaração dele:
-l lista cada arquivo correspondente uma única vez e -w corresponde apenas a palavras inteiras, então vmdX não é contado. var fica de fora porque repetir uma declaração var não é um erro por si só. Um resultado acima de 1
significa que o nome é declarado em mais de um chunk. Substitua vmd pelo nome da sua mensagem de erro.
Colisões de identificadores só importam quando as declarações compartilham um escopo. O mesmo nome repetido em módulos ou closures separados não prova uma colisão; o erro de parse acima prova.
Por que isso acontece
As predefinições VM usam mangled-shuffled como Identifier Names Generator. Ele percorre um alfabeto pequeno em uma ordem embaralhada e,
com a ofuscação VM, todo global renomeado recebe um prefixo vm (o identifiersPrefix padrão). A ordem embaralhada fica
em cache por processo, então arquivos ofuscados no mesmo processo, ou com o mesmo seed fixo, tiram nomes da mesma
sequência - o primeiro global de cada arquivo tem o mesmo nome, o segundo tem outro nome em comum, e assim por diante.
Cada arquivo é ofuscado de forma independente, e o gerador recomeça do início da sequência para cada um. Quando
dois arquivos acabam no mesmo escopo, os nomes colidem. Duas declarações const vmd = … de nível superior caem no mesmo
escopo, e o parser rejeita a segunda.
Opções que introduzem mais identificadores de nível superior aumentam a chance de dois arquivos chegarem ao mesmo nome gerado.
vmWrapTopLevelInitializers é uma delas, e todas as predefinições VM já a ativam; opções como
vmDynamicOpcodes ou vmBytecodeEncoding adicionam mais.
Soluções
Prefira fazer o bundle primeiro e depois ofuscar o bundle uma única vez. Se você ofuscar separadamente e os scripts compartilharem um escopo global, escolha uma das opções a seguir:
Ative
randomIdentifiersPrefix(recomendado)Cada execução da ofuscação recebe um prefixo aleatório adicionado a todos os identificadores globais (na ofuscação VM, ele substitui o prefixo
vmpadrão). Os nomes de arquivos diferentes deixam de compartilhar um namespace, então as colisões desaparecem sem que você precise coordenar prefixos manualmente.Defina um
identifiersPrefixúnico por arquivoPasse manualmente um prefixo diferente ao ofuscar cada arquivo (por exemplo,
identifiersPrefix: 'auth_'para um,checkout_para outro). Funciona, mas é propenso a erros se você tiver muitos arquivos - prefira a opção aleatória acima.Mude
identifierNamesGeneratorparahexadecimalNomes hexadecimais usam um espaço de chaves muito maior, então é bem menos provável que dois arquivos produzam o mesmo identificador - mas a unicidade não é garantida. Contrapartida: os identificadores são mais longos que a saída de
mangled-shuffled, então o bundle fica um pouco maior.Use a interface de lote com vários arquivos ou verifique o plugin do seu bundler
O painel adiciona um prefixo distinto por arquivo quando você usa a ofuscação em lote de vários arquivos, que está disponível nos planos pagos. Se você usa um plugin de bundler, verifique o comportamento dele em vez de supor que faz o mesmo. Se você está montando a ofuscação manualmente com a API do npm, precisa ativar um prefixo por conta própria.
Para verificar a correção, refaça o build, recarregue a aplicação combinada e confirme que o SyntaxError sumiu. O nome da
mensagem de erro antiga não deve mais ser declarado em mais de um chunk; um prefixo muda todos os nomes gerados, então
o grep acima só informa sobre aquele nome específico, não sobre os novos.
Opções relacionadas
randomIdentifiersPrefix- prefixo aleatório por build (recomendado)identifiersPrefix- string de prefixo explícitaidentifierNamesGenerator- formato dos nomes (mangled,hexadecimal, …)
