ماژول workbox-sw
راه بسیار آسانی را برای راه اندازی و اجرا با ماژول های Workbox فراهم می کند، بارگذاری ماژول های Workbox را ساده می کند و برخی از روش های کمکی ساده را ارائه می دهد.
میتوانید workbox-sw
از طریق CDN ما استفاده کنید یا از آن با مجموعهای از فایلهای جعبه کاری در سرور خود استفاده کنید.
ساده ترین راه برای شروع استفاده از این ماژول از طریق CDN است. فقط باید موارد زیر را به سرویسکار خود اضافه کنید:
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);
با این کار، فضای نام workbox
را در سرویسکار خود خواهید داشت که دسترسی به همه ماژولهای Workbox را فراهم میکند.
workbox.precaching.*
workbox.routing.*
etc
زمانی که شما شروع به استفاده از ماژول های اضافی می کنید، جادویی وجود دارد.
هنگامی که برای اولین بار به یک ماژول ارجاع می دهید، workbox-sw
آن را تشخیص داده و قبل از در دسترس قرار دادن ماژول آن را بارگذاری می کند. می توانید این اتفاق را در تب شبکه در DevTools مشاهده کنید.
این فایل ها توسط مرورگر شما ذخیره می شوند و آنها را برای استفاده آفلاین در آینده در دسترس قرار می دهد.
اگر نمیخواهید از CDN استفاده کنید، به اندازه کافی آسان است که به فایلهای Workbox میزبانی شده در دامنه خودتان بروید.
سادهترین روش این است که فایلها را از طریق دستور copyLibraries
workbox-cli
دریافت کنید و سپس به workbox-sw
بگویید این فایلها را از طریق گزینه modulePathPrefix
config کجا پیدا کند.
اگر فایلها را در /third_party/workbox-vX.YZ/
قرار دهید، از آنها به شکل زیر استفاده میکنید:
importScripts('/third_party/workbox-vX.Y.Z/workbox-sw.js');
workbox.setConfig({
modulePathPrefix: '/third_party/workbox-vX.Y.Z/',
});
در زیر هود، بارگیری ماژول های جدید برای اولین بار شامل فراخوانی importScripts()
با مسیر فایل جاوا اسکریپت مربوطه (چه در CDN میزبانی می شود یا از طریق یک URL محلی) است. در هر صورت، یک محدودیت مهم اعمال میشود: فراخوانهای ضمنی به importScripts()
فقط میتوانند در داخل کنترلر install
یک سرویسگر یا در طول اجرای همزمان و اولیه اسکریپت سرویسکار انجام شوند.
برای جلوگیری از نقض این محدودیت، بهترین روش ارجاع به workbox.*
خارج از کنترل کننده رویداد یا توابع ناهمزمان است.
به عنوان مثال، کد سرویسکار سطح بالا زیر مناسب است:
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);
// This will work!
workbox.routing.registerRoute(
({request}) => request.destination === 'image',
new workbox.strategies.CacheFirst()
);
اما اگر به workbox.strategies
در جاهای دیگر در Service Worker خود ارجاع نداده باشید، کد زیر ممکن است مشکل ساز باشد:
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);
self.addEventListener('fetch', event => {
if (event.request.url.endsWith('.png')) {
// Oops! This causes workbox-strategies.js to be imported inside a fetch handler,
// outside of the initial, synchronous service worker execution.
const cacheFirst = new workbox.strategies.CacheFirst();
event.respondWith(cacheFirst.handle({request: event.request}));
}
});
اگر نیاز به نوشتن کدی دارید که در غیر این صورت با این محدودیت مخالفت کند، میتوانید با استفاده از متد workbox.loadModule()
فراخوانی ( importScripts()
را خارج از کنترلکننده رویداد راهاندازی کنید:
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);
// This will trigger the importScripts() for workbox.strategies and its dependencies:
workbox.loadModule('workbox-strategies');
self.addEventListener('fetch', event => {
if (event.request.url.endsWith('.png')) {
// Referencing workbox.strategies will now work as expected.
const cacheFirst = new workbox.strategies.CacheFirst();
event.respondWith(cacheFirst.handle({request: event.request}));
}
});
از طرف دیگر، میتوانید یک مرجع به فضاهای نام مربوطه خارج از کنترلکنندههای رویداد خود ایجاد کنید، و سپس از آن مرجع استفاده کنید:
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);
// This will trigger the importScripts() for workbox.strategies and its dependencies:
const {strategies} = workbox;
self.addEventListener('fetch', event => {
if (event.request.url.endsWith('.png')) {
// Using the previously-initialized strategies will work as expected.
const cacheFirst = new strategies.CacheFirst();
event.respondWith(cacheFirst.handle({request: event.request}));
}
});
همه ماژول های Workbox دارای دو ساخت هستند، یک ساخت اشکال زدایی که شامل ورود به سیستم و بررسی نوع اضافی است و یک ساخت تولید که لاگ و بررسی نوع را حذف می کند.
به طور پیشفرض، workbox-sw
از ساخت اشکالزدایی برای سایتهای روی لوکال هاست استفاده میکند، اما برای هر منبع دیگری از ساخت تولید استفاده میکند.
اگر میخواهید اشکالزدایی یا ساختهای تولید را اجباری کنید، میتوانید گزینه پیکربندی debug
را تنظیم کنید:
workbox.setConfig({
debug: true,
});
workbox-sw
تبدیل کنید هنگام بارگیری Workbox با استفاده از workbox-sw
، همه بستههای Workbox از طریق فضای نام جهانی workbox.*
قابل دسترسی هستند.
اگر نمونه کدی دارید که از دستورهای import
استفاده میکند که میخواهید آنها را برای استفاده از workbox-sw
تبدیل کنید، تنها کاری که باید انجام دهید این است که workbox-sw
بارگیری کنید و همه دستورات import
را با متغیرهای محلی جایگزین کنید که به آن ماژولها در فضای نام جهانی اشاره میکنند.
این کار به این دلیل کار میکند که هر بسته Workbox Service Worker منتشر شده در npm نیز در فضای نام workbox
جهانی از طریق یک نسخه camelCase از نام موجود است (مثلاً همه ماژولهای صادر شده از بسته npm workbox-precaching
را میتوان در workbox.precaching.*
. و همه موارد ماژول های صادر شده از بسته npm workbox-background-sync
می توان در workbox.backgroundSync.*
یافت.
به عنوان مثال، در اینجا کدی وجود دارد که از عبارات import
برای ارجاع به ماژول های Workbox استفاده می کند:
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponse} from 'workbox-cacheable-response';
registerRoute(
({request}) => request.destination === 'image',
new CacheFirst({
plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
})
);
و در اینجا همان کد برای استفاده از workbox-sw
بازنویسی شده است (توجه کنید که فقط عبارات import تغییر کرده است - منطق لمس نشده است):
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);
const {registerRoute} = workbox.routing;
const {CacheFirst} = workbox.strategies;
const {CacheableResponse} = workbox.cacheableResponse;
registerRoute(
({request}) => request.destination === 'image',
new CacheFirst({
plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
})
);