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

بديل حديث لـ importScripts().

الخلفية

كانت وحدات ES مفضّلة لدى المطوّرين منذ فترة. بالإضافة إلى عدد من المزايا الأخرى، فهي تقدم وعودًا بتنسيق وحدات عمومية حيث يمكن إصدار الرمز الذي تمت مشاركته مرة واحدة وتشغيله في المتصفحات وفي أوقات تشغيل بديلة مثل Node.js. على الرغم من أنّ جميع المتصفحات الحديثة توفّر بعض التوافق مع وحدات ES، إلا أنها لا توفر جميعها الدعم في أي مكان يمكن تشغيل فيه هذا الرمز. على وجه التحديد، بدأنا للتوّ توفّر إمكانية استيراد وحدات 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 دعمًا في إصدار معاينة 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 في مشغِّلي الخدمات، ولكن لم يكن الأمر كذلك حتى الآن.

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

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

_صورة من تصوير فلادو باونوفيك على UnLaunch_