ماژول های ES در کارگران خدماتی

جایگزینی مدرن برای importScripts().

زمینه

ماژول های ES برای مدتی مورد علاقه توسعه دهندگان بوده اند. علاوه بر تعدادی از مزایای دیگر ، آنها نوید یک قالب ماژول جهانی را ارائه می دهند که در آن کد مشترک می تواند یک بار منتشر شود و در مرورگرها و در زمان های اجرای جایگزین مانند Node.js اجرا شود. در حالی که همه مرورگرهای مدرن برخی از ماژول‌های ES را پشتیبانی می‌کنند، همه آنها در هر جایی که بتوان کد را اجرا کرد، پشتیبانی نمی‌کنند. به طور خاص، پشتیبانی برای وارد کردن ماژول‌های ES در داخل سرویس‌کار مرورگر به‌تازگی در دسترس‌تر می‌شود.

این مقاله وضعیت فعلی پشتیبانی از ماژول ES در سرویس‌کاران در مرورگرهای رایج، همراه با برخی از مشکلاتی که باید اجتناب شود و بهترین شیوه‌ها برای ارسال کد سرویس‌کار سازگار با معکوس توضیح می‌دهد.

موارد استفاده کنید

مورد استفاده ایده آل برای ماژول های ES در داخل سرویس کاران برای بارگذاری یک کتابخانه مدرن یا کد پیکربندی است که با سایر زمان های اجرا که از ماژول های ES پشتیبانی می کنند به اشتراک گذاشته شده است.

تلاش برای اشتراک‌گذاری کد به این روش قبل از ماژول‌های ES مستلزم استفاده از قالب‌های ماژول «جهان‌شمول» قدیمی‌تر مانند UMD است که شامل دیگ بخار غیرضروری است، و نوشتن کدی که تغییراتی را در متغیرهای در معرض دید جهانی ایجاد می‌کند.

اسکریپت‌های وارد شده از طریق ماژول‌های ES می‌توانند در صورت تغییر محتویات آنها، جریان به‌روزرسانی سرویس‌کارگر را فعال کنند و با رفتار importScripts() مطابقت داشته باشند.

محدودیت های فعلی

فقط واردات استاتیک

ماژول‌های ES را می‌توان به یکی از دو روش وارد کرد: یا به صورت استاتیک ، با استفاده از import ... from '...' ، یا به صورت پویا ، با استفاده از روش import() . در داخل یک سرویس کار، در حال حاضر فقط نحو ایستا پشتیبانی می شود.

این محدودیت مشابه محدودیت مشابهی است که در استفاده از importScripts() قرار داده شده است. فراخوانی‌های دینامیک به importScripts() در داخل یک سرویس‌کار کار نمی‌کنند، و همه فراخوان‌های importScripts() که ذاتاً همزمان هستند، باید قبل از اتمام مرحله install توسط سرویس‌گر تکمیل شوند. این محدودیت تضمین می‌کند که مرورگر از تمام کدهای جاوا اسکریپت مورد نیاز برای پیاده‌سازی یک سرویس‌گر در حین نصب مطلع است و می‌تواند به طور ضمنی حافظه پنهان کند.

در نهایت، این محدودیت ممکن است برداشته شود و ممکن است وارد کردن ماژول ES پویا مجاز باشد . در حال حاضر، مطمئن شوید که فقط از نحو ایستا در داخل یک سرویس دهنده استفاده می کنید.

کارگران دیگر چطور؟

پشتیبانی از ماژول‌های ES در کارگران «اختصاصی» - آنهایی که با new Worker('...', {type: 'module'}) ساخته شده‌اند - گسترده‌تر است و از نسخه 80 و همچنین در Chrome و Edge پشتیبانی می‌شود. نسخه های اخیر سافاری هر دو واردات ماژول ES استاتیک و پویا در کارگران اختصاص داده شده پشتیبانی می شوند.

کروم و اج از نسخه 83 از ماژول‌های ES در کارگران اشتراکی پشتیبانی می‌کنند، اما هیچ مرورگر دیگری در حال حاضر پشتیبانی نمی‌کند.

پشتیبانی از نقشه های وارداتی وجود ندارد

نقشه‌های وارداتی به محیط‌های زمان اجرا اجازه می‌دهند تا مشخص‌کننده‌های ماژول را بازنویسی کنند، برای مثال، URL یک CDN ترجیحی را که می‌توان از آن ماژول‌های ES بارگیری کرد، پیش‌نویس کرد.

در حالی که Chrome و Edge نسخه 89 و بالاتر از نقشه‌های وارداتی پشتیبانی می‌کنند، در حال حاضر نمی‌توان از آنها با سرویس‌دهندگان استفاده کرد .

پشتیبانی از مرورگر

ماژول‌های ES در سرویس‌کاران در Chrome و Edge با نسخه 91 پشتیبانی می‌شوند.

سافاری در نسخه پیش‌نمایش فناوری 122 پشتیبانی اضافه کرد و توسعه‌دهندگان باید انتظار داشته باشند که در آینده شاهد انتشار این قابلیت در نسخه پایدار سافاری باشند.

کد نمونه

این یک مثال اساسی از استفاده از یک ماژول ES به اشتراک گذاشته شده در زمینه window یک برنامه وب است، در حالی که یک سرویس دهنده را نیز ثبت می کند که از همان ماژول ES استفاده می کند:

// Inside config.js:
export const cacheName = 'my-cache';
// Inside your web app:
<script type="module">
  import {cacheName} from './config.js';
  // Do something with cacheName.

  await navigator.serviceWorker.register('es-module-sw.js', {
    type: 'module',
  });
</script>
// Inside es-module-sw.js:
import {cacheName} from './config.js';

self.addEventListener('install', (event) => {
  event.waitUntil((async () => {
    const cache = await caches.open(cacheName);
    // ...
  })());
});

سازگاری با عقب

اگر همه مرورگرها از ماژول‌های ES در سرویس‌دهنده‌ها پشتیبانی کنند، مثال بالا به خوبی کار می‌کند، اما از زمان نوشتن این مقاله، اینطور نیست.

برای قرار دادن مرورگرهایی که پشتیبانی داخلی ندارند، می‌توانید اسکریپت Service Worker خود را از طریق یک باندلر سازگار با ماژول ES اجرا کنید تا یک سرویس‌کار ایجاد کنید که شامل همه کدهای ماژول درون خطی باشد و در مرورگرهای قدیمی‌تر کار کند. از طرف دیگر، اگر ماژول‌هایی که می‌خواهید وارد کنید در قالب‌های IIFE یا UMD در دسترس هستند، می‌توانید آنها را با استفاده از importScripts() وارد کنید.

هنگامی که دو نسخه از Service Worker خود را در دسترس دارید - یکی که از ماژول‌های ES استفاده می‌کند و دیگری که از ماژول‌های ES استفاده نمی‌کند، باید تشخیص دهید که مرورگر فعلی چه چیزی را پشتیبانی می‌کند و اسکریپت مربوطه را ثبت کنید. بهترین روش‌ها برای شناسایی پشتیبانی در حال حاضر در جریان هستند، اما می‌توانید بحث را در این شماره GitHub برای توصیه‌ها دنبال کنید.

_عکس از Vlado Paunovic در Unsplash _