٩ يونيو ٢٠٢٠

Dynamic imports

بيانات التصدير والاستيراد التي تناولناها في الفصول السابقة تسمى “ثابتة”. النحو بسيط للغاية وصارم.

أولاً ، لا يمكننا إنشاء أي لـ “استيراد” ديناميكيًا.

يجب أن يكون مسار الوحدة النمطية سلسلة أولية ، ولا يمكن أن يكون استدعاء دالة. هذا لن يعمل:

import ... from getModuleName(); // Error, only from "string" is allowed

Second, we can’t import conditionally or at run-time:

if(...) {
  import ...; // Error, not allowed!
}

{
  import ...; // Error, we can't put import in any block
}

وذلك لأن الاستيراد /التصدير يهدف إلى توفير العمود الفقري لبنية الكود. هذا شيء جيد ، حيث يمكن تحليل بنية الكود ، ويمكن تجميع الوحدات وتجميعها في ملف واحد بواسطة أدوات خاصة ، ويمكن إزالة عمليات التصدير غير المستخدمة (“اهتزاز الشجرة”). هذا ممكن فقط لأن هيكل الواردات / الصادرات بسيط وثابت.

ولكن كيف يمكننا استيراد وحدة نمطية ديناميكيًا حسب الطلب؟

The import() expression

يقوم التعبير “import (module)” بتحميل الوحدة النمطية وإرجاع الوعد الذي يتم حله في كائن الوحدة النمطية الذي يحتوي على كافة عمليات التصدير الخاصة به. يمكن استدعاؤها من أي مكان في التعليمات البرمجية.

يمكننا استخدامه ديناميكيًا في أي مكان من الرمز ، على سبيل المثال:

let modulePath = prompt("Which module to load?");

import(modulePath)
  .then(obj => <module object>)
  .catch(err => <loading error, e.g. if no such module>)

أو يمكننا استخدام let module = انتظار الاستيراد (modulePath) إذا كان داخل دالة غير متزامنة.

على سبيل المثال ، إذا كان لدينا الوحدة التالية say.js:

// 📁 say.js
export function hi() {
  alert(`Hello`);
}

export function bye() {
  alert(`Bye`);
}

… ثم يمكن أن يكون الاستيراد الديناميكي مثل هذا:

let {hi, bye} = await import('./say.js');

hi();
bye();

أو ، إذا كان say.js يحتوي على التصدير الافتراضي:

// 📁 say.js
export default function() {
  alert("Module loaded (export default)!");
}

… ثم ، للوصول إليه ، يمكننا استخدام خاصية “افتراضي” لكائن الوحدة:

let obj = await import('./say.js');
let say = obj.default;
// or, in one line: let {default: say} = await import('./say.js');

say();

هنا المثال كاملا:

نتيجة
say.js
index.html
export function hi() {
  alert(`Hello`);
}

export function bye() {
  alert(`Bye`);
}

export default function() {
  alert("Module loaded (export default)!");
}
<!doctype html>
<script>
  async function load() {
    let say = await import('./say.js');
    say.hi(); // Hello!
    say.bye(); // Bye!
    say.default(); // Module loaded (export default)!
  }
</script>
<button onclick="load()">Click me</button>
برجاء الملاحظة:

تعمل عمليات الاستيراد الديناميكية في النصوص العادية ، ولا تتطلب ذلك script type="module".

برجاء الملاحظة:

على الرغم من أن `` import () يشبه استدعاء دالة ، إلا أنها بناء جملة خاص يحدث فقط لاستخدام الأقواس (على غرار super () `).

لذلك لا يمكننا نسخ “استيراد” إلى متغير أو استخدام “استدعاء / تطبيق” معه. إنها ليست وظيفة.

خريطة الدورة التعليمية

التعليقات

إقرأ هذا قبل أن تضع تعليقًا…
  • إذا كان لديك اقتراحات أو تريد تحسينًا - من فضلك من فضلك إفتح موضوعًا فى جيتهاب أو شارك بنفسك بدلًا من التعليقات.
  • إذا لم تستطع أن تفهم شيئّا فى المقال - وضّح ماهو.
  • إذا كنت تريد عرض كود استخدم عنصر <code> ، وللكثير من السطور استخدم <pre>، ولأكثر من 10 سطور استخدم (plnkr, JSBin, codepen…)