أصول Javascript في مكون سمة

أنا أحاول بناء مكون لمعاينة ملفات STL. توجد مكتبة جافا سكريبت ممتازة لهذا الغرض، لكنني لست متأكدًا من كيفية جعلها تعمل داخل مكون السمة.

إنها جافا سكريبت عادية وليست ES6، مما يعني على ما أعتقد أنني لا يمكنني ببساطة وضعها في مجلد “javascripts” واستيرادها، أليس كذلك؟ بالإضافة إلى ذلك، يبدو أن المكتبة تعتمد على الاستيراد من وسم سكريبت (script tag).

لذا، يمكنني إنشاء وسم سكريبت وإضافته إلى رأس المستند، لكن كيف أعرف اسم ملف المكتبة JS؟ أيضًا، تتكون المكتبة من عدة ملفات JS، وتفترض أن هذه الملفات ستكون متاحة في نفس المجلد. ثم تقوم بإنشاء أوسمة سكريبت إضافية لتحميل باقي المكتبة.

إذن، هل يجب وضع هذه الملفات في مجلد “javascripts”؟ أم يجب معاملتها كأصول (assets)؟ أقرب شيء أعثر عليه لفعل شيء مشابه هو إضافة discourse-math، لكن إذا أمكن، سأفضل الاحتفاظ بهذا كمكون سمة.

يبدو أن هذا يوضح كيفية القيام بذلك لـ إضافة: How to ship javascript library with plugin?
لم أجد حتى الآن أي شيء خاص بمكون السمة.

لا أعرف، لكنك لا تملك إجابات جيدة!

الخطوة التالية التي يجب النظر إليها هي… الأمر… المتعلق بتضمين ملفات أخرى في مكون السمة.

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

لا أعتقد ذلك، أظن أن كل مكون يحصل على دليله الافتراضي الخاص. شيء مثل discourse/theme-10/… لذا لتحميل الأشياء من هناك، يجب أن أعرف على الأقل ما هو الدليل بطريقة ما.

إعجاب واحد (1)

يبدو أن أسماء الأصول يمكن الوصول إليها فقط كمتغيرات، والأسماء الحقيقية هي أرقام طويلة ومعقدة، لذا لن يعمل هذا أيضًا.
يبدو نوعًا ما أنه لا توجد طريقة للقيام بذلك كمكون في الوقت الحالي، لذا سأقوم بتحميل ملفات JS عبر nginx والوصول إليها بهذه الطريقة مؤقتًا. وهذا يعني على الأرجح أن هذا المكون سيعمل معي فقط للأسف.

يمكنك إضافة وسم السكربت العادي إلى ملف header.html داخل مكون السمة الخاص بك.

يعمل التثبيت الجانبي!
مرة واحدة فقط. :frowning:

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

صحيح، لكن كود viewstl ليس مخصصًا للدمج المباشر.
مع التحميل الجانبي، وضعت وسم سكربت مثل هذا في common/head_tag.html:

<script src="/xi/viewstl/stl_viewer.min.js"></script>

(يتم تقديم /xi/ من nginx)

Discourse هو تطبيق صفحة واحدة (SPA). لا يمكنك ببساطة إضافة سكريبت يعمل عند تحميل الصفحة (onLoad) لأن ذلك لن يعمل. ستحتاج إلى الربط بنقاط نهاية واجهة برمجة التطبيقات (API endpoints) الخاصة بنا. راجع دليل المطور لسمات Discourse

حسناً، سأحاول استبدال طريقة التحميل المعتمدة على وسوم السكربت القديمة بشيء آخر.

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

على أي حال، إليك ما أحصل عليه، ربما يتمكن أحد من المساعدة:

إليك عبارة الاستيراد التي لا تعمل:

وهنا الخطأ الذي أحصل عليه:

_application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333 حدث خطأ في المكون/الموضوع "STL previews": خطأ: تعذر العثور على الوحدة `discourse/theme-17/three/build/three.module` المستوردة من `discourse/theme-17/stlviewer/StlViewer`
    at h (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74612)
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74581
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74665
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74490
    at require (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74663)
    at h (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74616)
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74581
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74665
    at _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74490
    at require (_ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:74663)
(anonymous) @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74333
u @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74325
initialize @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:74304
i.initialize @ _application-547e0be66174ffd22a4d74fd8b568f6a3892a266cff18cb078c08d6357227acb.js:7723
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49335
e.each @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67724
e.walk @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67638
e.each @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67568
e.topsort @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67576
_runInitializer @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49361
runInitializers @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:49333
_bootSync @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:47768
domReady @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:47668
n._run @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67275
n._join @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:67251
n.join @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:66968
f @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:53760
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:53864
l @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3776
c @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3844
setTimeout (async)
(anonymous) @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3882
u @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3510
fireWith @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3640
fire @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3648
u @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3510
fireWith @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:3640
ready @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:4120
z @ _ember_jquery-36a23101c869ab0dc53fc908de69adb785731593573d32bdeef416acc1076ef4.js:4130

هل النقطة ‘.’ فاصل سحري للوحدات أم شيء من هذا القبيل؟

أعتقد أن ‘.’ سحري، لأنه عند إعادة تسمية three.module.js إلى three_module.js، أواجه مشكلة مختلفة تمامًا: لا يمكنني تحميل المظهر بعد الآن (خطأ 500).

لقد جربت أيضًا استيراد three.js مباشرة من CDN باستخدام عنوان URL كامل، لكن يبدو أن هذا لا يعمل أيضًا…

إذا كنت تحتاج فقط إلى تحميل عنصر جافا سكريبت في الوقت المناسب (Just In Time)، كما أفعل هنا حيث أحتاج إلى مكتبة D3، فيمكنك استخدام هذا النمط مع Loadscript:

وأعلى قليلاً:

يعيد Loadscript كائن Promise، لذا يجب عليك استدعاء .then على النتيجة. (لست متأكداً تماماً، لكن أفترض أن النتيجة مخزنة ضمنياً، مما يعني أنها ستعمل بسرعة أكبر في المرة الثانية وما بعدها.)

كما ترون، يمكنك ربطها معاً لتحميل عدة سكريبتات واحدة تلو الأخرى.

لاحظ أنها تعمل داخل مكون Ember ويتم استدعاؤها من خلال خطاف didInsertElement. لمزيد من المعلومات حول مكونات Ember، راجع: Templates are HTML - Components - Ember Guides

لاحظ أيضاً أن السكريبتات نفسها موجودة في مجلد javacsripts/assets.

استندت في هذا إلى كود المستخدم @j.jaffeux المستخدم في مكان ما لتحميل سكريبت مختلف تماماً (شكراً جوفري! :+1:)

إليك مثال من Discourse:

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

4 إعجابات

مثير للاهتمام، شكرًا على التوجيهات.
سأحاول استخدام loadScript وأرى ما إذا كان ذلك يمكن أن يحل مشكلتي.

إعجابَين (2)

قررت تجربة نهج أبسط.
فقط أقوم بإنشاء إطار مضمن (iframe) يحمل صفحة HTML يمكنها تنفيذ جميع عمليات السكربت المعقدة لجعل المعاينة تعمل. حاليًا، ليس الأمر بتنسيق قابل لإعادة الاستخدام، لكن سيكون من السهل نسبيًا إنشاء إضافة له.