작업 상자-창

workbox-window 패키지는 window 컨텍스트, 즉 웹페이지 내에서 실행할 모듈 집합입니다. 이는 서비스 워커에서 실행되는 다른 작업 상자 패키지를 보완합니다.

workbox-window의 주요 기능/목표는 다음과 같습니다.

workbox-window 가져오기 및 사용

workbox-window 패키지의 기본 진입점은 Workbox 클래스이며 CDN에서 또는 널리 사용되는 자바스크립트 번들링 도구를 사용하여 코드로 가져올 수 있습니다.

CDN 사용

사이트에 Workbox 클래스를 가져오는 가장 쉬운 방법은 CDN에서 가져오는 것입니다.

<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    wb.register();
  }
</script>

이 예에서는 <script type="module">import을 사용하여 Workbox 클래스를 로드합니다. 이전 브라우저에서 작동하도록 이 코드를 트랜스파일해야 한다고 생각할 수도 있지만 실제로는 필요하지 않습니다.

서비스 워커를 지원하는 모든 주요 브라우저도 네이티브 JavaScript 모듈을 지원하므로 이 코드를 모든 브라우저에 제공하는 것은 괜찮습니다 (이전 브라우저는 무시하기만 함).

JavaScript 번들러로 Workbox 로드

workbox-window를 사용하는 데 도구가 전혀 필요하지 않지만 개발 인프라에 이미 npm 종속 항목과 함께 작동하는 webpack 또는 Rollup과 같은 번들러가 포함되어 있으면 이러한 번들러를 사용하여 workbox-window를 로드할 수 있습니다.

첫 번째 단계는 workbox-window를 애플리케이션의 종속 항목으로 설치하는 것입니다.

npm install workbox-window

그런 다음 애플리케이션의 JavaScript 파일 중 하나에서 workbox-window 패키지 이름을 참조하여 import 워크박스를 만듭니다.

import {Workbox} from 'workbox-window';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  wb.register();
}

번들러가 동적 가져오기 문을 통한 코드 분할을 지원하는 경우 workbox-window를 조건부로 로드할 수도 있습니다. 이렇게 하면 페이지의 기본 번들 크기를 줄이는 데 도움이 됩니다.

workbox-window는 상당히 작지만 사이트의 핵심 애플리케이션 로직으로 로드해야 할 이유가 없습니다. 서비스 워커의 특성상 점진적 향상이기 때문입니다.

if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}

고급 번들 개념

서비스 워커에서 실행되는 Workbox 패키지와 달리 package.json에 있는 workbox-windowmainmodule 필드에서 참조하는 빌드 파일은 ES5로 트랜스파일됩니다. 따라서 오늘날의 빌드 도구와 호환됩니다. 그중 일부는 개발자가 node_module 종속 항목의 어떤 것도 트랜스파일할 수 없습니다.

빌드 시스템에서 종속 항목을 트랜스파일할 수 있다면 (또는 코드를 트랜스파일할 필요가 없는 경우) 패키지 자체가 아니라 특정 소스 파일을 가져오는 것이 좋습니다.

다음은 Workbox를 가져올 수 있는 다양한 방법과 각 방법에 관한 설명입니다.

// Imports a UMD version with ES5 syntax
// (pkg.main: "build/workbox-window.prod.umd.js")
const {Workbox} = require('workbox-window');

// Imports the module version with ES5 syntax
// (pkg.module: "build/workbox-window.prod.es5.mjs")
import {Workbox} from 'workbox-window';

// Imports the module source file with ES2015+ syntax
import {Workbox} from 'workbox-window/Workbox.mjs';

Workbox 클래스를 가져온 후에는 이 클래스를 사용하여 서비스 워커를 등록하고 상호작용할 수 있습니다. 다음은 애플리케이션에서 Workbox를 사용할 수 있는 방법의 몇 가지 예입니다.

서비스 워커를 등록하고 서비스 워커가 처음 활성화될 때 사용자에게 알림

