نقل البيانات من الإصدار 5 إلى الإصدار 6 من Workbox

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

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

workbox-core

لن تُضيف طريقة skipWaiting() في workbox-core معالِج install بعد الآن، وستكون المكالمة إلى self.skipWaiting() هي الإجراء المكافئ.

من الآن فصاعدًا، استخدِم self.skipWaiting() بدلاً من skipWaiting() لأنّه من المرجّح أن تتم إزالته في الإصدار 7 من Workbox.

workbox-precaching

  • لم يعُد بإمكانك استخدام مستندات HTML من مصادر متعددة لعناوين URL التي تتوافق مع إعادة توجيه HTTP من أجل تلبية طلب التنقّل باستخدام workbox-precaching. هذا السيناريو غير شائع بشكل عام.
  • يتجاهل workbox-precaching الآن مَعلمة طلب البحث fbclid لعنوان URL عند البحث عن استجابة تم تخزينها مسبقًا لطلب معيّن.
  • تستقبل الدالة الإنشائية PrecacheController الآن كائنًا يتضمّن سمات محدّدة كمعلَمة لها، بدلاً من سلسلة. يتيح هذا العنصر السمات التالية: cacheName (تؤدي الغرض نفسه الذي تؤديه السلسلة التي تم تمريرها إلى دالة الإنشاء في الإصدار 5)، وplugins (تحلّ محلّ طريقة addPlugins() من الإصدار 5)، وfallbackToNetwork (تحلّ محلّ الخيار المشابه الذي تم تمريره إلى createHandler() وcreateHandlerBoundToURL()‎ في الإصدار 5).
  • تأخذ طريقتا install() وactivate() في دالة PrecacheController الآن مَعلمة واحدة بالضبط، ويجب ضبطها على InstallEvent أو ActivateEvent المطابقَين، على التوالي.
  • تمت إزالة طريقة addRoute() من PrecacheController. بدلاً من ذلك، يمكن استخدام فئة PrecacheRoute الجديدة لإنشاء مسار يمكنك تسجيله بعد ذلك.
  • تمت إزالة طريقة precacheAndRoute() من PrecacheController. (لا يزال متوفّرًا كطريقة مساعدة ثابتة يتم تصديرها بواسطة وحدة workbox-precaching). وقد تمّت إزالته لأنّه يمكن استخدام PrecacheRoute بدلاً منه.
  • تمّت إزالة طريقة createMatchCalback() من PrecacheController. يمكن استخدام PrecacheRoute الجديد بدلاً من ذلك.
  • تمت إزالة طريقة createHandler() من PrecacheController. يمكن استخدام السمة strategy للكائن PrecacheController لمعالجة الطلبات بدلاً من ذلك.
  • سبق أن تمت إزالة التصدير الثابت لـ createHandler() من وحدة workbox-precaching. بدلاً من ذلك، على المطوّرين إنشاء مثيل PrecacheController واستخدام سمة strategy.
  • أصبح المسار المسجّل باستخدام precacheAndRoute() الآن مسارًا "حقيقيًا" يستخدم فئة Router في workbox-routing. وقد يؤدي ذلك إلى ترتيب تقييم مختلف لمساراتك إذا كنت تتخلّل المكالمات إلى registerRoute() وprecacheAndRoute().

workbox-routing

تأخذ طريقة setDefaultHandler() الآن مَعلمة ثانية اختيارية تتوافق مع طريقة HTTP التي تنطبق عليها، وتكون القيمة التلقائية لها هي 'GET'.

  • إذا كنت تستخدم setDefaultHandler() وكانت جميع طلباتك GET، ليس عليك إجراء أي تغييرات.
  • إذا كان لديك أي طلبات ليست GET (POST أو PUT أو غير ذلك)، لن تؤدي setDefaultHandler() بعد الآن إلى مطابقة هذه الطلبات.

إعدادات التصميم

لم يكن من المخطّط أن يكون خيار mode متاحًا في وضعَي getManifest وinjectManifest في workbox-build وworkbox-cli، وقد تمت إزالته. لا ينطبق ذلك على workbox-webpack-plugin، الذي يتيح استخدام mode في المكوّن الإضافي InjectManifest.

