مهاجرت از Workbox v4 به v5، مهاجرت از Workbox v4 به v5

این راهنما بر روی شکستن تغییرات ارائه شده در Workbox v5 متمرکز شده است، با نمونه هایی از تغییراتی که باید هنگام ارتقاء از Workbox v4 ایجاد کنید.

شکستن تغییرات

کلاس های پلاگین تغییر نام دادند

تعدادی از بسته های Workbox v4 شامل کلاس هایی به نام Plugin بودند. در نسخه 5، آن کلاس‌ها برای پیروی از شناسه بسته الگو + Plugin تغییر نام داده‌اند:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

این تغییر نام چه در حال استفاده از کلاس ها از طریق وارد کردن ماژول و چه از طریق فضای نام workbox.* اعمال می شود.

نقطه جایگزینی پیش فرض مانیفست پیش کش

قبلاً، هنگام استفاده از یکی از ابزارهای ساخت در حالت "inject manifest"، فایل کارگر سرویس منبع شما برای وجود precacheAndRoute([]) بررسی می شد، با آرایه خالی [] به عنوان مکان نگهدار برای نقطه ای که در آن پیش کش استفاده می شد. مانیفست تزریق شد.

در Workbox v5، منطق جایگزینی تغییر کرده است، و اکنون 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 می بینیم، قرار می گیرد. در عوض، ما آن را به‌عنوان عملکردی می‌بینیم که باید از طریق یک روش جدید، createHandlerBoundToURL() ، بخشی از workbox-precaching باشد. این روش جدید می‌تواند دست به دست هم با کلاس NavigationRoute موجود در workbox-routing برای انجام همان منطق کار کند.

اگر از گزینه navigateFallback در یکی از حالت‌های «تولید SW» ابزار ساخت استفاده می‌کنید، تغییر مکان به‌طور خودکار انجام می‌شود. اگر قبلاً گزینه‌های navigateFallbackBlacklist یا navigateFallbackWhitelist را پیکربندی کرده‌اید، آن‌ها را به ترتیب به navigateFallbackDenylist یا navigateFallbackAllowlist تغییر دهید.

اگر از حالت «inject manifest» استفاده می‌کنید یا فقط سرویس worker را خودتان می‌نویسید، و Workbox v4 Service Worker شما مستقیما 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});

در v5، handle() request به عنوان یک پارامتر مورد نیاز در نظر می گیرد و به استفاده از event.request برنمی گردد. اطمینان حاصل کنید که هنگام فراخوانی handle() یک درخواست معتبر ارسال می کنید.

workbox-broadcast-update همیشه از postMessage() استفاده می کند

در نسخه 4، کتابخانه workbox-broadcast-update به طور پیش‌فرض از Broadcast Channel API برای ارسال پیام در زمانی که پشتیبانی می‌شود استفاده می‌کند، و تنها زمانی که Broadcast Channel پشتیبانی نمی‌شود به استفاده postMessage() بازمی‌گردد.

متوجه شدیم که گوش دادن به دو منبع بالقوه پیام‌های دریافتی، نوشتن کد سمت سرویس گیرنده را بسیار پیچیده می‌کند. علاوه بر این، در برخی از مرورگرها، تماس‌های postMessage() از طرف سرویس‌کار که به صفحات سرویس گیرنده ارسال می‌شوند به‌طور خودکار تا زمانی که شنونده رویداد 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 قبل از نسخه ۸ دیگر برای workbox-webpack-plugin ، workbox-build یا workbox-cli پشتیبانی نمی‌شوند. اگر نسخه Node.js قبل از 8 را اجرا می کنید، زمان اجرا خود را به نسخه پشتیبانی شده به روز کنید.

workbox-webpack-plugin به webpack نسخه 4 یا بالاتر نیاز دارد

اگر از workbox-webpack-plugin استفاده می‌کنید، تنظیمات بسته وب خود را به‌روزرسانی کنید تا حداقل از webpack v4 استفاده کنید.

تعمیرات اساسی گزینه ابزار ساخت

تعدادی از پارامترهای پیکربندی workbox-build ، workbox-cli و workbox-webpack-plugin دیگر پشتیبانی نمی‌شوند. به عنوان مثال، generateSW همیشه یک بسته نرم افزاری محلی Workbox برای شما ایجاد می کند، بنابراین گزینه importWorkboxFrom دیگر معنی ندارد.

برای لیست گزینه های پشتیبانی شده به اسناد ابزار مربوطه مراجعه کنید.