많은 웹 애플리케이션 사용자 서비스 워커는 애셋을 사전 캐시하여 후속 페이지 로드 시 앱이 오프라인으로 작동하도록 합니다. 경우에 따라 사용자에게 이제 앱을 오프라인에서 사용할 수 있다고 알리는 것이 타당할 수 있습니다.

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // `event.isUpdate` will be true if another version of the service
  // worker was controlling the page when this version was registered.
  if (!event.isUpdate) {
    console.log('Service worker activated for the first time!');

    // If your service worker is configured to precache assets, those
    // assets should all be available now.
  }
});

// Register the service worker after event listeners have been added.
wb.register();

서비스 워커가 설치되었지만 활성화 대기 중인 경우 사용자에게 알림

기존 서비스 워커가 제어하는 페이지가 새 서비스 워커를 등록하면, 기본적으로 초기 서비스 워커에 의해 제어되는 모든 클라이언트가 완전히 로드 취소될 때까지 해당 서비스 워커가 활성화되지 않습니다.

이는 특히 현재 페이지를 새로고침해도 새 서비스 워커가 활성화되지 않는 경우 개발자에게 혼란을 야기하는 일반적인 원인입니다.

혼동을 최소화하고 이러한 상황이 발생할 때 명확히 하기 위해 Workbox 클래스는 수신 대기할 수 있는 waiting 이벤트를 제공합니다.

const wb = new Workbox('/sw.js');

wb.addEventListener('waiting', event => {
  console.log(
    `A new service worker has installed, but it can't activate` +
      `until all tabs running the current version have fully unloaded.`
  );
});

// Register the service worker after event listeners have been added.
wb.register();

사용자에게 workbox-broadcast-update 패키지의 캐시 업데이트를 알립니다.

workbox-broadcast-update 패키지는 (빠른 전송을 위해) 캐시에서 콘텐츠를 제공하는 동시에 사용자에게 콘텐츠 업데이트를 알릴 수 있는 좋은 방법입니다 (비활성 상태 재검증 전략 사용).

창에서 이러한 업데이트를 수신하려면 CACHE_UPDATED 유형의 message 이벤트를 수신 대기하면 됩니다.

const wb = new Workbox('/sw.js');

wb.addEventListener('message', event => {
  if (event.data.type === 'CACHE_UPDATED') {
    const {updatedURL} = event.data.payload;

    console.log(`A newer version of ${updatedURL} is available!`);
  }
});

// Register the service worker after event listeners have been added.
wb.register();

캐시할 URL 목록을 서비스 워커에 전송

일부 애플리케이션의 경우 빌드 시 사전 캐시해야 하는 모든 애셋을 알 수 있지만, 일부 애플리케이션은 사용자가 먼저 방문하는 URL에 따라 완전히 다른 페이지를 제공합니다.

후자 카테고리에 있는 앱의 경우 사용자가 방문한 특정 페이지에 필요한 애셋만 캐시하는 것이 좋을 수 있습니다. workbox-routing 패키지를 사용하는 경우 캐시할 URL 목록을 라우터에 전송할 수 있습니다. 그러면 라우터 자체에 정의된 규칙에 따라 URL을 캐시합니다.

이 예에서는 새 서비스 워커가 활성화될 때마다 페이지에서 로드한 URL 목록을 라우터로 전송합니다. 서비스 워커에서 정의된 경로와 일치하는 URL만 캐시되므로 모든 URL을 보내도 됩니다.

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // Get the current page URL + all resources the page loaded.
  const urlsToCache = [
    location.href,
    ...performance.getEntriesByType('resource').map(r => r.name),
  ];
  // Send that list of URLs to your router in the service worker.
  wb.messageSW({
    type: 'CACHE_URLS',
    payload: {urlsToCache},
  });
});

// Register the service worker after event listeners have been added.
wb.register();

서비스 워커 수명 주기의 중요한 순간

