Menghindari Tabrakan Pengenal di Antara Berkas Hasil Obfuskasi
Ketika beberapa berkas hasil obfuskasi VM berakhir di bundel yang sama, berkas-berkas itu dapat mendeklarasikan pengenal tingkat atas yang sama dan membuat halaman gagal saat parsing. Berikut penyebabnya dan cara memperbaikinya.
Gejalanya
Build Anda berjalan lancar, tetapi peramban melempar error saat parsing, sebelum aplikasi dimulai:
Untuk melihat berapa banyak chunk yang mendeklarasikan nama dari error tersebut, hitung berkas yang berisi deklarasinya:
-l mencantumkan setiap berkas yang cocok satu kali dan -w hanya mencocokkan kata utuh, sehingga vmdX tidak ikut dihitung. var tidak disertakan karena mengulang deklarasi var bukanlah error dengan sendirinya. Hasil di atas 1
berarti nama tersebut dideklarasikan di lebih dari satu chunk. Ganti vmd dengan nama dari pesan error Anda.
Tabrakan pengenal hanya berpengaruh ketika deklarasinya berbagi cakupan yang sama. Nama yang sama yang berulang di modul atau closure terpisah bukan bukti adanya tabrakan; error parsing di atas adalah buktinya.
Mengapa ini terjadi
Preset VM menggunakan generator nama pengenal mangled-shuffled. Generator ini menelusuri alfabet kecil dalam urutan
acak, dan di bawah obfuskasi VM setiap global yang diganti nama mendapat prefiks vm (ditambahkan di depan identifiersPrefix apa pun yang Anda setel, sehingga checkout_
menjadi vm_checkout_...).
Urutan acak tersebut disimpan dalam cache per proses, sehingga berkas yang diobfuskasi dalam proses yang sama, atau dengan seed tetap
yang sama, mengambil dari urutan yang sama - global pertama di setiap berkas memiliki nama yang sama, global kedua memiliki
nama lain yang sama, dan seterusnya.
Setiap berkas diobfuskasi secara independen dan generator mengulang dari awal urutannya untuk setiap berkas. Ketika dua berkas
berakhir di cakupan yang sama, nama-namanya bertabrakan. Dua deklarasi let vmd tingkat atas jatuh di cakupan yang
sama dan parser menolak yang kedua.
Setiap berkas yang diobfuskasi VM mendeklarasikan satu nama runtime tingkat atas tanpa sufiks, dan itu sudah cukup untuk
bertabrakan. renameGlobals: true membuatnya jauh lebih buruk: setiap deklarasi tingkat atas menjadi nama vm* yang
pendek, dan nama-nama milik runtime sendiri kehilangan sufiks uniknya.
Perbaikan
Sebaiknya bundel dulu, lalu obfuskasi bundel tersebut sekali. Jika Anda memang mengobfuskasi secara terpisah dan skrip-skrip itu berbagi cakupan global, pilih salah satu dari berikut:
Aktifkan
randomIdentifiersPrefix(direkomendasikan)Setiap proses obfuskasi mendapatkan prefiks acak yang ditambahkan di depan setiap pengenal global (pada obfuskasi VM, prefiks ini menggantikan prefiks bawaan
vm). Nama dari berkas yang berbeda tidak lagi berbagi namespace, sehingga tabrakan hilang tanpa Anda harus mengoordinasikan prefiks secara manual.Setel
identifiersPrefixunik per berkasBerikan prefiks yang berbeda secara manual saat mengobfuskasi setiap berkas (misalnya
identifiersPrefix: 'auth_'untuk satu berkas,checkout_untuk berkas lain). Efektif, tetapi rawan keliru jika Anda memiliki banyak berkas; lebih baik gunakan opsi acak di atas.Ubah
identifierNamesGeneratormenjadihexadecimalNama heksadesimal menggunakan ruang kunci yang jauh lebih besar, sehingga kecil kemungkinan dua berkas menghasilkan pengenal yang sama, tetapi keunikannya tidak dijamin. Konsekuensinya: pengenal lebih panjang daripada keluaran
mangled-shuffled, sehingga bundel sedikit lebih besar.Gunakan obfuskasi batch multi-berkas, atau periksa plugin bundler Anda
Dasbor menambahkan prefiks yang berbeda untuk setiap berkas dalam satu batch multi-berkas (paket berbayar); berkas dari batch yang berbeda tetap bisa bertabrakan. Jika Anda menggunakan plugin bundler, verifikasi perilakunya alih-alih berasumsi bahwa plugin itu melakukan hal yang sama. Jika Anda memanggil paket
javascript-obfuscatoratau API sendiri, Anda harus mengaktifkan prefiks sendiri.
Untuk memverifikasi perbaikan, build ulang dan muat ulang aplikasi gabungan, lalu pastikan SyntaxError sudah hilang. Nama dari
pesan error sebelumnya seharusnya tidak lagi dideklarasikan di lebih dari satu chunk; prefiks mengubah setiap nama hasil generate,
jadi grep di atas hanya memberi tahu Anda tentang nama tersebut, bukan tentang nama-nama yang baru.
Opsi terkait
randomIdentifiersPrefix- prefiks acak per build (direkomendasikan)identifiersPrefix- string prefiks eksplisitidentifierNamesGenerator- bentuk nama (mangled,hexadecimal, …)
