تحميل مكتبات JavaScript عبر register_asset

لاحظت أن ملفات JS المضافة باستخدام register_asset عبر الإضافات يتم تمريرها كسلسلة نصية إلى دالة eval.

المشكلة مع eval هي أنها لا تضيف الكائن إلى النطاق العام (global scope)، كما نوقش هنا: https://stackoverflow.com/questions/4670805/javascript-eval-on-global-scope، وهو أمر ضروري لاستخدام مكتبة JS.

على وجه التحديد، كنت أحاول استخدام https://github.com/muaz-khan/RecordRTC/blob/master/RecordRTC.js في إضافة، لكن الدوال غير قابلة للوصول في ملفات Ember.

الحل البديل هو معالجة الملف باستخدام Webpack، مع استخدام libraryTarget مضبوطة على umd.

تمت معالجة العديد من المكتبات بهذه الطريقة، ويبدو أنها تعمل بشكل فوري.

الآن، لست خبيرًا في هذه الأمور، لكنني أتساءل فقط عما إذا كان من المنطقي أن يقوم Discourse بإضافة الأصول المسجلة إلى النطاق العام.

ملاحظة: أعتذر إذا بدا بعض هذا تافهًا. لم أتوقع أن أتعامل مع Webpack لجعل مكتبات JS تعمل مع Discourse، وهو ما دفعني لنشر هذه الملاحظة. :wink:

يبدو أن هناك شيئًا خاطئًا هنا - لقد راجعتُ إضافة lazyYT الخاصة بنا التي تتضمن أصلًا باستخدام register_asset، ولم تكن ضمن كتلة eval.

هل يمكنك تزويدي بمثال صغير لإضافة يعيد إنتاج المشكلة؟

أتساءل عما إذا كان هذا أثرًا جانبيًا غير مقصود لـ

(أي أن هذا يحدث فقط في وضع التطوير)

تساءلتُ عن ذلك أيضًا - إذا كان الأمر كذلك، فهناك حلول بديلة، لكنني أود مثالًا قابلًا للتكرار.

بالتأكيد.

مثير للاهتمام. يمكنني تشغيل الإضافة في بيئة الإنتاج للتحقق مما إذا كان الأمر كذلك.

@eviltrout
إضافة صغيرة تستخدم نفس المكتبة المذكورة في المنشور الأصلي GitHub - fzngagan/js-test · GitHub

لقد حاولت ببساطة استدعاء الدالة التي أضافتها المكتبة في المُهيئ (initializer)، وفي وحدة تحكم JavaScript (js console) حصلت على الخطأ ReferenceError: RecordRTC is not defined.

لقد استخدمت النسخة غير المصغرة (unminified) من المكتبة، مما قد يساعد في عملية التصحيح.

أيضًا، لقطة شاشة من تبويب sources لإظهار أن كل شيء تم تمريره إلى دالة eval.

من النتائج الأخرى التي توصلت إليها أن ملفات JavaScript المضمنة في كل من discourse-spoiler-alert و lazy-yt تقوم بحقن دوال في كائن jQuery العام، لكنها لا تعلن عن أي دوال على المستوى العلوي.

لقد تفحصتُ ملحقك (plugin) وأستطيع تأكيد أن eval موجود فقط في وضع التطوير. في وضع الإنتاج، سيتم إدراجه في النطاق العام (global scope). أدرك أن هذا ليس مثاليًا، لكنني أيضًا لا أعتقد أنه ينبغي توزيع المكتبات عادةً دون نوع من الدعم للوحدات (modules) (على سبيل المثال، UMD).

اقتراحي هو إعادة تغليف JS مع دعم من نوع UMD ثم استيراده (import)، لكن إعداد ذلك قد يكون معقدًا بعض الشيء إذا لم تكن لديك خبرة كبيرة في التعامل مع وحدات JS.

بدلاً من ذلك، توجد طريقة سهلة لجعل هذا يعمل عن طريق تعديل RecordRTC.js وإضافة السطر التالي:

window.RecordRTC = RecordRTC;

سيكون الأمر أفضل إذا قمت بتغليف محتويات الملف بالكامل في IIFE:

(function(exports) {
  // ضع محتويات الملف الأصلية هنا
  exports.RecordRTC = RecordRTC;
})(window);

نعم، أنا أتفق معك. كثير منها يُوزَّع بهذه الطريقة ويعمل بسلاسة. شكرًا لك على البحث في هذا الأمر وللتأكيد :+1: لقد اتبعتُ نهج تغليف المكتبة عبر webpack وهو يعمل دون الحاجة حتى إلى استيرادها. كان ينبغي لي اختبارها في وضع الإنتاج على أي حال.