서비스 워커 수명 주기는 복잡하므로 완전히 이해하기 어려울 수 있습니다. 이 서비스가 매우 복잡한 이유 중 하나는 서비스 워커의 가능한 모든 사용 (예: 둘 이상의 서비스 워커 등록, 여러 프레임에 여러 서비스 워커 등록, 다른 이름으로 서비스 워커 등록 등)에 관한 모든 특이 사례를 처리해야 하기 때문입니다.

하지만 서비스 워커를 구현하는 대부분의 개발자는 사용법이 매우 간단하므로 이러한 모든 특이 사례에 대해 걱정할 필요가 없습니다. 대부분의 개발자는 페이지 로드당 하나의 서비스 워커만 등록하고 서버에 배포하는 서비스 워커 파일의 이름을 변경하지 않습니다.

Workbox 클래스는 모든 서비스 워커 등록을 인스턴스 자체의 등록된 서비스 워커와 외부 서비스 워커라는 두 가지 카테고리로 나누어 서비스 워커 수명 주기에 관한 더 간단한 뷰를 수용합니다.

  • 등록된 서비스 워커: Workbox 인스턴스가 register()를 호출하여 설치를 시작한 서비스 워커 또는 register()를 호출한 경우 이미 활성화된 서비스 워커가 등록 시 updatefound 이벤트를 트리거하지 않았습니다.
  • 외부 서비스 워커: register()를 호출하는 Workbox 인스턴스와 별도로 설치를 시작한 서비스 워커입니다. 일반적으로 이 문제는 사용자가 다른 탭에서 사이트의 새 버전을 연 경우 발생합니다. 이벤트가 외부 서비스 워커에서 발생하면 이벤트의 isExternal 속성이 true로 설정됩니다.

이 두 가지 유형의 서비스 워커를 염두에 두고 중요한 서비스 워커 수명 주기의 모든 순간과 이를 처리하는 방법에 대한 개발자 권장사항이 아래에 정리되어 있습니다.

서비스 워커를 처음 설치할 때

서비스 워커가 처음 설치될 때를 이후의 모든 업데이트 처리 방식과 다르게 취급하고 싶을 것입니다.

workbox-window에서는 다음 이벤트 중 하나에서 isUpdate 속성을 확인하여 버전 최초 설치와 향후 업데이트를 구분할 수 있습니다. 처음 설치 시 isUpdatefalse입니다.

const wb = new Workbox('/sw.js');

wb.addEventListener('installed', event => {
  if (!event.isUpdate) {
    // First-installed code goes here...
  }
});

wb.register();
테마 이벤트 권장 조치
새 서비스 워커가 설치됨 (처음) installed

서비스 워커를 처음 설치할 때는 사이트가 오프라인으로 작동하는 데 필요한 모든 애셋을 사전 캐시하는 것이 일반적입니다. 이제 사이트가 오프라인에서 작동할 수 있다고 사용자에게 알리는 것이 좋습니다.

또한 서비스 워커를 처음 설치할 때는 페이지 로드에 대한 가져오기 이벤트를 가로채지 않으므로 이미 로드된 애셋을 캐싱하는 것을 고려할 수도 있습니다 (단, 애셋이 이미 사전 캐시되고 있는 경우에는 필요하지 않음). 위의 캐시할 URL 목록을 서비스 워커에 전송 예시에서는 이를 수행하는 방법을 보여줍니다.

서비스 워커가 페이지 제어를 시작했습니다. controlling

새 서비스 워커가 설치되고 페이지 제어를 시작하면 이후의 모든 가져오기 이벤트가 해당 서비스 워커를 거치게 됩니다. 서비스 워커가 특정 가져오기 이벤트를 처리하기 위해 특별한 로직을 추가하는 경우, 이 시점에 로직이 실행될 것을 알 수 있습니다.

서비스 워커를 처음 설치할 때는 서비스 워커가 활성화 이벤트에서 clients.claim()를 호출하지 않으면 현재 페이지를 제어하지 않습니다. 기본 동작은 다음 페이지 로드가 제어되기 시작할 때까지 기다리는 것입니다.

