نقل البيانات من الإصدار 4 إلى الإصدار 5 من Workspace

يركز هذا الدليل على التغييرات الأساسية التي تمّت في الإصدار 5 من Workbox، مع أمثلة على التغييرات التي يجب إجراؤها عند الترقية من الإصدار 4 من Workbox.

تغييرات قد تؤدي إلى أعطال

إعادة تسمية فئات المكوّنات الإضافية

تضمّنت عدة حِزم من الإصدار 4 من Workbox فئات باسم Plugin. في الإصدار 5، تمت إعادة تسمية هذه الفئات لتتوافق مع معرّف حزمة النمط + Plugin:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

وينطبق هذا التغيير سواء كنت تستخدم الفئات من خلال عمليات استيراد الوحدات أو من خلال مساحات أسماء workbox.*.

نقطة الاستبدال التلقائية لبيان التخزين المؤقت المُسبَق

في السابق، عند استخدام أحد أدوات الإنشاء في وضع "إدراج البيان"، كان يتم التحقّق من ملف الخدمة العاملة المصدر بحثًا عن precacheAndRoute([])، مع استخدام الصفيف الفارغ [] كعنصر نائب للنقطة التي تم فيها إدراج بيان التخزين المؤقت المُسبَق.

في الإصدار 5 من Workbox، تغيّر منطق الاستبدال، ويتم الآن استخدام self.__WB_MANIFEST تلقائيًا كنقطة الحقن.

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

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

تمت إعادة تسمية الخيارَين blacklist وwhitelist اللذين كانا متاحَين في السابق لمسارات التنقّل، denylist وallowlist.

كانت خدمة workbox-routing توفّر سابقًا طريقة registerNavigationRoute() التي كانت تؤدي عمليتين:

  1. رصد ما إذا كان حدث fetch معيّن قد تضمّن mode من 'navigate' أم لا
  2. إذا كان الأمر كذلك، تم الردّ على هذا الطلب باستخدام محتوى عنوان URL مُخزَّن مؤقتًا ومبرمَج مسبقًا، بغض النظر عن عنوان URL الذي يتم الانتقال إليه.

هذا النمط شائع الاستخدام عند تنفيذ بنية App Shell.

أما الخطوة الثانية، فهي إنشاء استجابة من خلال القراءة من ذاكرة التخزين المؤقت، وتقع خارج نطاق مسؤوليات workbox-routing. بدلاً من ذلك، نعتبرها وظيفة يجب أن تكون جزءًا من workbox-precaching عبر طريقة جديدة، وهي createHandlerBoundToURL(). يمكن أن تعمل هذه الطريقة الجديدة جنبًا إلى جنب مع فئة NavigationRoute الحالية في workbox-routing لتحقيق المنطق نفسه.

إذا كنت تستخدم الخيار navigateFallback في أحد أوضاع "إنشاء SW" في أداة الإنشاء، سيتم إجراء عملية التبديل تلقائيًا. إذا سبق لك ضبط أحد الخيارين navigateFallbackBlacklist أو navigateFallbackWhitelist، يمكنك تغييره إلى navigateFallbackDenylist أو navigateFallbackAllowlist على التوالي.

في حالة استخدام الخيار "إدخال البيان" أو كتابة مشغّل الخدمات بنفسك، ويتصل عامل الخدمات الإصدار 4 من Workbox بـ registerNavigationRoute() مباشرةً، ستحتاج إلى إجراء تغيير على الرمز للحصول على السلوك المكافئ.

// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';

const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
  whitelist: [...],
  blacklist: [...],
});

// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';

const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
  allowlist: [...],
  denylist: [...],
});
registerRoute(navigationRoute);

لم تعُد بحاجة إلى الاتصال بـ getCacheKeyForURL()، لأنّ createHandlerBoundToURL() سيتولى ذلك نيابةً عنك.

إزالة makeRequest() من workbox-strategies

إنّ استدعاء makeRequest() يعادل في أغلب الأحيان استدعاء handle() في إحدى فئات workbox-strategy. كانت الاختلافات بين الطريقتين طفيفة جدًا لدرجة أن الاحتفاظ بكلتاهما لم يكن منطقيًا. من المفترض أن يتمكّن المطوّرون الذين استخدموا makeRequest() من التبديل إلى استخدام handle() بدون إجراء أي تغييرات أخرى:

// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});

// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});

في الإصدار 5، يتعامل handle() مع request كمَعلمة مطلوبة، ولن يعود إلى استخدام event.request. تأكَّد من إرسال طلب صالح عند الاتصال بالرقم handle().

يستخدم Workbox-broadcast-update postMessage() دائمًا

في الإصدار 4، تستخدم مكتبة workbox-broadcast-update تلقائيًا Broadcast Channel API لإرسال الرسائل عندما تكون متوافقة، وستعود إلى استخدام postMessage() فقط في حال عدم توفّر قناة البث.

لقد تبيّن لنا أنّ الحاجة إلى الاستماع إلى مصدرَين محتمَلَين للرسائل الواردة جعلت من كتابة الرمز البرمجي من جهة العميل أمرًا معقدًا للغاية. بالإضافة إلى ذلك، في بعض المتصفّحات، يتم تلقائيًا تخزين طلبات postMessage() من worker الخدمة المُرسَلة إلى صفحات العميل إلى أن يتم إعداد مستمع أحداث message. لا يتم تخزين مؤقت باستخدام واجهة برمجة التطبيقات Broadcast Channel API، ويتم تجاهل الرسائل التي يتم بثها إذا تم إرسالها قبل أن تكون صفحة العميل جاهزة لاستلامها.

ولهذا السبب، غيّرنا workbox-broadcast-update لاستخدام postMessage() دائمًا في الإصدار 5. يتم إرسال الرسائل واحدًا تلو الآخر إلى جميع صفحات العميل ضمن نطاق مشغّل الخدمات الحالي.

لاستيعاب هذا السلوك الجديد، يمكنك إزالة أي رمز كان لديك في صفحات العميل التي أنشأت نُسخًا من BroadcastChannel، وبدلاً من ذلك، يمكنك إعداد مستمع أحداث message على navigator.serviceWorker:

// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
  const {cacheName, updatedUrl} = event.data.payload;
  // ... your code here ...
});

// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
  // Optional: ensure the message came from workbox-broadcast-update
  if (event.meta === 'workbox-broadcast-update') {
    const {cacheName, updatedUrl} = event.data.payload;
    // ... your code here ...
  }
});

من المفترض ألا يحتاج مستخدمو workbox-window إلى إجراء أي تغييرات، لأنّه تم تعديل منطقها الداخلي للاستماع إلى طلبات postMessage().

تتطلب أدوات التصميم الإصدار Node.js أو إصدار أعلى

لم تعُد إصدارات Node.js السابقة للإصدار 8 متوافقة مع workbox-webpack-plugin أو workbox-build أو workbox-cli. إذا كنت تستخدم إصدارًا أقدم من 8 من Node.js، عليك تحديث وقت التشغيل إلى إصدار متوافق.

Workbox-webpack-plugin يتطلب إصدار webpack 4 أو إصدار أعلى

إذا كنت تستخدم workbox-webpack-plugin، عليك تعديل إعدادات webpack لاستخدام الإصدار 4 من webpack على الأقل.

تعديل خيار أداة الإنشاء

لم يعُد عدد مَعلمات الإعداد workbox-build وworkbox-cli وworkbox-webpack-plugin متاحًا. على سبيل المثال، سينشئ الخيار generateSW دائمًا حِزمة تشغيل Workbox محلية لك، لذا لم يعُد الخيار importWorkboxFrom منطقيًا.

يُرجى الرجوع إلى وثائق الأداة ذات الصلة للحصول على قوائم الخيارات المتوافقة.

إزالة createSWString من Workbox-build

تمت إزالة وضع "generateSWString" من workbox-build. نتوقّع أن يكون تأثير هذه التغييرات طفيفًا، لأنّه تم استخدامها داخليًا بشكل أساسي من قِبل "workbox-webpack-plugin".

التغييرات الاختيارية

استخدام عمليات استيراد الوحدات

