این راهنما بر تغییرات ناسازگار معرفیشده در Workbox نسخه ۶ تمرکز دارد و مثالهایی از تغییراتی که باید هنگام ارتقا از Workbox نسخه ۵ اعمال کنید ارائه میدهد.
تغییرات ناگهانی
workbox-core
روش skipWaiting() در workbox-core دیگر در گرداننده install اضافه نخواهد شد و معادل فقط فراخوانی self.skipWaiting() است.
ازاینپس، بهجای آن از self.skipWaiting() استفاده کنید زیرا احتمالاً skipWaiting() در Workbox نسخه ۷ برداشته خواهد شد.
workbox-precaching
- دیگر نمیتوان از اسناد HTML میانمبدئی برای نشانیهای وب مربوط به هدایت HTTP برای برآورده کردن درخواست پیمایش با
workbox-precachingاستفاده کرد. این سناریو معمولاً غیررایج است. - اکنون
workbox-precachingهنگام جستجوی پاسخ پیشنهانسازیشده برای درخواست دادهشده، پارامتر پُرسمان نشانی وبfbclidرا نادیده میگیرد. - سازنده
PrecacheControllerاکنون بهجای رشته، شیئی با ویژگیهای خاص را بهعنوان پارامتر خود میگیرد. این شیء از ویژگیهای زیر پشتیبانی میکند:cacheName(که همان هدف رشتهای را دارد که در نسخه ۵ به سازنده ارسال شده است)،plugins(که جایگزین روشaddPlugins()از نسخه ۵ میشود)، وfallbackToNetwork(که جایگزین گزینه مشابهی میشود که بهcreateHandler()و `createHandlerBoundToURL() در نسخه ۵ ارسال شده است). - روشهای
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 خود پشتیبانی میکند.
ابزارهای ساخت به Node.js نسخه ۱۰ یا بالاتر نیاز دارند
نسخههای Node.js قبلاز v10 دیگر برای workbox-webpack-plugin، workbox-build، یا workbox-cli پشتیبانی نمیشوند. اگر از نسخه Node.js قدیمیتر از v8 استفاده میکنید، زمان اجرای خود را به نسخه پشتیبانیشده بهروز کنید.
بهبودهای جدید
workbox-strategies
Workbox v6 روش جدیدی را برای توسعهدهندگان شخص ثالث معرفی میکند تا استراتژیهای Workbox خود را تعریف کنند. این کار تضمین میکند که توسعهدهندگان طرف سوم این قابلیت را دارند که Workbox را بهگونهای گسترش دهند که نیازهایشان را کاملاً برآورده کند.
کلاس پایه راهبرد جدید
در نسخه ۶، همه کلاسهای استراتژی Workbox باید کلاس پایه جدید Strategy را گسترش دهند. همه استراتژیهای داخلی برای پشتیبانی از این موضوع بازنویسی شدهاند.
کلاس پایه Strategy مسئول دو چیز اصلی است:
- فراخوانی فراخوانهای برگشتی چرخه حیات افزونه که برای همه گردانندههای استراتژی مشترک است (مثلاً وقتی شروع میشوند، پاسخ میدهند، و پایان مییابند).
- ایجاد یک نمونه «گرداننده» که میتواند وضعیت را برای هر درخواست جداگانهای که یک استراتژی مدیریت میکند، مدیریت کند.
کلاس «گرداننده» جدید
قبلاً ماژولهای داخلی داشتیم که fetchWrapper و cacheWrapper را فراخوانی میکردند، که (همانطور که از نامشان پیداست) میاناهای برنامهسازی کاربردی مختلف واکشی و حافظه پنهان را با قلابهایی در چرخه حیاتشان میپوشانند. این سازوکاری است که درحالحاضر به افزونهها اجازه میدهد کار کنند، اما برای توسعهدهندگان آشکار نیست.
کلاس «گرداننده» جدید، StrategyHandler، این روشها را آشکار میکند تا استراتژیهای سفارشی بتوانند fetch() یا cacheMatch() را فراخوانی کنند و هر افزونهای که به نمونه استراتژی اضافه شده است بهطور خودکار فراخوانی شود.
این کلاس همچنین به توسعهدهندگان امکان میدهد فراخوانیهای برگشتی سفارشی و چرخه حیات خود را که ممکن است مختص استراتژیهای آنها باشد اضافه کنند و این فراخوانیها «بهراحتی» با میانای افزونه موجود کار خواهند کرد.
وضعیت چرخه حیات افزونه جدید
در Workbox نسخه ۵، افزونهها بدون حالت هستند. یعنی اگر درخواستی برای /index.html هم فراخوانی برگشتی requestWillFetch و هم فراخوانی برگشتی cachedResponseWillBeUsed را راهاندازی کند، این دو فراخوانی برگشتی هیچ راهی برای برقراری ارتباط با یکدیگر ندارند یا حتی نمیدانند که توسط یک درخواست راهاندازی شدهاند.
در نسخه ۶، همه فراخوانیهای برگشتی افزونه نیز به شیء state جدیدی منتقل خواهند شد. این شیء حالت برای این شیء افزونه خاص و این فراخوانی استراتژی خاص (یعنی فراخوانی handle()) منحصربهفرد خواهد بود. این به توسعهدهندگان امکان میدهد افزونههایی بنویسند که در آنها یک فراخوان برگشتی میتواند بهطور مشروط کاری را براساس آنچه فراخوان برگشتی دیگری در همان افزونه انجام داده است انجام دهد (مثلاً محاسبه دلتای زمانی بین اجرای requestWillFetch و fetchDidSucceed یا fetchDidFail).
فراخوانیهای جدید چرخه حیات افزونه
فراخوانیهای برگشتی چرخه حیات افزونه جدیدی اضافه شده است تا توسعهدهندگان بتوانند بهطور کامل از وضعیت چرخه حیات افزونه بهره ببرند:
-
handlerWillStart: قبلاز شروع اجرای منطق گرداننده فراخوانی میشود. از این فراخوانی برگشتی میتوان برای تنظیم وضعیت اولیه گرداننده استفاده کرد (مثلاً ثبت زمان شروع). handlerWillRespond: قبلاز اینکه روش استراتژیهایhandle()پاسخی برگرداند فراخوانی شده است. از این فراخوانی برگشتی میتوان برای اصلاح آن پاسخ قبلاز برگرداندن آن به یک کنترلکننده مسیر یا منطق سفارشی دیگر استفاده کرد.-
handlerDidRespond: پساز اینکه روشhandle()استراتژی پاسخی را برمیگرداند فراخوانی میشود. از این فراخوانی برگشتی میتوان برای ثبت جزئیات پاسخ نهایی استفاده کرد، مثلاً پساز تغییراتی که افزایههای دیگر ایجاد کردهاند. handlerDidComplete: پساز اینکه همه قولهای تمدید طول عمر اضافهشده به رویداد از فراخوانی این استراتژی حلوفصل شدند، فراخوانی میشود. از این فراخوانی برگشتی میتوان برای گزارش کردن هر دادهای که برای محاسبه باید تا اتمام کار گرداننده منتظر بماند (مثلاً وضعیت اصابت حافظه پنهان، تأخیر حافظه پنهان، تأخیر شبکه) استفاده کرد.handlerDidError: اگر گرداننده نتواند پاسخ معتبری از هیچ منبعی ارائه دهد، فراخوانی میشود. از این فراخوانی میتوان برای ارائه محتوای «جایگزین» بهعنوان جایگزینی برای خطای شبکه استفاده کرد.
توسعهدهندگانی که استراتژیهای سفارشی خودشان را پیادهسازی میکنند لازم نیست نگران فراخوانی این فراخوانهای برگشتی باشند؛ همه اینها توسط کلاس پایه جدید Strategy مدیریت میشود.
انواع TypeScript دقیقتر برای گردانندهها
تعاریف TypeScript برای روشهای مختلف فراخوانی عادیسازی شده است. این کار باید به تجربه بهتری برای توسعهدهندگانی که از TypeScript استفاده میکنند و کد خودشان را برای پیادهسازی یا فراخوانی گردانندهها مینویسند منجر شود.
workbox-window
روش جدید messageSkipWaiting()
روش جدیدی به نام messageSkipWaiting() به ماژول workbox-window اضافه شده است تا فرایند دستور دادن به «waiting» service worker برای فعال شدن سادهتر شود. این نسخه بهبودهایی را ارائه میدهد:
- این روش
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 تنظیم میشود و درغیراینصورت، روی 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-strategies استفاده میکند
workbox-precaching بازنویسی شده است تا از workbox-strategies بهعنوان پایه استفاده کند. این کار نباید به تغییرات مخرب منجر شود و باید به سازگاری بلندمدت بهتری در نحوه دسترسی دو ماژول به شبکه و حافظه پنهان منجر شود.
پیشذخیرهسازی اکنون ورودیها را یکییکی پردازش میکند، نه بهصورت انبوه
workbox-precaching بهروزرسانی شده است تا بهجای تلاش برای درخواست و ذخیره همه ورودیها در حافظه نهان بهطور همزمان (و واگذار کردن نحوه کنترل سرعت به مرورگر)، فقط یک ورودی در مانیفست پیشذخیره در حافظه نهان درخواست و ذخیره شود.
این کار باید احتمال خطاهای net::ERR_INSUFFICIENT_RESOURCES را درحین پیشذخیرهسازی کاهش دهد و همچنین باید رقابت پهنای باند بین پیشذخیرهسازی و درخواستهای همزمان ایجادشده توسط برنامه وب را کاهش دهد.
PrecacheFallbackPlugin امکان بازگشت به حالت آفلاین را آسانتر میکند
workbox-precaching اکنون شامل PrecacheFallbackPlugin است که روش چرخه حیات جدید handlerDidError اضافهشده در نسخه ۶ را پیادهسازی میکند.
این کار باعث میشود که وقتی پاسخی دردسترس نیست، بهراحتی بتوانید نشانی وب پیشذخیرهشدهای را بهعنوان «جایگزین» برای استراتژی خاصی مشخص کنید. افزونه بهدرستی کلید حافظه نهان صحیح را برای نشانی وب پیشنهانسازیشده، ازجمله هر پارامتر بازبینی موردنیاز، میسازد.
در اینجا نمونهای از استفاده از آن برای پاسخ دادن با /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 به ما اطلاع دهید.