تتطلّب أدوات الإنشاء استخدام الإصدار 10 من Node.js أو إصدار أحدث.

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

تحسينات جديدة

workbox-strategies

توفّر الإصدار 6 من Workbox طريقة جديدة للمطوّرين التابعين لجهات خارجية لتحديد استراتيجيات Workbox الخاصة بهم. يضمن ذلك قدرة المطوّرين التابعين لجهات خارجية على توسيع نطاق Workbox بطرق تلبي احتياجاتهم بالكامل.

فئة أساسية جديدة للاستراتيجية

في الإصدار 6، يجب أن تُنشئ جميع فئات استراتيجيات Workbox الفئة الأساسية الجديدة Strategy. تمت إعادة كتابة جميع الاستراتيجيات المضمّنة لدعم ذلك.

تتحمّل الفئة الأساسية Strategy أمرَين أساسيَين:

  • استدعاء عمليات الاستدعاء لدورة حياة المكوّن الإضافي الشائعة لجميع معالجات الاستراتيجيات (مثل عند البدء والاستجابة والانتهاء)
  • إنشاء مثيل "معالج" يمكنه إدارة الحالة لكل طلب فردي تعالجّه استراتيجية معيّنة

فئة "معالج" جديدة

كانت لدينا في السابق وحدات داخلية تُسمى fetchWrapper وcacheWrapper، والتي (كما يشير اسمها) تلف واجهات برمجة التطبيقات المختلفة لعمليات الجلب والتخزين المؤقت باستخدام عناصر الربط في دورة حياتها. هذه هي الآلية التي تسمح حاليًا بتشغيل المكوّنات الإضافية، ولكنّها غير متاحة للمطوّرين.

ستُعرِض فئة "المعالج" الجديدة، StrategyHandler، هذه الطرق حتى تتمكّن الاستراتيجيات المخصّصة من استدعاء fetch() أو cacheMatch() وتنفيذ أيّ مكونات إضافية تمت إضافتها إلى مثيل الاستراتيجية تلقائيًا.

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

حالة جديدة لمرحلة نشاط المكوّن الإضافي

في الإصدار 5 من Workbox، تكون المكوّنات الإضافية غير مرتبطة بحالة. وهذا يعني أنّه إذا كان طلب /index.html يؤدي إلى تشغيل كلّ من requestWillFetch وcachedResponseWillBeUsed، لن يكون بإمكان هاتين الدالتَين التواصل مع بعضهما أو حتى معرفة أنّهما تم تشغيلهما من خلال الطلب نفسه.

في الإصدار 6، سيتم أيضًا تمرير كائن state جديد إلى جميع عمليات استدعاء المكوّنات الإضافية. سيكون عنصر الحالة هذا فريدًا لعنصر المكوّن الإضافي هذا وطريقة استدعاء الاستراتيجية هذه (أي طلب handle()). يتيح ذلك للمطوّرين كتابة مكوّنات إضافية يمكن فيها أن ينفّذ طلب استدعاء واحد إجراءً بشكل مشروط استنادًا إلى ما نفّذه طلب استدعاء آخر في المكوّن الإضافي نفسه (مثل احتساب الفرق الزمني بين تشغيل requestWillFetch وfetchDidSucceed أو fetchDidFail).

وظائف الاستدعاء الجديدة في مراحل نشاط المكوّن الإضافي

