خرائط المصدر: سريعة وسهلة





يتم استخدام آلية خرائط المصدر لتعيين رموز المصدر للبرنامج إلى البرامج النصية التي تم إنشاؤها على أساسها. وعلى الرغم من أن هذا الموضوع ليس جديدا وسبق أن كتبت عددا من المقالات حول ذلك (على سبيل المثال، هذا ، هذا و هذا واحد )، وبعض جوانب لا تزال بحاجة الى توضيح. المقالة المقدمة هي محاولة لتنظيم وتنظيم كل ما هو معروف في هذا الموضوع في شكل موجز ويسهل الوصول إليه.



تعتبر المقالة Source Maps فيما يتعلق بتطوير العميل في بيئة المتصفحات الشائعة (على سبيل المثال ، DevTools Google Chrome) ، على الرغم من أن نطاقها غير مرتبط بأي لغة أو بيئة معينة. المصدر الرئيسي لخرائط المصدر هو بالطبع المعيار ، على الرغم من أنه لم يتم اعتماده بعد (الحالة - الاقتراح) ، ولكن لا يزال مدعومًا على نطاق واسع من قبل المتصفحات.



بدأ العمل على خرائط المصدر في نهاية العقد الأول من القرن الحادي والعشرين ؛ تم إنشاء الإصدار الأول للمكون الإضافي Firebug Closure Inspector. تم إصدار الإصدار الثاني في عام 2010 واحتوى على تغييرات فيما يتعلق بتقليل حجم ملف الخريطة. تم تطوير الإصدار الثالث كجزء من التعاون بين Google و Mozilla وتم اقتراحه في 2011 (المراجعة الأخيرة في 2013).



حاليًا ، في بيئة تطوير العميل ، هناك حالة حيث لا يتم دمج شفرة المصدر تقريبًا أبدًا في صفحة الويب تقريبًا ، ولكنها تمر بمراحل مختلفة من المعالجة قبل ذلك: التصغير ، التحسين ، التسلسل ، علاوة على ذلك ، يمكن كتابة شفرة المصدر نفسها بلغات تتطلب الترجمة ... في هذه الحالة ، لأغراض التصحيح ، هناك حاجة إلى آلية تسمح لك بمراقبة التعليمات البرمجية الأصلية التي يمكن قراءتها في مصحح الأخطاء.



تتطلب خرائط المصدر الملفات التالية للعمل:



  • إنشاء ملف جافا سكريبت بالفعل
  • مجموعة من الملفات مع كود المصدر تستخدم لانشائه
  • ملف الخريطة الذي يعينهم على بعضهم البعض


ملف الخريطة



تستند جميع أعمال خرائط المصدر إلى ملف خريطة ، والذي قد يبدو ، على سبيل المثال ، على النحو التالي:



{
    "version":3,
    "file":"index.js",
    "sourceRoot":"",
    "sources":["../src/index.ts"],
    "names":[],
    "mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,SAAS,SAAS;IACd,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;",
    "sourcesContent": []
}


