Mô-đun ES trong trình chạy dịch vụ

Phương thức thay thế hiện đại cho importScripts().

Thông tin khái quát

Mô-đun ES đã được nhà phát triển yêu thích từ lâu. Ngoài một số lợi ích khác, chúng còn hứa hẹn về một định dạng mô-đun chung, trong đó mã dùng chung có thể được phát hành một lần và chạy trong các trình duyệt và trong các thời gian chạy thay thế như Node.js. Mặc dù tất cả trình duyệt hiện đại đều hỗ trợ một số mô-đun ES, nhưng không phải tất cả trình duyệt đều hỗ trợ mọi nơi có thể chạy mã. Cụ thể, chúng tôi mới chỉ bắt đầu cung cấp rộng rãi tính năng hỗ trợ nhập các mô-đun ES bên trong trình chạy dịch vụ của trình duyệt.

Bài viết này trình bày chi tiết về trạng thái hiện tại của tính năng hỗ trợ mô-đun ES trong trình chạy dịch vụ trên các trình duyệt phổ biến, cùng với một số lỗi cần tránh, cũng như các phương pháp hay nhất để vận chuyển mã của trình chạy dịch vụ có khả năng tương thích ngược.

Trường hợp sử dụng

Trường hợp sử dụng lý tưởng cho các mô-đun ES bên trong trình chạy dịch vụ là để tải mã cấu hình hoặc thư viện hiện đại được chia sẻ với các thời gian chạy khác hỗ trợ các mô-đun ES.

Hãy cố gắng chia sẻ mã theo cách này trước khi các mô-đun ES đòi hỏi phải sử dụng các định dạng mô-đun "phổ biến" cũ hơn như UMD có chứa mã nguyên mẫu không cần thiết và viết mã đã thực hiện thay đổi đối với các biến hiển thị toàn cục.

Các tập lệnh được nhập qua các mô-đun ES có thể kích hoạt quy trình cập nhật của trình chạy dịch vụ nếu nội dung của các tập lệnh đó thay đổi, phù hợp với hành vi của importScripts().

Hạn chế hiện tại

Chỉ nhập dữ liệu tĩnh

Bạn có thể nhập các mô-đun ES theo một trong 2 cách: tĩnh, sử dụng cú pháp import ... from '...' hoặc động bằng phương thức import(). Bên trong một trình chạy dịch vụ, hiện chỉ có cú pháp tĩnh được hỗ trợ.

Giới hạn này tương tự như hạn chế tương tự đặt ra cho việc sử dụng importScripts(). Các lệnh gọi động đến importScripts() không hoạt động bên trong trình chạy dịch vụ và tất cả các lệnh gọi importScripts() vốn đồng bộ hoá, phải hoàn tất trước khi trình chạy dịch vụ hoàn tất giai đoạn install. Quy định hạn chế này đảm bảo rằng trình duyệt biết và có thể ngầm lưu vào bộ nhớ đệm tất cả mã JavaScript cần thiết để triển khai trình chạy dịch vụ trong quá trình cài đặt.

Cuối cùng, quy định hạn chế này có thể được gỡ bỏ và có thể được phép nhập mô-đun ES động. Hiện tại, hãy đảm bảo rằng bạn chỉ sử dụng cú pháp tĩnh bên trong một trình chạy dịch vụ.

Còn các trình thực thi khác thì sao?

Hỗ trợ các mô-đun ES trong trình thực thi "chuyên biệt" (những mô-đun được tạo bằng new Worker('...', {type: 'module'})) phổ biến hơn và đã được hỗ trợ trong Chrome và Edge kể từ phiên bản 80, cũng như các phiên bản gần đây của Safari. Cả tính năng nhập mô-đun ES tĩnh và động đều được hỗ trợ trong worker chuyên dụng.

Chrome và Edge đã hỗ trợ các mô-đun ES trong nhân viên dùng chung kể từ phiên bản 83, nhưng hiện chưa có trình duyệt nào khác hỗ trợ.

Không hỗ trợ nhập bản đồ

Nhập bản đồ cho phép các môi trường thời gian chạy viết lại thông số mô-đun, chẳng hạn như thêm vào trước URL của CDN ưa thích mà từ đó các mô-đun ES có thể được tải.

Mặc dù Chrome và Edge phiên bản 89 trở lên hỗ trợ bản đồ nhập, nhưng hiện tại, bạn không thể sử dụng các trình thực thi dịch vụ này.

Hỗ trợ trình duyệt

Các mô-đun ES trong trình chạy dịch vụ được hỗ trợ trong Chrome và Edge kể từ phiên bản 91.

Safari đã hỗ trợ thêm trong Bản phát hành dùng thử công nghệ 122 và nhà phát triển dự kiến sẽ thấy chức năng này được phát hành trong phiên bản Safari ổn định trong tương lai.

Ví dụ về mã

Đây là ví dụ cơ bản về cách sử dụng mô-đun ES dùng chung trong ngữ cảnh window của ứng dụng web, đồng thời đăng ký một trình chạy dịch vụ sử dụng cùng một mô-đun 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);
    // ...
  })());
});

Khả năng tương thích ngược

Ví dụ trên sẽ phù hợp nếu tất cả các trình duyệt đều hỗ trợ mô-đun ES trong trình thực thi dịch vụ, nhưng tại thời điểm viết bài này, thì không đúng như vậy.

Để phù hợp với các trình duyệt không được tích hợp sẵn tính năng hỗ trợ, bạn có thể chạy tập lệnh trình chạy dịch vụ thông qua trình đóng gói tương thích với mô-đun ES để tạo một trình chạy dịch vụ bao gồm tất cả mã mô-đun cùng dòng và sẽ hoạt động trong các trình duyệt cũ hơn. Ngoài ra, nếu các mô-đun mà bạn đang cố nhập đã có sẵn theo gói ở định dạng IIFE hoặc UMD, thì bạn có thể nhập các mô-đun đó bằng cách sử dụng importScripts().

Khi có hai phiên bản trình chạy dịch vụ – một phiên bản sử dụng mô-đun ES và phiên bản còn lại không sử dụng mô-đun ES, bạn sẽ cần phát hiện những gì mà trình duyệt hiện tại hỗ trợ và đăng ký tập lệnh trình chạy dịch vụ tương ứng. Các phương pháp hay nhất để phát hiện tính năng hỗ trợ hiện có thông lượng, nhưng bạn có thể làm theo nội dung thảo luận trong vấn đề này trên GitHub để biết các đề xuất.

_Ảnh chụp của Vlado Paunovic trên Unsplash_