على الرغم من أنّ هذا التغيير (أ) اختياري و(ب) كان ممكنًا من الناحية الفنية عند استخدام الإصدار 4 من Workbox، فإنّ أكبر تغيير نتوقّعه أثناء الانتقال إلى الإصدار 5 هو نموذج يمكنك من خلاله إنشاء عامل خدمة مجمّع من خلال استيراد وحدات Workbox. يشكّل هذا النهج بديلاً لاستدعاء importScripts('/path/to/workbox-sw.js') في أعلى worker الخدمة واستخدام Workbox من خلال مساحة الاسم workbox.*.

إذا كنت تستخدم إحدى أدوات الإنشاء (workbox-webpack-plugin أو workbox-build أو workbox-cli) في وضع "إنشاء حِزم البرامج الثابتة"، سيتم إجراء هذا التغيير تلقائيًا. ستُنشئ كل هذه الأدوات حِزمة مخصّصة ومحلية لواجهة تشغيل Workbox إلى جانب الرمز البرمجي الفعلي اللازم لتنفيذ منطق worker الخدمة. في هذا السيناريو، لم تعُد هناك أيّ تبعية workbox-sw أو نسخة CDN من Workbox. استنادًا إلى قيمة إعداد inlineWorkboxRuntime، سيتم تقسيم وقت تشغيل Workbox إلى ملف منفصل يجب نشره إلى جانب عامل الخدمة (عند ضبطه على false، وهو الإعداد التلقائي)، أو سيتم تضمينه مع منطق عامل الخدمة (عند ضبطه على true).

إذا كنت تستخدم أدوات الإنشاء في وضع "حقن البيان"، أو إذا كنت لا تستخدم أدوات إنشاء Workbox على الإطلاق، يمكنك الاطّلاع على مزيد من المعلومات عن إنشاء حِزمة وقت تشغيل Workbox في دليل استخدام حِزم (webpack/Rollup) مع Workbox الحالي.

تمّت كتابة المستندات والأمثلة للإصدار 5 بافتراض استخدام بنية استيراد الوحدات، على الرغم من أنّ نطاق الاسم workbox.* سيظلّ متوافقًا مع الإصدار 5 من Workbox.

قراءة الردود المخزّنة مسبقًا

يحتاج بعض المطوّرين إلى قراءة الردود المخزّنة مسبقًا مباشرةً من ذاكرة التخزين المؤقت، بدلاً من استخدامها بشكل ضمني من خلال طريقة precacheAndRoute(). هناك نمط شائع في الإصدار 4 هو الحصول أولاً على مفتاح ذاكرة التخزين المؤقت الخاص بالإصدار الحالي من مورد مخزَّن مؤقتًا، ثم إدخال هذا المفتاح مع اسم ذاكرة التخزين المؤقت في ذاكرة التخزين المؤقت إلى caches.match() للحصول على Response.

لتبسيط هذه العملية، يتيح workbox-precaching في الإصدار 5 طريقة جديدة مكافئة، وهي matchPrecache():

// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';

const cachedResponse = await caches.match(
  getCacheKeyForURL(`/somethingPrecached`),
  {
    cacheName: cacheNames.precache,
  }
);

// v5:
import {matchPrecache} from 'workbox-precaching';

const cachedResponse = await matchPrecache(`/somethingPrecached`);

استخدام TypeScript

في الإصدار 5، تتم كتابة مكتبات وقت تشغيل Workbox بلغة TypeScript. سنواصل نشر وحدات وحِزم JavaScript المُترجَمة لاستيعاب المطوّرين الذين لم يتبنّوا TypeScript، ولكن إذا كنت تستخدم TypeScript، من المفترض أن تستفيد من معلومات دقيقة وحديثة دائمًا عن الأنواع مباشرةً من مشروع Workbox.

مثال على نقل البيانات

يوضّح هذا الإجراء عملية نقل معقدة إلى حدٍ ما، مع تعليقات مضمّنة. وهو يستخدم البيانات المجمّعة لتضمين بيئة تشغيل مخصّصة لـ Workbox في مشغّل الخدمات النهائي بدلاً من تحميل بيئة التشغيل من شبكة توصيل المحتوى (CDN).

مع أنّ هذا القسم لا يشمل كل التغييرات التي قد تؤدي إلى عطل، إليك قبل وبعد ترقية ملف عامل تشغيل واحد من الإصدار 4 إلى الإصدار 5، بما في ذلك التبديل إلى TypeScript.

الحصول على المساعدة

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