โมดูล ES ใน Service Worker

ทางเลือกสมัยใหม่สำหรับ ImportScripts()

ข้อมูลเบื้องต้น

โมดูล ES เป็นเกมโปรดของนักพัฒนาซอฟต์แวร์มาระยะหนึ่งแล้ว นอกจาก ประโยชน์อื่นๆ อีก นำเสนอรูปแบบโมดูลที่เป็นสากล ซึ่งสามารถให้โค้ดที่แชร์ได้ เผยแพร่ครั้งเดียวและใช้ในเบราว์เซอร์และในรันไทม์อื่นๆ เช่น Node.js ขณะที่ เบราว์เซอร์รุ่นใหม่ทั้งหมด รองรับโมดูล ES บ้าง แต่ก็ไม่ได้ให้การสนับสนุนในทุกที่ สามารถเรียกใช้ได้ โดยเฉพาะอย่างยิ่ง การรองรับการนำเข้าโมดูล ES ภายใน ของ โปรแกรมทำงานของบริการ จะเริ่มให้บริการในวงกว้างมากขึ้น

บทความนี้อธิบายถึงสถานะปัจจุบันของการรองรับโมดูล ES ใน Service Worker ในเบราว์เซอร์ที่ใช้กันทั่วไป รวมถึงข้อผิดพลาดบางอย่างที่ควรหลีกเลี่ยง และแนวทางปฏิบัติแนะนำสำหรับ รหัส Service Worker ที่เข้ากันได้แบบย้อนหลังสำหรับการจัดส่ง

กรณีการใช้งาน

กรณีการใช้งานที่เหมาะที่สุดสำหรับโมดูล ES ภายในโปรแกรมทำงานของบริการคือการโหลด ไลบรารีสมัยใหม่หรือโค้ดการกำหนดค่าที่แชร์กับรันไทม์อื่นๆ ที่ รองรับโมดูล ES

การพยายามแชร์โค้ดด้วยวิธีนี้ก่อนโมดูล ES ที่เกี่ยวข้องกับเวอร์ชันที่เก่ากว่า "สากล" รูปแบบโมดูล เช่น UMD ที่มี ต้นแบบที่ไม่จำเป็นและการเขียนโค้ดที่ทำการเปลี่ยนแปลงกับ ตัวแปร

สคริปต์ที่นำเข้าผ่านโมดูล ES จะทริกเกอร์โปรแกรมทำงานของบริการได้ อัปเดต หากมีการเปลี่ยนแปลงเนื้อหา โดยจับคู่กับ พฤติกรรม จาก importScripts()

ข้อจำกัดปัจจุบัน

การนำเข้าแบบคงที่เท่านั้น

คุณสามารถนำเข้าโมดูล ES ได้ 2 วิธี ดังนี้ แบบคงที่ โดยใช้ไวยากรณ์ import ... from '...' หรือ แบบไดนามิก โดยใช้เมธอด import() ภายใน Service Worker จะมีเพียง ไวยากรณ์ได้รับการรองรับในปัจจุบัน

ข้อจำกัดนี้คล้ายคลึงกับ ข้อจำกัดที่คล้ายกัน มีการดำเนินการเมื่อ importScripts() การโทรแบบไดนามิกไปยัง importScripts() จะไม่ ทำงานภายใน Service Worker และการเรียกใช้ importScripts() ทั้งหมด ทำงานพร้อมกันโดยธรรมชาติ ต้องทำให้เสร็จก่อนที่โปรแกรมทำงานของบริการจะดำเนินการเสร็จสมบูรณ์ install ข้อจำกัดนี้ช่วยให้เบราว์เซอร์ รู้ว่า เบราว์เซอร์รู้จักและ สามารถแคชโดยปริยาย โค้ด JavaScript ทั้งหมดที่จำเป็นสำหรับโปรแกรมทำงานของบริการ การใช้งานในระหว่างการติดตั้ง