تمّت إضافة وظائف استدعاء جديدة لدورة حياة المكوّن الإضافي للسماح للمطوّرين بالاستفادة إلى أقصى حدّ من حالة دورة حياة المكوّن الإضافي:

  • handlerWillStart: يتمّ استدعاؤها قبل بدء تنفيذ أيّ منطق للمعالج. يمكن استخدام هذا المرجع لضبط حالة معالِج الطلب الأولية (مثل تسجيل وقت البدء).
  • handlerWillRespond: يتمّ استدعاؤها قبل أن تُرجِع طريقة handle() الخاصة بالاستراتيجيات استجابةً. يمكن استخدام هذا المرجع لتعديل هذا الردّ قبل إرجاعه إلى معالِج مسار أو منطق مخصّص آخر.
  • handlerDidRespond: يتمّ استدعاؤها بعد أن تُرجع طريقة handle() في الاستراتيجية استجابةً. يمكن استخدام هذا المرجع لتسجيل أي تفاصيل نهائية للردّ، مثلاً بعد التغييرات التي أجرتها الإضافات الأخرى.
  • handlerDidComplete: يتمّ استدعاؤه بعد تسوية جميع العروض التي تزيد من مدّة الاشتراك التي تمت إضافتها إلى الحدث من خلال استدعاء هذه الاستراتيجية. يمكن استخدام هذا المرجع لإعداد تقارير عن أي بيانات تحتاج إلى الانتظار حتى ينتهي معالِج البيانات من احتسابها (مثل حالة مطابقة ذاكرة التخزين المؤقت، ووقت استجابة ذاكرة التخزين المؤقت، ووقت استجابة الشبكة).
  • handlerDidError: يتمّ استدعاؤه إذا لم يتمكّن معالِج الحدث من تقديم استجابة صالحة من أيّ مصدر. يمكن استخدام هذا المرجع للرجوع إليه من أجل تقديم محتوى "احتياطي" كبديل لخطأ في الشبكة.

لا داعي للقلق بشأن استدعاء عمليات الاستدعاء هذه بأنفسهم من قِبل المطوّرين الذين ينفذون استراتيجياتهم المخصّصة، لأنّ فئة Strategy الأساسية الجديدة تتعامل مع كل ذلك.

أنواع TypeScript أكثر دقة للمعالجات

تم توحيد تعريفات TypeScript لطرق ردّ الاتصال المختلفة. من المفترض أن يؤدي ذلك إلى تقديم تجربة أفضل للمطوّرين الذين يستخدمون TypeScript ويكتبون رموزهم البرمجية الخاصة بهم لتنفيذ معالِجات أو الاتصال بها.

workbox-window

طريقة messageSkipWaiting() الجديدة

تمت إضافة طريقة جديدة، messageSkipWaiting()، إلى وحدة workbox-window لتبسيط عملية إخبار عامل الخدمة"في انتظار التنشيط" بالتنشيط. يقدّم ذلك بعض التحسينات:

  • ويُطلِق هذا الإجراء postMessage() مع نص الرسالة العادي التلقائي، {type: 'SKIP_WAITING'}، الذي يتحقّق منه عامل الخدمة الذي أنشأه Workbox لتشغيل skipWaiting().
  • يختار مشغّل الخدمات "في انتظار التحميل" الصحيح لنشر هذه الرسالة، حتى لو لم يكن مشغّل الخدمات نفسه الذي تم تسجيل workbox-window به.

إزالة الأحداث "الخارجية" لصالح السمة isExternal

تمّت إزالة جميع الأحداث "الخارجية" في workbox-window بدلاً من الأحداث "العادية" التي تم ضبط سمة isExternal فيها على true. يتيح ذلك للمطوّرين الذين يهتمون بهذا التمييز مواصلة رصده، ويمكن للمطوّرين الذين لا يحتاجون إلى معرفة ذلك تجاهل السمة.

صياغة أكثر وضوحًا لـ "إتاحة إعادة تحميل الصفحة للمستخدمين"

بفضل التغييرَين أعلاه، يمكن تبسيط "إتاحة إعادة تحميل الصفحة للمستخدمين":

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

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

    const showSkipWaitingPrompt = () => {
      // This assumes a hypothetical createUIPrompt() method with
      // onAccept and onReject callbacks:
      const prompt = createUIPrompt({
        onAccept: () => {
          wb.addEventListener('controlling', () => {
            window.location.reload();
          });

          // This will postMessage() to the waiting service worker.
          wb.messageSkipWaiting();
        },

        onReject: () => {
          prompt.dismiss();
        },
      });
    };

    // Listening for externalwaiting is no longer needed.
    wb.addEventListener('waiting', showSkipWaitingPrompt);
    wb.register();
  }
</script>

workbox-routing

