استفاده از پلاگین ها

هنگام استفاده از Workbox، ممکن است بخواهید یک درخواست و یک پاسخ را هنگام واکشی یا ذخیره شدن در حافظه پنهان دستکاری کنید. پلاگین‌های Workbox به شما این امکان را می‌دهند که رفتارهای بیشتری را با حداقل دیگ بخار اضافی به کارمند خدمات خود اضافه کنید. آنها را می توان بسته بندی کرد و در پروژه های خود دوباره استفاده کرد یا به صورت عمومی برای استفاده دیگران نیز منتشر کرد.

Workbox تعدادی افزونه را در اختیار ما قرار می‌دهد، و - اگر از نوع حیله‌گر هستید - می‌توانید افزونه‌های سفارشی متناسب با نیازهای برنامه خود بنویسید.

پلاگین های Workbox موجود

Workbox افزونه‌های رسمی زیر را برای استفاده در سرویس‌کار شما ارائه می‌دهد:

  • BackgroundSyncPlugin : اگر یک درخواست شبکه با شکست مواجه شود، این افزونه به شما امکان می‌دهد آن را به صف همگام‌سازی پس‌زمینه اضافه کنید تا زمانی که رویداد همگام‌سازی بعدی آغاز شد دوباره درخواست شود.
  • BroadcastUpdatePlugin : به شما امکان می دهد هر زمان که حافظه پنهان به روز می شود، پیامی را در یک کانال پخش یا از طریق postMessage() ارسال کنید.
  • CacheableResponsePlugin : فقط درخواست‌های کش که معیارهای خاصی را دارند.
  • ExpirationPlugin : تعداد و حداکثر سن موارد موجود در حافظه پنهان را مدیریت می کند.
  • RangeRequestsPlugin : به درخواست هایی که شامل سرصفحه درخواست Range HTTP هستند پاسخ دهید.

افزونه‌های Workbox - خواه یکی از افزونه‌های فهرست‌شده در بالا باشند، یا یک افزونه سفارشی، با یک استراتژی Workbox با افزودن نمونه‌ای از افزونه به ویژگی plugins استراتژی استفاده می‌شوند:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {ExpirationPlugin} from 'workbox-expiration';

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    cacheName: 'images',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 60,
        maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
      }),
    ],
  })
);

روش هایی برای پلاگین های سفارشی

یک افزونه Workbox باید یک یا چند تابع callback را پیاده سازی کند. هنگامی که یک افزونه را به یک استراتژی اضافه می کنید، عملکردهای پاسخ به تماس به طور خودکار در زمان مناسب اجرا می شوند. استراتژی اطلاعات مربوط به عملکرد پاسخ به تماس شما را در مورد درخواست و/یا پاسخ فعلی ارسال می‌کند، و به افزونه شما زمینه‌ای را می‌دهد که برای انجام اقدام لازم است. توابع پاسخ به تماس زیر پشتیبانی می شوند:

  • cacheWillUpdate : قبل از استفاده از Response برای به روز رسانی حافظه پنهان فراخوانی می شود. در این روش، پاسخ را می توان قبل از اضافه شدن به حافظه پنهان تغییر داد، یا می توانید برای جلوگیری از به روز رسانی کامل کش، null برگردانید.
  • cacheDidUpdate : زمانی که ورودی جدیدی به حافظه پنهان اضافه می شود یا ورودی موجود به روز می شود، فراخوانی می شود. افزونه‌هایی که از این روش استفاده می‌کنند ممکن است زمانی مفید باشند که بخواهید بعد از به‌روزرسانی حافظه پنهان عملی را انجام دهید.
  • cacheKeyWillBeUsed : قبل از استفاده از یک درخواست به عنوان کلید حافظه پنهان فراخوانی می شود. این هم برای جستجوی حافظه پنهان (زمانی که mode 'read' است) و هم برای نوشتن حافظه پنهان (زمانی که mode 'write' است) رخ می دهد. اگر قبل از استفاده از URL ها برای دسترسی به حافظه نهان، نیاز به لغو یا عادی سازی URL ها دارید، این پاسخ تماس مفید است.
  • cachedResponseWillBeUsed : این مورد درست قبل از استفاده از یک پاسخ از حافظه پنهان فراخوانی می شود که به شما امکان می دهد آن پاسخ را بررسی کنید. در این مرحله از زمان، می‌توانید پاسخ دیگری را برگردانید یا null برگردانید.
  • requestWillFetch : هر زمان که درخواستی در حال رفتن به شبکه باشد، فراخوانی می شود. زمانی مفید است که نیاز دارید Request درست قبل از اینکه به شبکه برود تغییر دهید.
  • fetchDidFail : زمانی که درخواست شبکه ناموفق می‌شود، به احتمال زیاد به دلیل عدم اتصال به شبکه، فراخوانی می‌شود و زمانی که مرورگر اتصال شبکه داشته باشد، فعال نمی‌شود، اما یک خطا دریافت می‌کند (به عنوان مثال، 404 Not Found ).
  • fetchDidSucceed : هر زمان که یک درخواست شبکه با موفقیت انجام شود، بدون توجه به کد پاسخ HTTP، فراخوانی می شود.
  • handlerWillStart : قبل از شروع هر منطق کنترل کننده فراخوانی می شود که در صورت نیاز به تنظیم حالت اولیه کنترل کننده مفید است. به عنوان مثال، اگر می‌خواهید بدانید که کنترل‌کننده چقدر طول می‌کشد تا یک پاسخ را ایجاد کند، می‌توانید زمان شروع را در این پاسخ تماس یادداشت کنید.
  • handlerWillRespond : قبل از فراخوانی متد handle() استراتژی پاسخی را برمی گرداند، که اگر نیاز به تغییر یک پاسخ قبل از برگرداندن آن به RouteHandler یا سایر منطق های سفارشی داشته باشید مفید است.
  • handlerDidRespond : پس از اینکه متد handle() استراتژی پاسخی را برمی گرداند فراخوانی می شود. این زمانی است که ممکن است ثبت جزئیات پاسخ نهایی (به عنوان مثال، پس از تغییرات ایجاد شده توسط سایر افزونه ها) مفید باشد.
  • handlerDidComplete : نامیده می شود پس از تمام طول عمر وعده های اضافه شده به رویداد از فراخوانی استراتژی حل و فصل شده اند. اگر برای محاسبه مواردی مانند وضعیت ضربه حافظه پنهان، تأخیر حافظه پنهان، تأخیر شبکه و سایر اطلاعات مفید، نیاز به گزارش در مورد هر داده ای دارید که باید منتظر بمانید تا کنترل کننده تمام شود، مفید است.
  • handlerDidError : اگر کنترل کننده نتواند پاسخ معتبری را از هر منبعی ارائه دهد، فراخوانی می شود، که زمان بهینه برای ارائه نوعی پاسخ بازگشتی به عنوان جایگزینی برای شکست کامل است.