workbox-window 관점에서 이는 서비스 워커가 clients.claim()를 호출하는 경우에만 controlling 이벤트가 전달됨을 의미합니다. 등록 전에 페이지를 이미 제어한 경우 이 이벤트는 전달되지 않습니다.

서비스 워커가 활성화되었습니다. activated

위에서 언급했듯이 서비스 워커가 처음으로 활성화를 완료할 때 페이지 제어를 시작했을 수도 있고 그렇지 않을 수도 있습니다.

따라서 서비스 워커가 페이지를 제어하는 시기를 파악하기 위해 활성화 이벤트를 수신 대기해서는 안 됩니다. 그러나 서비스 워커의 활성 이벤트에서 로직을 실행 중이고 로직이 완료되는 시점을 알아야 하는 경우 활성화된 이벤트가 이를 알려줍니다.

서비스 워커의 업데이트된 버전이 발견된 경우

새 서비스 워커가 설치되기 시작하지만 현재 기존 버전이 페이지를 제어하고 있는 경우 다음 모든 이벤트의 isUpdate 속성이 true가 됩니다.

이러한 상황에서 대응하는 방법은 일반적으로 사용자가 이 업데이트를 받는 시기와 방법을 관리해야 하므로 처음 설치할 때와 다릅니다.

테마 이벤트 권장 조치
새 서비스 워커가 설치되었습니다 (이전 서비스 워커 업데이트). installed

첫 번째 서비스 워커 설치(event.isUpdate === true)가 아니라면 최신 버전의 서비스 워커 (즉, 현재 페이지를 제어하는 것과 다른 버전)가 발견되어 설치되었음을 의미합니다.

일반적으로 사이트의 새 버전이 서버에 배포되었으며 새 애셋이 사전 캐싱을 방금 완료했을 수 있습니다.

참고: 일부 개발자는 installed 이벤트를 사용하여 사용자에게 사이트의 새 버전을 사용할 수 있다고 알립니다. 그러나 설치 중인 서비스 워커에서 skipWaiting()를 호출하는지 여부에 따라 설치된 서비스 워커가 즉시 활성화될 수도 있고 활성화되지 않을 수도 있습니다. skipWaiting()호출하는 경우 새 서비스 워커가 활성화되었을 때 사용자에게 업데이트를 알리는 것이 가장 좋으며, skipWaiting를 호출하지 않는 경우 대기 이벤트에서 대기 중인 업데이트를 사용자에게 알리는 것이 좋습니다 (자세한 내용은 아래 참조).

서비스 워커가 설치되었지만 대기 단계에서 멈춤 waiting

업데이트된 버전의 서비스 워커가 설치되는 동안 skipWaiting()를 호출하지 않으면 현재 활성 서비스 워커에 의해 제어되는 모든 페이지가 로드 취소될 때까지 활성화되지 않습니다. 사용자에게 업데이트가 있으며 다음 방문 시 적용될 것이라고 알리는 것이 좋습니다.

경고! 개발자가 업데이트를 받기 위해 사용자에게 새로고침하라는 메시지를 표시하는 것이 일반적이지만 대부분의 경우 페이지를 새로고침해도 설치된 작업자가 활성화되지는 않습니다. 사용자가 페이지를 새로고침하고 서비스 워커가 아직 대기 중이면 waiting 이벤트가 다시 실행되고 event.wasWaitingBeforeRegister 속성이 true가 됩니다. 향후 버전에서 이 환경을 개선할 계획입니다. 업데이트는 문제 #1848을 참조하세요.

또 다른 옵션은 사용자에게 메시지를 표시하고 업데이트를 받을지 아니면 계속 기다릴지 묻는 것입니다. 업데이트를 받기로 선택한 경우 postMessage()를 사용하여 서비스 워커에 skipWaiting()을 실행하도록 지시할 수 있습니다. 이에 관한 예는 사용자에게 페이지 새로고침 기능 제공 고급 레시피를 참고하세요.

