تجنّب تعارض المعرِّفات
عندما ينتهي الأمر بعدة ملفات مشوَّشة باستخدام VM في الحزمة نفسها، قد تصرّح بالمعرِّف نفسه في المستوى الأعلى فتتعطل الصفحة أثناء التحليل. إليك سبب حدوث ذلك وكيفية إصلاحه.
العَرَض
يكتمل البناء دون مشكلات، لكن المتصفح يرمي خطأً أثناء التحليل، قبل أن يبدأ التطبيق:
لمعرفة عدد الأجزاء التي تصرّح بالاسم الوارد في الخطأ، عُدّ الملفات التي تحتوي على تصريح به:
يسرد -l كل ملف مطابق مرة واحدة، ويطابق -w الكلمات الكاملة فقط، فلا يُحتسب vmdX. وقد استُبعد var لأن تكرار تصريح var ليس خطأً في حد ذاته. والنتيجة الأكبر من 1
تعني أن الاسم مُصرَّح به في أكثر من جزء. استبدل vmd بالاسم الوارد في رسالة الخطأ لديك.
لا يكون لتعارض المعرِّفات أثر إلا عندما تتشارك التصريحات النطاق نفسه. فتكرار الاسم نفسه في وحدات أو دوال مغلقة منفصلة ليس دليلًا على وجود تعارض؛ أما خطأ التحليل أعلاه فهو الدليل.
لماذا يحدث ذلك
تستخدم إعدادات VM المسبقة مولِّد أسماء المعرِّفات mangled-shuffled. فهو يمرّ على أبجدية صغيرة بترتيب مخلوط،
وفي تشويش VM يحصل كل متغير عام أُعيدت تسميته على البادئة vm (تُضاف قبل أي identifiersPrefix تضبطه، فيصبح checkout_
vm_checkout_...). ويُخزَّن الترتيب
المخلوط مؤقتًا لكل عملية، لذا فإن الملفات المشوَّشة في العملية نفسها، أو بقيمة seed ثابتة نفسها، تستمد أسماءها من التسلسل
نفسه، فيحمل أول متغير عام في كل ملف الاسم نفسه، والثاني اسمًا مشتركًا آخر، وهكذا.
يُشوَّش كل ملف على حدة، ويبدأ المولِّد من أول تسلسله من جديد لكل ملف. وعندما ينتهي ملفان في النطاق نفسه، تتعارض
الأسماء. فيقع تصريحان let vmd في المستوى الأعلى ضمن النطاق نفسه، ويرفض المحلِّل التصريح الثاني.
يصرّح كل ملف مشوَّش باستخدام VM باسم واحد لبيئة التشغيل في المستوى الأعلى بلا لاحقة، وهذا وحده يكفي لحدوث التعارض.
ويجعل renameGlobals: true الأمر أسوأ بكثير: إذ يصبح كل تصريح في المستوى الأعلى اسمًا قصيرًا من نوع vm*، وتفقد
الأسماء الخاصة ببيئة التشغيل لاحقتها الفريدة.
الحلول
يُفضَّل التحزيم أولًا، ثم تشويش الحزمة مرة واحدة. وإذا شوّشت الملفات منفصلةً وكانت السكربتات تتشارك نطاقًا عامًا واحدًا، فاختر أحد الحلول التالية:
فعّل
randomIdentifiersPrefix(موصى به)تحصل كل عملية تشويش على بادئة عشوائية تُضاف إلى بداية كل معرِّف عام (وفي تشويش VM تحلّ محل البادئة الافتراضية
vm). فلا تعود الأسماء من الملفات المختلفة تتشارك نطاق أسماء واحدًا، وتختفي التعارضات دون أن تضطر إلى تنسيق البادئات يدويًا.اضبط
identifiersPrefixفريدًا لكل ملفمرِّر يدويًا بادئة مختلفة عند تشويش كل ملف (مثل
identifiersPrefix: 'auth_'لملف، وcheckout_لآخر). هذا فعّال، لكنه عرضة للأخطاء إذا كانت لديك ملفات كثيرة، لذا يُفضَّل الخيار العشوائي أعلاه.بدّل
identifierNamesGeneratorإلىhexadecimalتستخدم الأسماء الست عشرية فضاء مفاتيح أكبر بكثير، فيقلّ كثيرًا احتمال أن يُنتج ملفان المعرِّف نفسه، لكن التفرّد غير مضمون. المقابل: المعرِّفات أطول من ناتج
mangled-shuffled، فتصبح الحزمة أكبر قليلًا.استخدم واجهة الدفعات متعددة الملفات، أو تحقّق من إضافة المجمِّع لديك
تضيف لوحة التحكم بادئة مميزة لكل ملف ضمن دفعة واحدة متعددة الملفات (الخطط المدفوعة)؛ أما الملفات من دفعات منفصلة فقد تتعارض مع ذلك. وإذا كنت تستخدم إضافة للمجمِّع، فتحقّق من سلوكها بدلًا من افتراض أنها تفعل الشيء نفسه. وإذا كنت تستدعي حزمة
javascript-obfuscatorأو API بنفسك، فعليك تفعيل البادئة بنفسك.
للتحقق من الإصلاح، أعد البناء وأعد تحميل التطبيق المُجمَّع وتأكّد من اختفاء SyntaxError. يجب ألا يعود الاسم الوارد في
رسالة الخطأ القديمة مُصرَّحًا به في أكثر من جزء؛ فالبادئة تغيّر كل اسم مولَّد، لذا فإن أمر grep أعلاه لا يخبرك إلا عن ذلك
الاسم بعينه، لا عن الأسماء الجديدة.
خيارات ذات صلة
randomIdentifiersPrefix: بادئة عشوائية لكل بناء (موصى به)identifiersPrefix: نص بادئة صريحidentifierNamesGenerator: شكل الأسماء (mangledوhexadecimalو…)