همه این تماس‌های برگشتی async هستند، و بنابراین هر زمان که یک حافظه پنهان یا رویداد واکشی به نقطه مربوطه برای پاسخ تماس مربوطه رسید، باید await تا مورد استفاده قرار گیرد.

اگر افزونه‌ای از تمام تماس‌های بالا استفاده می‌کرد، این کد حاصل می‌شود:

const myPlugin = {
  cacheWillUpdate: async ({request, response, event, state}) => {
    // Return `response`, a different `Response` object, or `null`.
    return response;
  },
  cacheDidUpdate: async ({
    cacheName,
    request,
    oldResponse,
    newResponse,
    event,
    state,
  }) => {
    // No return expected
    // Note: `newResponse.bodyUsed` is `true` when this is called,
    // meaning the body has already been read. If you need access to
    // the body of the fresh response, use a technique like:
    // const freshResponse = await caches.match(request, {cacheName});
  },
  cacheKeyWillBeUsed: async ({request, mode, params, event, state}) => {
    // `request` is the `Request` object that would otherwise be used as the cache key.
    // `mode` is either 'read' or 'write'.
    // Return either a string, or a `Request` whose `url` property will be used as the cache key.
    // Returning the original `request` will make this a no-op.
    return request;
  },
  cachedResponseWillBeUsed: async ({
    cacheName,
    request,
    matchOptions,
    cachedResponse,
    event,
    state,
  }) => {
    // Return `cachedResponse`, a different `Response` object, or null.
    return cachedResponse;
  },
  requestWillFetch: async ({request, event, state}) => {
    // Return `request` or a different `Request` object.
    return request;
  },
  fetchDidFail: async ({originalRequest, request, error, event, state}) => {
    // No return expected.
    // Note: `originalRequest` is the browser's request, `request` is the
    // request after being passed through plugins with
    // `requestWillFetch` callbacks, and `error` is the exception that caused
    // the underlying `fetch()` to fail.
  },
  fetchDidSucceed: async ({request, response, event, state}) => {
    // Return `response` to use the network response as-is,
    // or alternatively create and return a new `Response` object.
    return response;
  },
  handlerWillStart: async ({request, event, state}) => {
    // No return expected.
    // Can set initial handler state here.
  },
  handlerWillRespond: async ({request, response, event, state}) => {
    // Return `response` or a different `Response` object.
    return response;
  },
  handlerDidRespond: async ({request, response, event, state}) => {
    // No return expected.
    // Can record final response details here.
  },
  handlerDidComplete: async ({request, response, error, event, state}) => {
    // No return expected.
    // Can report any data here.
  },
  handlerDidError: async ({request, event, error, state}) => {
    // Return a `Response` to use as a fallback, or `null`.
    return fallbackResponse;
  },
};

شی event موجود در فراخوان های فهرست شده در بالا، رویداد اصلی است که عمل واکشی یا حافظه پنهان را آغاز کرده است. گاهی اوقات، یک رویداد اصلی وجود نخواهد داشت، بنابراین کد شما باید قبل از ارجاع به آن، وجود آن را بررسی کند.

همه تماس‌های پلاگین نیز یک شیء state ارسال می‌شوند که منحصر به یک پلاگین خاص و استراتژی آن است. این بدان معناست که می‌توانید پلاگین‌هایی بنویسید که در آن یک callback می‌تواند به‌صورت مشروط یک کار را بر اساس کاری که پاسخ تماس دیگری در همان افزونه انجام داده است انجام دهد (به عنوان مثال، تفاوت بین اجرای requestWillFetch() و fetchDidSucceed() یا fetchDidFail() را محاسبه کنید.

افزونه های شخص ثالث

اگر افزونه‌ای را توسعه می‌دهید و فکر می‌کنید خارج از پروژه شما کاربرد دارد، ما شما را تشویق می‌کنیم که آن را به عنوان یک ماژول منتشر کنید! در زیر لیست کوتاهی از افزونه‌های Workbox ارائه شده توسط انجمن آمده است:

با جستجو در مخزن npm، ممکن است بتوانید افزونه های Workbox ارائه شده توسط جامعه بیشتری را بیابید .

در نهایت، اگر یک افزونه Workbox ساخته‌اید که می‌خواهید آن را به اشتراک بگذارید، هنگام انتشار آن، کلمه کلیدی workbox-plugin اضافه کنید. اگر دارید، در Twitter @WorkboxJS به ما اطلاع دهید!