서비스 워커가 페이지 제어를 시작했습니다. controlling

업데이트된 서비스 워커가 페이지 제어를 시작하면 현재 제어 중인 서비스 워커의 버전이 페이지가 로드될 때 제어 중이던 버전과 다르다는 것을 의미합니다. 어떤 경우에는 문제가 되지 않을 수 있지만, 현재 페이지에서 참조하는 일부 애셋이 더 이상 캐시에 없고 서버에 없음을 의미할 수도 있습니다. 페이지의 일부가 제대로 작동하지 않을 수 있음을 사용자에게 알리는 것이 좋습니다.

참고: 서비스 워커에서 skipWaiting()를 호출하지 않으면 controlling 이벤트가 실행되지 않습니다.

서비스 워커가 활성화되었습니다. activated 업데이트된 서비스 워커 활성화가 완료되면 서비스 워커의 activate에서 실행 중이던 모든 로직이 완료되었음을 의미합니다. 로직이 완료될 때까지 지연해야 하는 항목이 있다면 지금 실행하세요.

예상치 못한 버전의 서비스 워커가 발견된 경우

사용자가 사이트를 백그라운드 탭에서 오랫동안 열어 두는 경우가 있습니다. 사용자는 사이트가 이미 백그라운드 탭에 열려 있다는 사실을 모르고 새 탭을 열고 사이트로 이동할 수도 있습니다. 이 경우 두 버전의 사이트를 동시에 실행할 수 있으며, 이로 인해 개발자에게 몇 가지 흥미로운 문제가 발생할 수 있습니다.

탭 A가 사이트의 v1을 실행 중이고 탭 B가 v2를 실행한다고 가정해 보겠습니다. 탭 B가 로드되면 v1과 함께 제공된 서비스 워커 버전에 의해 제어되지만 서버에서 반환하는 페이지 (탐색 요청에 네트워크 우선 캐싱 전략을 사용하는 경우)에는 모든 v2 애셋이 포함됩니다.

탭 B에서는 일반적으로 문제가 되지 않습니다. v2 코드를 작성할 때 v1 코드의 작동 방식을 알고 있었기 때문입니다. 하지만 탭 A에는 문제가 될 수 있습니다. v1 코드로는 v2 코드로 인해 발생할 수 있는 변경사항을 예측할 수 없었기 때문입니다.

이러한 상황을 처리하는 데 도움이 되도록 workbox-window는 '외부' 서비스 워커의 업데이트를 감지하면 수명 주기 이벤트를 전달합니다. 여기서 외부는 현재 Workbox 인스턴스가 등록한 버전이 아닌 모든 버전을 의미합니다.

Workbox v6 이상에서는 이러한 이벤트가 위에 설명된 이벤트와 같으며 각 이벤트 객체에 isExternal: true 속성이 추가됩니다. 웹 애플리케이션이 '외부' 서비스 워커를 처리하기 위해 특정 로직을 구현해야 하는 경우 이벤트 핸들러에서 해당 속성을 확인할 수 있습니다.

흔히 발생하는 실수 방지

Workbox에서 제공하는 가장 유용한 기능 중 하나는 개발자 로깅입니다. 이는 특히 workbox-window의 경우에 해당합니다.

서비스 워커를 사용한 개발은 종종 혼란스러울 수 있으며 예상과 상반되는 상황이 발생할 경우 그 이유를 알기 어려울 수 있습니다.

예를 들어 서비스 워커를 변경하고 페이지를 새로고침하면 브라우저에 변경사항이 표시되지 않을 수 있습니다. 이 문제가 발생하는 가장 큰 이유는 서비스 워커가 아직 활성화 대기 중일 때입니다.

그러나 Workbox 클래스에 서비스 워커를 등록하면 개발자 콘솔에서 모든 수명 주기 상태 변경사항을 확인할 수 있습니다. 이는 상황이 예상대로 진행되지 않는 이유를 디버깅하는 데 도움이 될 수 있습니다.

