استخدام نافذة مربع العمل

وحدة Workbox واحدة التي لم تتم تغطيتها بشكل كبير حتى الآن في هذه المستندات هي workbox-window، وهي مجموعة من الوحدات التي سيتم تشغيلها في window. في ما يلي أهداف هذه الوحدة:

  • لتبسيط عملية تسجيل مشغّلي الخدمات وإجراء تعديلات عليه من خلال مساعدة المطوّرين على تحديد اللحظات المهمة في دورة حياة عاملي الخدمات، ما يُسهِّل عليهم الاستجابة في تلك اللحظات.
  • لمنع المطوّرين من ارتكاب أخطاء شائعة، مثل تسجيل عامل خدمة في النطاق الخطأ
  • لتبسيط المراسلة بين window ونطاق مشغّل الخدمات.

استيراد workbox-window واستخدامه

التصدير الذي ستستخدمه غالبًا من workbox-window هو الفئة Workbox، والتي يمكنك استيرادها في Node أو من شبكة توصيل المحتوى (CDN) في صفحة ويب.

إنشاء حزمة محلية

إذا كانت سلسلة الأدوات تتضمّن أداة تجميع مثل webpack أو Rollup، يمكنك تجميع workbox-window محليًا.

أولاً، عليك تثبيت workbox-window كبرنامج يعتمد على الإنتاج لتطبيقك:

npm install workbox-window --save

بعد ذلك، في JavaScript الخاص بالتطبيق، يمكنك import فئة Workbox من workbox-window:

<script type="module">
import {Workbox} from 'workbox-window';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  wb.register();
}
</script>

على الرغم من أنّ workbox-window صغير جدًا، يمكنك تقسيمه عن منطق التطبيق الأساسي لموقعك الإلكتروني باستخدام import الديناميكي، ما يمكن أن يقلل من حجم الحزمة الرئيسية لصفحتك:

<script type="module">
if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}
</script>

استخدام شبكة توصيل المحتوى (CDN)

رغم أنّ الطريقة الأسهل لاستخدام workbox-window هي عبر استيرادها من شبكة توصيل محتوى (CDN):

<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    wb.register();
  }
</script>

ستلاحظ أنّ العنصر <script> في المثال أعلاه يستخدم السمة type="module". هذا الإجراء مطلوب إذا كنت تريد استخدام عبارات import ثابتة في المتصفّح بدون خطوة إنشاء. إنّ جميع المتصفحات الرئيسية التي تتيح استخدام مهام الخدمة تتيح أيضًا استخدام وحدات JavaScript، لذا لا بأس بعرض هذا الرمز البرمجي لأي متصفح، لأنّ المتصفحات القديمة ستتجاهل عناصر <script> التي تحتوي على قيمة سمة type‏="module".

تسجيل مشغّل الخدمات

يتم تسجيل مشغّل خدمات في workbox-window باستخدام طريقة register لفئة Workbox على النحو التالي:

import {Workbox} from 'workbox-window';

const wb = new Workbox('/sw.js');
wb.register();

قد يبدو أنّ هذا الإجراء هو نفسه تسجيل عامل خدمة بنفسك باستخدام navigator.serviceWorker.register. ومع ذلك، سيتولى Workbox.register الانتظار حتى حدث window load قبل تسجيل مشغّل الخدمات. ويُفضَّل ذلك في الحالات التي يتم فيها استخدام ميزة التخزين المؤقت المُسبَق لتجنُّب التنافس على النطاق الترددي الذي قد يؤخّر بدء تشغيل الصفحة.

الاتصال بين window ونطاق مشغّل الخدمات

يكون للنُسخ العاملة في الخلفية نطاق خاص بها منفصل عن window، ولا يمكنها الوصول إلا إلى مجموعة فرعية من واجهات برمجة التطبيقات المتاحة في window. ومع ذلك، من الممكن الاتصال بين window ومشغّل الخدمات. يتيح workbox-window التواصل بسهولة بين النطاقَين باستخدام طريقة messageSW في وحدة workbox-window.

يستخدم Workbox تنسيقًا محدّدًا للرسائل، وهو عنصر يتضمّن السمات التالية:

  • type هي سلسلة فريدة مطلوبة تحدد الرسالة. يجب أن يكون التنسيق بأحرف كبيرة مع شرطات سفلية تفصل بين الكلمات (على سبيل المثال، CACHE_URLS).
  • meta هي سلسلة اختيارية تمثّل اسم حزمة Workbox التي تُرسِل الرسالة، ويتم عادةً حذفها.
  • payload هي مَعلمة اختيارية تمثّل البيانات التي تريد إرسالها. يمكن أن يكون أي نوع بيانات.

في ما يلي مثال على آلية عمل messageSW، بدءًا من الرمز البرمجي في worker الخدمة:

// sw.js
const SW_VERSION = '1.0.0';

self.addEventListener('message', (event) => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

ثم الرمز التالي في صفحة الويب الخاصة بك:

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

هناك العديد من الحالات التي يمكن فيها أن يكون التواصل بين عامل الخدمة وwindow مفيدًا، مثل إشعار المستخدم عند توفّر تحديث لعامل الخدمة. تعتمد هذه الوصفة على طريقة مساعدة خاصة للسمة self.skipWaiting تُسمى messageSkipWaiting، والتي ترسل رسالة بقيمة type تبلغ SKIP_WAITING.