حذف generalSWString از workbox-build

حالت generateSWString از workbox-build حذف شده است. ما انتظار داریم که تأثیر این حداقل باشد، زیرا در ابتدا توسط workbox-webpack-plugin به صورت داخلی استفاده می شد.

تغییرات اختیاری

استفاده از واردات ماژول

در حالی که این تغییر الف) اختیاری است و ب) از نظر فنی در هنگام استفاده از Workbox v4 امکان پذیر بود، بزرگترین تغییری که در حین انتقال به v5 پیش بینی می کنیم، مدلی است که در آن شما با وارد کردن ماژول های Workbox، سرویس کار همراه خود را ایجاد می کنید. این رویکرد جایگزینی برای فراخوانی importScripts('/path/to/workbox-sw.js') در بالای سرویس‌کار و استفاده از Workbox از طریق فضای نام workbox.* است.

اگر از یکی از ابزارهای ساخت ( workbox-webpack-plugin ، workbox-build ، workbox-cli ) در حالت "تولید SW" استفاده می کنید، این تغییر به طور خودکار برای شما اتفاق می افتد. همه این ابزارها یک بسته محلی و سفارشی از زمان اجرا Workbox را در کنار کد واقعی لازم برای اجرای منطق سرویس‌کار شما خروجی می‌دهند. در این سناریو، دیگر هیچ وابستگی به workbox-sw یا کپی CDN Workbox وجود ندارد. بسته به مقدار پیکربندی inlineWorkboxRuntime شما، زمان اجرا Workbox یا به یک فایل جداگانه تقسیم می‌شود که باید در کنار service worker شما مستقر شود (هنگامی که روی false تنظیم می‌شود، که پیش‌فرض است)، یا به صورت درون خطی همراه با منطق سرویس‌کار گنجانده می‌شود. وقتی روی true تنظیم شود).

اگر از ابزارهای ساخت در حالت «تزریق مانیفست» استفاده می‌کنید، یا اصلاً از ابزارهای ساخت Workbox استفاده نمی‌کنید، می‌توانید درباره ایجاد بسته‌ای زمان اجرا Workbox خود در Using Bundlers موجود (وب بسته/تجمیع) با راهنمای جعبه کاری

مستندات و مثال‌های v5 با فرض اینکه ماژول نحو وارد می‌کند نوشته شده‌اند، اگرچه فضای نام workbox.* همچنان در Workbox v5 پشتیبانی می‌شود.

خواندن پاسخ های از پیش ذخیره شده

برخی از توسعه دهندگان به جای استفاده ضمنی از طریق متد precacheAndRoute() ، باید پاسخ های از پیش ذخیره شده را مستقیماً از حافظه پنهان بخوانند. یک الگوی رایج در نسخه 4 این است که ابتدا کلید کش مخصوص نسخه فعلی یک منبع پیش کش را دریافت کنید و سپس آن کلید را همراه با نام کش پیش کش به caches.match() ارسال کنید تا Response را دریافت کنید.

برای ساده کردن این فرآیند، workbox-precaching در v5 از یک متد جدید و معادل، 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 نوشته شده اند. در حالی که ما به انتشار ماژول‌ها و بسته‌های جاوا اسکریپت ترانسفیل‌شده ادامه می‌دهیم تا توسعه‌دهندگانی را که TypeScript را قبول نکرده‌اند در نظر بگیریم، اگر از TypeScript استفاده می‌کنید، باید از اطلاعات نوع دقیق و همیشه به‌روز مستقیماً از پروژه Workbox بهره ببرید.

نمونه مهاجرت

این commit نشان می دهد که یک مهاجرت نسبتاً درگیر با تفسیر درون خطی است. از Rollup استفاده می کند تا به جای بارگیری زمان اجرا از CDN، یک زمان اجرا Workbox سفارشی را در سرویس کارگر نهایی قرار دهد.

در حالی که همه تغییرات شکسته را پوشش نمی دهد، قبل و بعد از ارتقاء یک فایل Service Worker از نسخه 4 به نسخه 5، از جمله سوئیچ به TypeScript در اینجا آمده است.

دریافت کمک

ما پیش‌بینی می‌کنیم که بیشتر مهاجرت‌ها ساده باشد. اگر با مشکلاتی مواجه شدید که در این راهنما پوشش داده نشده است، با باز کردن مشکلی در GitHub به ما اطلاع دهید.