ท้ายที่สุดแล้ว ข้อจำกัดนี้อาจถูกยกเลิกและมีการเปลี่ยนแปลงในสเปน การนำเข้าโมดูล อาจได้รับอนุญาต สำหรับตอนนี้ โปรดตรวจสอบว่าคุณใช้เฉพาะไวยากรณ์แบบคงที่ภายในของ Service Worker

แล้วผู้ปฏิบัติงานคนอื่นๆ ล่ะ

การสนับสนุนสำหรับ โมดูล ES ใน "เฉพาะ" ผู้ปฏิบัติงาน—คนทำงานเหล่านี้ สร้างขึ้นด้วย new Worker('...', {type: 'module'}) ซึ่งแพร่หลายกว่าและ ได้รับการรองรับใน Chrome และ Edge ตั้งแต่ เวอร์ชัน 80 และ Safari เวอร์ชันล่าสุด ผู้ปฏิบัติงานเฉพาะรองรับการนำเข้าโมดูล ES แบบคงที่และแบบไดนามิก

Chrome และ Edge มีโมดูล ES ที่รองรับใน ผู้ปฏิบัติงานที่แชร์ ตั้งแต่เวอร์ชัน 83 แต่ยังไม่มี เบราว์เซอร์อื่นๆ ให้การสนับสนุนในเวลานี้

ไม่รองรับการนำเข้าแผนที่

การนำเข้าแผนที่ช่วยให้คุณ เพื่อเขียนตัวระบุโมดูลใหม่ เช่น เพิ่มไว้ข้างหน้า URL ของ CDN ที่ต้องการซึ่งโหลดโมดูล ES ได้

ขณะที่ใช้ Chrome และ Edge เวอร์ชัน 89 ขึ้นไป รองรับการนำเข้าแผนที่ ไม่สามารถใช้ได้กับบริการ ผู้ปฏิบัติงาน

การสนับสนุนเบราว์เซอร์

Chrome และ Edge รองรับโมดูล ES ใน Service Worker ตั้งแต่เริ่มต้น เวอร์ชัน 91

Safari ได้เพิ่มการรองรับใน ตัวอย่างเทคโนโลยี 122 รุ่น, และนักพัฒนาซอฟต์แวร์น่าจะได้เห็นฟังก์ชันนี้เปิดตัวในเวอร์ชัน Safari ในอนาคต

โค้ดตัวอย่าง

นี่คือตัวอย่างพื้นฐานของการใช้โมดูล ES ที่แชร์ใน window ของเว็บแอป ขณะที่ลงทะเบียน Service Worker ที่ใช้โมดูล 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 แต่จากข้อความที่เขียนมานี้ กลับไม่ใช่แบบนั้น

เพื่อรองรับเบราว์เซอร์ที่ไม่มีการสนับสนุนในตัว คุณสามารถใช้ สคริปต์โปรแกรมทำงานของบริการผ่าน Bundler ที่ใช้ร่วมกันได้กับโมดูล ES เพื่อสร้าง Service Worker ที่มีโค้ดโมดูลทั้งหมดในบรรทัดและจะทำงาน เบราว์เซอร์รุ่นเก่า หรือถ้าโมดูลที่คุณพยายามนำเข้า มีแพ็กเกจอยู่แล้วใน IIFE หรือ รูปแบบ UMD คุณสามารถนำเข้าได้โดยใช้ importScripts()

เมื่อคุณใช้ Service Worker ได้ 2 เวอร์ชัน เวอร์ชันที่ใช้ ES และอื่นๆ ที่ไม่มี คุณจะต้องตรวจหา ที่เบราว์เซอร์รองรับ และลงทะเบียนสคริปต์ Service Worker ที่เกี่ยวข้อง ดีที่สุด แนวทางปฏิบัติในการตรวจหาการสนับสนุนกำลังเกิดการทะลัก แต่คุณสามารถทำตาม การสนทนาใน ปัญหาเกี่ยวกับ GitHub สำหรับ วิดีโอแนะนำ

_รูปภาพโดย Vlado Paunovic ใน Unsplash_