عادة ما يكون اسم ملف الخريطة هو مجموع اسم البرنامج النصي الذي ينتمي إليه ، مع إضافة الامتداد ".map" ، bundle.js - bundle.js.map. هذا ملف json عادي يحتوي على الحقول التالية:



  • "الإصدار" - إصدار خرائط المصدر ؛
  • "ملف" - (اختياريًا) اسم الملف الذي تم إنشاؤه ، والذي ينتمي إليه ملف الخريطة الحالي ؛
  • "SourceRoot" - بادئة (اختيارية) لمسارات ملفات المصدر ؛
  • "المصادر" - قائمة بمسارات ملفات المصدر (يتم حلها بشكل مشابه لعناوين src لعلامة النص البرمجي ، يمكنك استخدام file: //.) ؛
  • "الأسماء" - قائمة بأسماء المتغيرات والوظائف التي خضعت لتغيير في الملف الذي تم إنشاؤه ؛
  • "Mappings" - إحداثيات تعيين المتغيرات ووظائف الملفات المصدر للملف الذي تم إنشاؤه بتنسيق Base64 VLQ ؛
  • "SourcesContent" - (اختياري) في حالة ملف خريطة قائم بذاته ، قائمة بالخطوط ، يحتوي كل منها على نص مصدر الملف من المصادر ؛


تنزيل خرائط المصدر



من أجل أن يقوم المتصفح بتحميل ملف الخريطة ، يمكن استخدام إحدى الطرق التالية:



  • جاء ملف جافا سكريبت مع رأس HTTP: SourceMap: <url> (سابقًا تم إهمال X-SourceMap الآن: <url>)
  • يحتوي ملف JavaScript الذي تم إنشاؤه على تعليق خاص على النموذج:


//# sourceMappingURL=<url> ( CSS /*# sourceMappingURL=<url> */)


وبالتالي ، بعد تحميل ملف الخريطة ، سيسحب المتصفح المصادر من حقل "المصادر" ، وباستخدام البيانات الموجودة في حقل "التعيينات" ، سيتم عرضها في البرنامج النصي الذي تم إنشاؤه. في علامة التبويب Sources DevTools ، يمكنك العثور على كلا الخيارين.



يمكن استخدام الملف: // pseudoprotocol لتحديد المسار. أيضًا ، يمكن أن يتضمن <url> محتويات ملف الخريطة بالكامل في ترميز Base64. في مصطلحات Webpack ، تسمى خرائط المصدر المماثلة خرائط المصدر المضمنة.



//# sourceMappingURL=data:application/json;charset=utf-8;base64,<source maps Base64 code>


أخطاء تحميل خرائط المصدر
, map- -, Network DevTools. , map-, Console DevTools : «DevTools failed to load SourceMap: ...». , : «Could not load content for ...».



ملفات الخرائط المستقلة



يمكن تضمين رمز الملف المصدر مباشرة في ملف الخريطة في حقل "sourcesContent" ، إذا كان هذا الحقل متاحًا ، فلا حاجة لتنزيله بشكل منفصل. في هذه الحالة ، لا تعكس أسماء الملفات في "المصادر" عنوانها الحقيقي ويمكن أن تكون عشوائية تمامًا. لهذا السبب ، يمكنك أن ترى مثل هذه "البروتوكولات" الغريبة في علامة التبويب Sources DevTools: webpack: //، ng: // ، إلخ.



تعيينات



جوهر آلية التعيين هو أن الإحداثيات (الصف / العمود) لأسماء المتغيرات والوظائف في الملف الذي تم إنشاؤه يتم تعيينها للإحداثيات في ملف شفرة المصدر المقابل. لكي تعمل آلية العرض ، يلزم توفر المعلومات التالية:



(# 1) رقم السطر في الملف الذي تم إنشاؤه ؛

(# 2) رقم العمود في الملف الذي تم إنشاؤه ؛

(# 3) فهرس المصدر في "المصادر" ؛

(# 4) رقم سطر المصدر ؛

(# 5) رقم عمود المصدر ؛



كل هذه البيانات موجودة في حقل "التعيينات" ، وقيمتها عبارة عن سلسلة طويلة ذات بنية خاصة وقيم مشفرة في Base64 VLQ.



يتم تقسيم السطر بالفاصلات المنقوطة (؛) إلى أقسام تتوافق مع الخطوط الموجودة في الملف الذي تم إنشاؤه (# 1).



يتم فصل كل قسم بفواصل (،) إلى مقاطع ، يمكن أن يحتوي كل منها على 1،4 أو 5 قيم:



  • رقم العمود في الملف الذي تم إنشاؤه (# 2) ؛
  • فهرس المصدر في "المصادر" (# 3) ؛
  • رقم سطر المصدر (# 4) ؛
  • رقم عمود المصدر (# 5) ؛
  • فهرس اسم المتغير / الوظيفة من قائمة "الأسماء" ؛


تكون قيم أرقام الأسطر والأعمدة نسبية ، وتشير إلى الإزاحة بالنسبة للإحداثيات السابقة والأولى فقط من بداية الملف أو القسم.



كل قيمة عبارة عن رقم Base64 VLQ. VLQ (الكمية ذات الطول المتغير) هو مبدأ ترميز عدد كبير بشكل تعسفي باستخدام عدد عشوائي من الكتل الثنائية ذات الطول الثابت.



تستخدم خرائط المصدر كتل من ستة بتات ، مرتبة من الأدنى إلى الأعلى. يتم الاحتفاظ بأعلى 6 بتات من كل كتلة (بتة استمرار) ، إذا تم تعيينها ، فإن الكتلة الحالية يتبعها الكتلة التالية من نفس الرقم ، إذا تمت إعادة التعيين ، فسيتم اكتمال التسلسل.



نظرًا لأنه يجب أن تحتوي خرائط المصدر على علامة ، فإن بت الإشارة محجوز أيضًا لها ، ولكن فقط في الكتلة الأولى من التسلسل. كما هو متوقع ، يعني بت إشارة تعيين رقم سالب.



وبالتالي ، إذا كان يمكن ترميز الرقم بكتلة واحدة ، فلا يمكن أن يكون modulo 15 (1111 2 ) ، حيث أنه في أول كتلة من ستة بتات من التسلسل يتم حجز بتين: سيتم دائمًا مسح بت البت ، سيتم تعيين بت الإشارة بناءً على علامة الرقم.



يتم تعيين كتل VLQ سداسية بتشفير Base64 ، حيث يتم تعيين كل تسلسل سداسي البت لحرف ASCII محدد.







نقوم بفك تشفير الرقم mE. قلب الطلب ، الجزء الأخير هو Em. نقوم بفك تشفير الأرقام من Base64: E - 000100، m - 100110. في الأول ، نتجاهل بت الاستمرارية العالية واثنين من الأصفار البادئة - 100. في الثانية نتجاهل الاستمرارية العالية وبتات الإشارة المنخفضة (بت مسح الإشارة - الرقم موجب) - 0011. ونتيجة لذلك ، نحصل على 100 0011 2 ، الذي يتوافق مع



العلامة العشرية 67. من الممكن في الاتجاه المعاكس ، ترميز 41. رمزه الثنائي هو 101001 2، نقوم بتقسيمها إلى كتلتين: الجزء العلوي هو 10 ، الجزء الأصغر (دائمًا 4 بت) هو 1001. أضف أهم بت استمرار (مسح) إلى الجزء العلوي والأصفار الثلاثة الرائدة - 000010. أضف أهم بت استمرار (مجموعة) إلى الجزء السفلي و بت الإشارة المنخفضة (مسح - رقم موجب) هو 110010. نقوم بتشفير الأرقام في Base64: 000010 - C ، 110010 - y. نقوم بعكس الطلب ، ونتيجة لذلك ، نحصل على yC. المكتبة التي



تحمل الاسم نفسه مفيدة جدًا للعمل مع VLQ .



All Articles