يتم تمرير مَعلمة منطقية جديدة، sameOrigin، إلى الدالة matchCallback المستخدَمة في workbox-routing. يتم ضبطها على true إذا كان الطلب لعنوان URL من المصدر نفسه، وfalse بخلاف ذلك.

ويؤدي ذلك إلى تبسيط بعض النماذج الشائعة:

// In v5:
registerRoute(
  ({url}) =>
    url.origin === self.location.origin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

// In v6:
registerRoute(
  ({sameOrigin, url}) => sameOrigin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

matchOptions في workbox-expiration

يمكنك الآن ضبط matchOptions في workbox-expiration، وسيتم تمريرها بعد ذلك على أنّها CacheQueryOptions إلى طلب cache.delete() الأساسي. (لن يحتاج معظم المطوّرين إلى تنفيذ هذا الإجراء).

workbox-precaching

استخدام استراتيجيات ميزة "علبة العمل"

تمت إعادة كتابة workbox-precaching لاستخدام workbox-strategies كأساس. من المفترض ألا يؤدّي ذلك إلى أي تغييرات جذرية، ومن المفترض أن يؤدّي إلى اتساق أفضل على المدى الطويل في كيفية وصول المكوّنَين إلى الشبكة وذاكرة التخزين المؤقت.

تعالج ميزة "التخزين المؤقت المُسبَق" الآن الإدخالات الواحدة تلو الأخرى، وليس بشكل مجمّع.

تم تعديل workbox-precaching لكي يتم طلب إدخال واحد فقط في بيان التخزين المؤقت المُسبَق وتخزينه مؤقتًا في كل مرة، بدلاً من محاولة طلب كل الإدخالات وتخزينها مؤقتًا في آنٍ واحد (وتفويض المتصفح بتحديد كيفية الحد من السرعة).

من المفترض أن يؤدي ذلك إلى تقليل احتمالية حدوث أخطاء net::ERR_INSUFFICIENT_RESOURCES أثناء التخزين المؤقت المُسبَق، كما من المفترض أن يؤدي إلى تقليل الصراع على معدل نقل البيانات بين التخزين المؤقت المُسبَق والطلبات المتزامنة التي يجريها تطبيق الويب.

يتيح PrecacheFallbackPlugin استخدام بديل بلا إنترنت بسهولة أكبر.

يتضمّن workbox-precaching الآن PrecacheFallbackPlugin، الذي ينفّذ طريقة handlerDidError الجديدة لدورة الحياة التي تمت إضافتها في الإصدار 6.

يسهّل ذلك تحديد عنوان URL محفوظ مسبقًا كخيار "احتياطي" لاستراتيجية معيّنة عندما لا يتوفّر استجابة بخلاف ذلك. سيتولى المكوّن الإضافي إنشاء مفتاح التخزين المؤقت الصحيح لعنوان URL المخزّن مسبقًا، بما في ذلك أي مَعلمة مراجعة مطلوبة.

في ما يلي نموذج لاستخدامها للردّ باستخدام /offline.html محفوظ مسبقًا في ذاكرة التخزين المؤقت عندما لا تتمكّن استراتيجية NetworkOnly من إنشاء استجابة لطلب التنقّل، أي عرض صفحة HTML مخصّصة بلا إنترنت:

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
  ({request}) => request.mode === 'navigate',
  new NetworkOnly({
    plugins: [
      new PrecacheFallbackPlugin({
        fallbackURL: '/offline.html',
      }),
    ],
  })
);

precacheFallback في ميزة التخزين المؤقت في وقت التشغيل

إذا كنت تستخدم generateSW لإنشاء عامل خدمة نيابةً عنك بدلاً من كتابته يدويًا، يمكنك استخدام خيار الضبط الجديد precacheFallback في runtimeCaching لتنفيذ الإجراء نفسه:

{
  // ... other generateSW config options...
  runtimeCaching: [{
    urlPattern: ({request}) => request.mode === 'navigate',
    handler: 'NetworkOnly',
    options: {
      precacheFallback: {
        // This URL needs to be included in your precache manifest.
        fallbackURL: '/offline.html',
      },
    },
  }],
}

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

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