문서
/

문제 해결

/

식별자 충돌 피하기

난독화된 파일 간 식별자 충돌 피하기

VM 난독화된 여러 파일이 같은 번들에 들어가면 같은 최상위 식별자를 선언해 파싱 단계에서 페이지가 중단될 수 있습니다. 이 문제가 발생하는 이유와 해결 방법을 설명합니다.

증상

빌드는 정상적으로 실행되지만, 앱이 시작되기 전 파싱 단계에서 브라우저가 오류를 던집니다.

Text

오류에 나온 이름을 몇 개의 청크가 선언하는지 보려면, 그 이름의 선언을 포함한 파일 수를 세어 보세요.

Text

-l은 일치하는 파일을 한 번씩만 나열하고 -w는 단어 전체만 일치시키므로 vmdX는 세지 않습니다. var 선언은 반복해도 그 자체로는 오류가 아니므로 제외했습니다. 결과가 1보다 크면 그 이름이 둘 이상의 청크에서 선언되었다는 뜻입니다. vmd를 오류 메시지에 나온 이름으로 바꾸세요.

식별자 충돌은 선언들이 스코프를 공유할 때만 문제가 됩니다. 서로 다른 모듈이나 클로저에서 같은 이름이 반복되는 것만으로는 충돌의 증거가 되지 않으며, 증거는 위와 같은 파싱 오류입니다.

발생 이유

VM 프리셋은 Identifier Names Generator를 mangled-shuffled로 설정합니다. 이 생성기는 작은 알파벳을 섞인 순서대로 순회하며, VM 난독화에서는 이름이 바뀐 모든 전역에 vm 접두사(기본 identifiersPrefix)가 붙습니다. 섞인 순서는 프로세스마다 캐시되므로, 같은 프로세스에서 난독화되거나 같은 고정 seed로 난독화된 파일은 같은 순서에서 이름을 가져옵니다. 그래서 각 파일의 첫 번째 전역은 같은 이름을 갖고 두 번째 전역도 서로 같은 이름을 갖는 식입니다.

각 파일은 독립적으로 난독화되며, 생성기는 파일마다 순서의 처음부터 다시 시작합니다. 두 파일이 같은 스코프에 놓이면 이름이 충돌합니다. 최상위 const vmd = … 선언 두 개가 같은 스코프에 놓이면 파서는 두 번째 선언을 거부합니다.

최상위 식별자를 더 많이 도입하는 옵션은 두 파일이 같은 생성 이름에 도달할 가능성을 높입니다. vmWrapTopLevelInitializers가 그중 하나이며 모든 VM 프리셋이 이미 이 옵션을 켭니다. vmDynamicOpcodes나 vmBytecodeEncoding 같은 옵션은 식별자를 더 늘립니다.

해결 방법

먼저 번들링한 뒤 그 번들을 한 번만 난독화하는 방식을 권장합니다. 파일을 따로 난독화하고 스크립트들이 전역 스코프를 공유한다면 다음 중 하나를 선택하세요.

  • randomIdentifiersPrefix 켜기(권장)

    난독화를 실행할 때마다 모든 전역 식별자 앞에 무작위 접두사가 붙습니다(VM 난독화에서는 기본 vm 접두사를 대체합니다). 서로 다른 파일의 이름이 더 이상 네임스페이스를 공유하지 않으므로, 접두사를 직접 조율하지 않아도 충돌이 사라집니다.

  • 파일마다 고유한 identifiersPrefix 설정하기

    각 파일을 난독화할 때 다른 접두사를 직접 전달합니다(예: 한 파일에는 identifiersPrefix: 'auth_', 다른 파일에는 checkout_). 효과는 있지만 파일이 많으면 실수하기 쉬우므로 위의 무작위 옵션을 권장합니다.

    JavaScript

  • identifierNamesGenerator를 hexadecimal로 바꾸기

    Hexadecimal 이름은 키 공간이 훨씬 커서 두 파일이 같은 식별자를 만들어 낼 가능성이 훨씬 낮지만, 고유성이 보장되지는 않습니다. 단점은 식별자가 mangled-shuffled 출력보다 길어서 번들이 약간 커진다는 것입니다.

  • 다중 파일 일괄 처리 UI를 사용하거나 번들러 플러그인 확인하기

    대시보드는 다중 파일 일괄 난독화를 사용할 때 파일마다 다른 접두사를 붙이며, 이 기능은 유료 플랜에서 사용할 수 있습니다. 번들러 플러그인을 사용한다면 같은 방식으로 동작한다고 가정하지 말고 실제 동작을 확인하세요. npm API로 난독화를 직접 연결한다면 접두사를 직접 켜야 합니다.

해결되었는지 확인하려면 결합된 애플리케이션을 다시 빌드하고 다시 로드한 뒤 SyntaxError가 사라졌는지 확인하세요. 이전 오류 메시지에 나온 이름은 더 이상 둘 이상의 청크에서 선언되지 않아야 합니다. 접두사는 생성되는 모든 이름을 바꾸므로, 위의 grep은 그 특정 이름에 대해서만 알려 줄 뿐 새 이름에 대해서는 알려 주지 않습니다.

관련 옵션