대기 중인 worker에 대한 workbox-window 콘솔 경고

또한 개발자가 서비스 워커를 처음 사용할 때 흔히 범하는 실수는 서비스 워커를 잘못된 범위에 등록하는 것입니다.

이를 방지하기 위해 서비스 워커를 등록하는 페이지가 서비스 워커의 범위에 있지 않은 경우 Workbox 클래스에서 경고를 표시합니다. 또한 서비스 워커가 활성 상태이지만 아직 페이지를 제어하지 않는 경우에도 경고가 표시됩니다.

비제어 작업자에 대한 workbox-window 콘솔 경고

서비스 워커 간 통신 기간

대부분의 고급 서비스 워커 사용에는 서비스 워커와 창 간에 많은 메시징이 필요합니다. Workbox 클래스는 인스턴스의 등록된 서비스 워커를 postMessage()하고 응답을 기다리는 messageSW() 메서드를 제공하여 이 작업에도 도움이 됩니다.

어떤 형식으로든 서비스 워커에 데이터를 전송할 수 있지만 모든 Workbox 패키지에서 공유하는 형식은 세 가지 속성이 있는 객체입니다 (마지막 두 가지는 선택사항임).

속성 필수 여부 유형 설명
type string

이 메시지를 식별하는 고유한 문자열입니다.

규칙에 따라 유형은 모두 대문자로 표시되며 단어를 구분하는 밑줄이 사용됩니다. 유형이 실행할 작업을 나타내면 현재형의 명령어여야 하며 (예: CACHE_URLS), 보고되는 정보를 나타내는 유형이라면 과거형 (예: URLS_CACHED)이어야 합니다.

meta 아니요 string Workbox에서는 항상 메시지를 전송하는 Workbox 패키지의 이름입니다. 직접 메시지를 보낼 때 이 속성을 생략하거나 원하는 값으로 설정할 수 있습니다.
payload 아니요 * 전송 중인 데이터입니다. 일반적으로 객체이지만 반드시 그럴 필요는 없습니다.

messageSW() 메서드를 통해 전송된 메시지는 MessageChannel를 사용하므로 수신자가 응답할 수 있습니다. 메시지에 응답하려면 메시지 이벤트 리스너에서 event.ports[0].postMessage(response)를 호출하면 됩니다. messageSW() 메서드는 응답한 response로 확인되는 프로미스를 반환합니다.

다음은 창에서 서비스 워커로 메시지를 보내고 응답을 받는 예입니다. 첫 번째 코드 블록은 서비스 워커의 메시지 리스너이고 두 번째 블록은 Workbox 클래스를 사용하여 메시지를 전송하고 응답을 기다립니다.

sw.js 코드:

const SW_VERSION = '1.0.0';

