وحدات ES في مشغّلي الخدمات

بديل حديث لـImportScripts()

الخلفية

لطالما كانت وحدات ES المفضلة لدى المطوّرين منذ فترة. بالإضافة إلى عدد من المزايا الأخرى، فإنها تعِد تنسيق وحدات عامة يمكن من خلاله إصدار الرمز المشترك مرة واحدة وتشغيله في المتصفحات وفي بيئات تشغيل بديلة، مثل Node.js. على الرغم من أنّ جميع المتصفّحات الحديثة تتيح بعض وحدات ES، إلا أنّها لا توفّر الدعم في أي مكان يمكن تشغيل هذه الرموز فيه. على وجه التحديد، بدأ دعم استيراد وحدات اللغة الإسبانية داخل مشغّل الخدمات في المتصفّح بات متاحًا على نطاق أوسع.

توضّح هذه المقالة الحالة الحالية لتوفُّر وحدات ES المتوفّرة لدى مشغّلي الخدمات في المتصفحات الشائعة، بالإضافة إلى بعض العيوب التي يجب تجنّبها وأفضل الممارسات المتعلقة بشحن رموز مشغّل الخدمات المتوافقة مع الإصدارات القديمة.

حالات الاستخدام

إنّ حالة الاستخدام المثالية لوحدات ES داخل مشغّلي الخدمات هي تحميل مكتبة حديثة أو رمز إعداد تتم مشاركته مع بيئات تشغيل أخرى متوافقة مع وحدات ES.

وقد استلزمت محاولة مشاركة الرمز بهذه الطريقة قبل وحدات ES استخدام تنسيقات وحدات "عامة" مثل UMD التي تتضمّن نصًا نموذجيًا غير ضروري وكتابة رموز أجريت تغييرات على المتغيّرات المعروضة عالميًا.

إنّ النصوص البرمجية التي يتم استيرادها من خلال وحدات ES يمكن أن تؤدي إلى بدء مسار تعديل عامل الخدمة في حال تغيّر محتواها، بما يتماشى مع سلوك importScripts().

القيود الحالية

عمليات الاستيراد الثابتة فقط

يمكن استيراد وحدات ES بإحدى الطريقتين التاليتين: إما ثابتًا أو باستخدام بنية import ... from '...' أو ديناميكيًا باستخدام طريقة import(). داخل مشغّل الخدمات، لا يتوفّر حاليًا سوى البنية الثابتة.

يشبه هذا القيد قيودًا مماثلة يتم فرضها على استخدام importScripts(). لا تعمل الطلبات الديناميكية المُرسَلة إلى importScripts() داخل مشغّل الخدمات، ويجب إكمال جميع طلبات importScripts()، المتزامنة بطبيعتها، قبل أن يكمل عامل الخدمة مرحلة install الخاصة به. ويضمن هذا التقييد معرفة المتصفّح لجميع رموز JavaScript اللازمة لتنفيذ مشغّل الخدمات أثناء التثبيت وإمكانية تخزينها مؤقتًا.

في النهاية، قد تتم إزالة هذا الحظر ويُسمح بعمليات استيراد وحدة ES الديناميكية. في الوقت الحالي، تأكد من استخدام البنية الثابتة فقط داخل مشغّل الخدمات.

ماذا عن العمال الآخرين؟

لقد أصبح الدعم المتوفّر لوحدات ES في العاملين "المخصصين"، تلك التي تم إنشاءها باستخدام new Worker('...', {type: 'module'})، أصبح متاحًا على نطاق واسع، وأصبح متاحًا في Chrome وEdge منذ الإصدار 80، بالإضافة إلى الإصدارات الأخيرة من Safari. يتيح العاملون المتخصّصون استيراد وحدات ES الثابتة والديناميكية على حد سواء.

يتوافق Chrome وEdge مع وحدات ES في العاملين المشتركين منذ الإصدار 83، ولكن لا يتوافق أي متصفّح آخر في الوقت الحالي.

ليس هناك دعم لخرائط الاستيراد

تسمح استيراد خرائط لبيئات وقت التشغيل بإعادة كتابة محدّدات الوحدات، على سبيل المثال، إضافة عنوان URL لشبكة توصيل المحتوى (CDN) المفضّلة التي يمكن تحميل وحدات ES من خلالها.

على الرغم من أنّ الإصدار 89 من متصفّح Chrome وEdge أو الإصدارات الأحدث تتوافق مع خرائط الاستيراد، لا يمكن استخدامها حاليًا مع مشغّلي الخدمات.

المتصفحات المتوافقة

تتوفّر وحدات ES في مشغّلي الخدمات في Chrome وEdge بدءًا من الإصدار 91.

أضاف متصفّح Safari توافقًا مع إصدار Technology Preview 122، ومن المتوقَّع أن يرى المطوّرون هذه الوظيفة في الإصدار الثابت من Safari في المستقبل.

مثال على الرمز

هذا مثال أساسي لاستخدام وحدة ES مشتركة في سياق window لتطبيق الويب، وفي الوقت نفسه تسجيل مشغّل خدمات يستخدم وحدة ES نفسها:

// Inside config.js:
export const cacheName = 'my-cache';
// Inside your web app:
<script type="module">
  import {cacheName} from './config.js';
  // Do something with cacheName.

  await navigator.serviceWorker.register('es-module-sw.js', {
    type: 'module',
  });
</script>
// Inside es-module-sw.js:
import {cacheName} from './config.js';

self.addEventListener('install', (event) => {
  event.waitUntil((async () => {
    const cache = await caches.open(cacheName);
    // ...
  })());
});

التوافق مع الأنظمة القديمة

سيعمل المثال أعلاه بشكل جيد إذا كانت جميع المتصفّحات متوافقة مع وحدات اللغة الإسبانية في مشغّلي الخدمات، ولكن لم يكن الأمر كذلك اعتبارًا من هذه الكتابة.

لاستيعاب المتصفحات التي لا تتضمّن توافقًا، يمكنك تشغيل النص البرمجي لمشغِّل الخدمات من خلال أداة تجميع متوافقة مع وحدات ES لإنشاء مشغّل خدمات يتضمّن جميع رموز الوحدات المضمّنة وستعمل في المتصفحات القديمة. بدلاً من ذلك، إذا كانت الوحدات التي تحاول استيرادها متاحة مسبقًا بتنسيق IIFE أو UMD، يمكنك استيرادها باستخدام importScripts().

عندما يتوفّر إصداران من مشغّل الخدمات، إحداهما يستخدم وحدات ES والأخرى لا تستخدمه، ستحتاج إلى اكتشاف ما يتوافق مع المتصفح الحالي وتسجيل النص البرمجي لمشغّل الخدمات المقابل. لا تزال أفضل الممارسات لرصد الدعم غير منتظمة، ولكن يمكنك متابعة المناقشة الواردة في مشكلة GitHub هذه للحصول على اقتراحات.

_صورة التقطها "فلادو" Paunovic على موقع Unسباش_