importScripts()의 최신 대안입니다.
배경
ES 모듈은 한동안 개발자들에게 인기를 끌었습니다. 다른 여러 이점 외에도, 공유 코드를 한 번 출시하고 브라우저와 Node.js와 같은 대체 런타임에서 실행할 수 있는 범용 모듈 형식을 제공합니다. 모든 최신 브라우저는 일부 ES 모듈 지원을 제공하지만, 코드를 실행할 수 있는 모든 위치에서 지원을 제공하지는 않습니다. 특히 브라우저의 서비스 워커 내에서 ES 모듈을 가져오는 기능이 이제 막 더 널리 지원되기 시작했습니다.
이 도움말에서는 일반적인 브라우저에서 서비스 워커의 ES 모듈 지원 현황과 피해야 할 몇 가지 문제, 하위 호환되는 서비스 워커 코드를 제공하기 위한 권장사항을 자세히 설명합니다.
사용 사례
서비스 워커 내에서 ES 모듈을 사용하는 이상적인 사용 사례는 ES 모듈을 지원하는 다른 런타임과 공유되는 최신 라이브러리 또는 구성 코드를 로드하는 것입니다.
ES 모듈 이전에 이러한 방식으로 코드를 공유하려면 불필요한 상용구를 포함하는 UMD와 같은 이전의 '범용' 모듈 형식을 사용하고 전역적으로 노출된 변수를 변경하는 코드를 작성해야 했습니다.
ES 모듈을 통해 가져온 스크립트는 콘텐츠가 변경되면 서비스 워커 업데이트 흐름을 트리거하여 importScripts()의 동작과 일치시킬 수 있습니다.
현재 제한사항
정적 가져오기만
ES 모듈은 import ... from '...' 문법을 사용하여 정적으로 가져오거나 import() 메서드를 사용하여 동적으로 가져올 수 있습니다. 서비스 워커 내에서는 현재 정적 문법만 지원됩니다.
이 제한은 importScripts() 사용에 적용되는 유사한 제한과 유사합니다. importScripts()에 대한 동적 호출은 서비스 워커 내에서 작동하지 않으며, 본질적으로 동기식인 모든 importScripts() 호출은 서비스 워커가 install 단계를 완료하기 전에 완료되어야 합니다. 이 제한사항은 브라우저가 설치 중에 서비스 워커 구현에 필요한 모든 자바스크립트 코드를 알고 암시적으로 캐시할 수 있도록 합니다.
결국 이 제한이 해제되고 동적 ES 모듈 가져오기가 허용될 수 있습니다. 현재로서는 서비스 워커 내에서 정적 문법만 사용해야 합니다.
다른 작업자는 어떤가요?
new Worker('...', {type: 'module'})로 구성된 '전용' 작업자의 ES 모듈에 대한 지원은 더 광범위하며 버전 80 이후 Chrome 및 Edge와 Safari의 최근 버전에서 지원되었습니다.
전용 작업자에서는 정적 및 동적 ES 모듈 가져오기가 모두 지원됩니다.
Chrome과 Edge는 버전 83부터 공유 작업자에서 ES 모듈을 지원했지만 현재 다른 브라우저는 지원하지 않습니다.
가져오기 맵 지원 안함
가져오기 맵을 사용하면 런타임 환경에서 모듈 지정자를 다시 작성할 수 있습니다. 예를 들어 ES 모듈을 로드할 수 있는 기본 CDN의 URL을 앞에 추가할 수 있습니다.
Chrome 및 Edge 버전 89 이상에서는 가져오기 맵을 지원하지만 현재 서비스 워커와 함께 사용할 수 없습니다.
브라우저 지원
서비스 워커의 ES 모듈은 버전 91부터 Chrome 및 Edge에서 지원됩니다.
Safari는 Technology Preview 122 출시에서 지원을 추가했으며 개발자는 향후 Safari의 안정화 버전에서 이 기능이 출시될 것으로 예상할 수 있습니다.
예시 코드
다음은 웹 앱의 window 컨텍스트에서 공유 ES 모듈을 사용하면서 동일한 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 모듈을 지원하는 경우 제대로 작동하지만 이 글을 작성하는 시점에는 그렇지 않습니다.
기본 제공 지원이 없는 브라우저를 수용하려면 ES 모듈 호환 번들러를 통해 서비스 워커 스크립트를 실행하여 모든 모듈 코드를 인라인으로 포함하고 이전 브라우저에서 작동하는 서비스 워커를 만들면 됩니다. 또는 가져오려는 모듈이 이미 IIFE 또는 UMD 형식으로 번들로 제공되는 경우 importScripts()를 사용하여 가져올 수 있습니다.
ES 모듈을 사용하는 버전과 사용하지 않는 버전의 서비스 워커를 사용할 수 있게 되면 현재 브라우저에서 지원하는 항목을 감지하고 해당 서비스 워커 스크립트를 등록해야 합니다. 지원 감지를 위한 권장사항은 현재 유동적이지만 이 GitHub 문제의 토론을 따라 권장사항을 확인할 수 있습니다.