addEventListener('message', event => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

main.js의 코드 (창에서 실행):

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

버전 비호환성 관리

위의 예는 창에서 서비스 워커 버전 확인을 구현하는 방법을 보여줍니다. 이 예를 사용하는 이유는 창과 서비스 워커 간에 메시지를 주고받을 때 서비스 워커가 페이지 코드가 실행 중인 것과 동일한 버전의 사이트를 실행하고 있지 않을 수 있다는 점을 인식하는 것이 중요하며, 이 문제를 처리하는 솔루션은 페이지를 네트워크 우선으로 제공하는지 아니면 캐시 우선으로 제공하는지에 따라 다릅니다.

네트워크 우선

페이지 네트워크를 먼저 제공하면 사용자는 항상 서버에서 최신 버전의 HTML을 가져옵니다. 하지만 사용자가 업데이트를 배포한 후 사이트를 처음 다시 방문할 때는 HTML이 최신 버전이지만 사용자의 브라우저에서 실행 중인 서비스 워커는 이전에 설치된 버전(아마도 이전 버전일 수 있음)입니다.

페이지의 현재 버전에서 로드한 JavaScript가 이전 버전의 서비스 워커에 메시지를 보내는 경우, 해당 버전은 응답 방법을 모르거나 호환되지 않는 형식으로 응답할 수 있으므로 이러한 가능성을 이해하는 것이 중요합니다.

따라서 중요한 작업을 수행하기 전에 항상 서비스 워커의 버전을 지정하고 호환되는 버전이 있는지 확인하는 것이 좋습니다.

예를 들어 위 코드에서 messageSW() 호출로 반환된 서비스 워커 버전이 예상 버전보다 오래된 경우 업데이트가 발견될 때까지 기다리는 것이 좋습니다 (register() 호출 시 발생해야 함). 이때 사용자에게 알리거나 수동으로 대기 단계를 건너뛰어 새 서비스 워커를 즉시 활성화할 수 있습니다.

캐시 우선

페이지를 네트워크 우선으로 제공하는 경우와 달리 페이지 캐시를 먼저 제공하면 처음에는 페이지가 항상 서비스 워커와 동일한 버전이 된다는 것을 알 수 있습니다 (서비스 워커가 제공되기 때문). 따라서 messageSW()를 즉시 사용해도 안전합니다.

그러나 페이지에서 register()를 호출할 때 (즉, 의도적으로 대기 단계를 건너뜀) 업데이트된 버전의 서비스 워커가 발견되어 활성화되면 더 이상 서비스 워커에 메시지를 보내는 것이 안전하지 않을 수 있습니다.

이러한 가능성을 관리하기 위한 한 가지 전략은 브레이킹 체인지와 브레이킹 체인지가 아닌 업데이트를 구별할 수 있는 버전 관리 스키마를 사용하는 것입니다. 브레이킹 체인지의 경우 서비스 워커에 메시지를 보내는 것이 안전하지 않음을 알 수 있습니다. 대신 이전 버전의 페이지를 실행 중이라고 사용자에게 경고하고 새로고침하여 업데이트를 받도록 제안하는 것이 좋습니다.

대기 건너뛰기 도우미

Window to Service Worker 메시징을 위한 일반적인 사용 규칙은 대기 단계를 건너뛰고 활성화하도록 설치된 서비스 워커에 지시하는 {type: 'SKIP_WAITING'} 메시지를 보내는 것입니다.

Workbox v6부터는 messageSkipWaiting() 메서드를 사용하여 현재 서비스 워커 등록과 연결된 대기 중인 서비스 워커에 {type: 'SKIP_WAITING'} 메시지를 보낼 수 있습니다. 대기 중인 서비스 워커가 없으면 자동으로 아무 작업도 하지 않습니다.

유형

Workbox

서비스 워커 등록 및 업데이트를 처리하고 서비스 워커 수명 주기 이벤트에 대한 반응을 지원하는 클래스입니다.

속성

  • 생성자

    void

    스크립트 URL 및 서비스 워커 옵션을 사용하여 새 작업 상자 인스턴스를 만듭니다. 스크립트 URL과 옵션은 navigator.serviceWorker.register(scriptURL, options)를 호출할 때 사용된 것과 동일합니다.

    constructor 함수는 다음과 같습니다.

    (scriptURL: string|TrustedScriptURL,registerOptions?: object)=> {...}

    • scriptURL

      문자열|TrustedScriptURL

      이 인스턴스와 연결된 서비스 워커 스크립트입니다. TrustedScriptURL 사용이 지원됩니다.

    • registerOptions

      객체 선택사항

  • 게시 중

    Promise<ServiceWorker>

  • 제어

    Promise<ServiceWorker>

  • getSW

    void

    제공되는 즉시 이 인스턴스의 스크립트 URL과 일치하는 서비스 워커에 대한 참조로 확인합니다.

    등록 시 일치하는 스크립트 URL이 있는 활성 또는 대기 중인 서비스 워커가 이미 있는 경우 이 서비스 워커가 사용됩니다 (둘 다 일치하는 경우 대기 중인 서비스 워커가 더 최근에 등록되었을 것이므로 대기 중인 서비스 워커가 활성 서비스 워커보다 우선합니다). 등록 시 일치하는 활성 또는 대기 중인 서비스 워커가 없으면 업데이트를 찾아 설치를 시작할 때까지 프로미스가 확인되지 않습니다. 업데이트를 찾으면 설치 서비스 워커가 사용됩니다.

    getSW 함수는 다음과 같습니다.

    ()=> {...}

    • returns

      Promise<ServiceWorker>

  • messageSW

    void

    전달된 데이터 객체를 workbox-window.Workbox#getSW를 통해 이 인스턴스에서 등록한 서비스 워커로 전송하고 응답(있는 경우)으로 확인합니다.

    event.ports[0].postMessage(...)를 호출하여 서비스 워커의 메시지 핸들러에서 응답을 설정할 수 있으며, 이는 messageSW()에서 반환된 프로미스를 해결합니다. 응답이 설정되지 않으면 프로미스가 결정되지 않습니다.

    messageSW 함수는 다음과 같습니다.

    (data: object)=> {...}

    • 데이터

      객체

      서비스 워커에 전송할 객체

    • returns

      프로미스<any>

  • messageSkipWaiting

    void

    현재 등록과 연결된 waiting 상태에 있는 서비스 워커에 {type: 'SKIP_WAITING'} 메시지를 전송합니다.

    현재 등록이 없거나 waiting인 서비스 워커가 없는 경우 이 메서드를 호출해도 아무 효과가 없습니다.

    messageSkipWaiting 함수는 다음과 같습니다.

    ()=> {...}

  • register

    void

    이 인스턴스 스크립트 URL 및 서비스 워커 옵션에 대해 서비스 워커를 등록합니다. 기본적으로 이 메서드는 창이 로드된 후까지 등록을 지연합니다.

    register 함수는 다음과 같습니다.

    (options?: object)=> {...}

    • 옵션

      객체 선택사항

      • 즉시 필요

        부울 선택사항

    • returns

      Promise<ServiceWorkerRegistration>

  • update

    void

    등록된 서비스 워커의 업데이트를 확인합니다.

    update 함수는 다음과 같습니다.

    ()=> {...}

    • returns

      Promise<void>

WorkboxEventMap

WorkboxLifecycleEvent

속성

  • isExternal

    부울 선택사항

  • isUpdate

    부울 선택사항

  • originalEvent

    이벤트 선택사항

  • sw

    ServiceWorker 선택사항

  • 대상

    WorkboxEventTarget 선택사항

  • 유형

    typeOperator

WorkboxLifecycleEventMap

WorkboxLifecycleWaitingEvent

속성

  • isExternal

    부울 선택사항

  • isUpdate

    부울 선택사항

  • originalEvent

    이벤트 선택사항

  • sw

    ServiceWorker 선택사항

  • 대상

    WorkboxEventTarget 선택사항

  • 유형

    typeOperator

  • wasWaitingBeforeRegister

    부울 선택사항

WorkboxMessageEvent

속성

  • 데이터

    모두

  • isExternal

    부울 선택사항

  • originalEvent

    이벤트

  • ports

    typeOperator

  • sw

    ServiceWorker 선택사항

  • 대상

    WorkboxEventTarget 선택사항

  • 유형

방법

messageSW()

workbox-window.messageSW(
  sw: ServiceWorker,
  data: object,
)

postMessage를 통해 데이터 객체를 서비스 워커에 전송하고 응답 (있는 경우)으로 확인합니다.

event.ports[0].postMessage(...)를 호출하여 서비스 워커의 메시지 핸들러에서 응답을 설정할 수 있으며, 이는 messageSW()에서 반환된 프로미스를 해결합니다. 응답이 설정되지 않으면 프로미스가 확인되지 않습니다.

매개변수

  • sw

    ServiceWorker

    메시지를 보낼 서비스 워커입니다.

  • 데이터

    객체

    서비스 워커에 전송할 객체입니다.

반환 값

  • 프로미스<any>