Workbox v4에서 v5로 이전

이 가이드에서는 Workbox v5에 도입된 브레이킹 체인지와 Workbox v4에서 업그레이드할 때 필요한 변경사항의 예를 중점적으로 설명합니다.

이전 버전과 호환되지 않는 변경사항

플러그인 클래스 이름 변경됨

여러 Workbox v4 패키지에는 Plugin라는 클래스가 포함되어 있습니다. v5에서 이러한 클래스는 패턴 패키지 식별자 + Plugin에 따라 이름이 변경되었습니다.

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

이러한 이름 바꾸기는 모듈 가져오기를 통해 클래스를 사용하든 workbox.* 네임스페이스를 통해 사용하든 관계없이 적용됩니다.

기본 사전 캐시 매니페스트 대체 지점

이전에는 '매니페스트 삽입' 모드에서 빌드 도구 중 하나를 사용할 때 소스 서비스 워커 파일에 precacheAndRoute([])가 있는지 확인했으며 빈 배열 []는 사전 캐시 매니페스트가 삽입된 지점의 자리표시자로 사용되었습니다.

Workbox v5에서 교체 로직이 변경되었으며 이제 self.__WB_MANIFEST가 기본적으로 삽입 지점으로 사용됩니다.

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

이 논의에 설명된 대로 이 변경으로 인해 환경이 단순해지면서 동시에 개발자가 커스텀 서비스 워커 코드 내에서 삽입된 매니페스트가 사용되는 방식을 더 잘 제어할 수 있게 되었습니다. 필요한 경우 injectionPoint 구성 옵션을 통해 이 대체 문자열을 변경할 수 있습니다.

이전에 탐색 경로에 지원되었던 두 옵션 blacklistwhitelistdenylistallowlist로 변경되었습니다.

이전에 workbox-routing는 내부적으로 두 가지 작업을 실행하는 registerNavigationRoute() 메서드를 지원했습니다.

  1. 지정된 fetch 이벤트에 'navigate'mode가 있는지 여부를 감지합니다.
  2. 이 경우 이동하는 URL에 관계없이 이전에 캐시되고 하드코딩된 URL의 콘텐츠를 사용하여 요청에 응답했습니다.

이는 앱 셸 아키텍처를 구현할 때 사용되는 일반적인 패턴입니다.

캐시에서 읽어서 응답을 생성하는 두 번째 단계는 workbox-routing의 역할에서 벗어납니다. 대신 새 메서드 createHandlerBoundToURL()를 통해 workbox-precaching에 포함되어야 하는 기능으로 간주합니다. 이 새로운 메서드는 workbox-routing의 기존 NavigationRoute 클래스와 함께 작동하여 동일한 로직을 실행할 수 있습니다.

빌드 도구의 'SW 생성' 모드 중 하나에서 navigateFallback 옵션을 사용하고 있다면 전환이 자동으로 이루어집니다. 이전에 navigateFallbackBlacklist 또는 navigateFallbackWhitelist 옵션을 구성한 경우 각각 navigateFallbackDenylist 또는 navigateFallbackAllowlist로 변경합니다.

'매니페스트 삽입' 모드를 사용하거나 서비스 워커를 직접 작성하고 Workbox v4 서비스 워커가 registerNavigationRoute()를 직접 호출하는 경우 코드를 변경하여 동일한 동작을 해야 합니다.

// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';

const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
  whitelist: [...],
  blacklist: [...],
});

// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';

const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
  allowlist: [...],
  denylist: [...],
});
registerRoute(navigationRoute);

createHandlerBoundToURL()에서 알아서 처리하므로 더 이상 getCacheKeyForURL()를 호출할 필요가 없습니다.

작업 상자 전략에서 makeRequest()를 삭제했습니다.

makeRequest()를 호출하는 것은 workbox-strategy 클래스 중 하나에서 handle()를 호출하는 것과 대체로 동일합니다. 두 가지 방법의 차이가 너무 미미해서 둘 다 포함하는 것은 말이 되지 않았습니다. makeRequest()를 호출한 개발자는 추가 변경 없이 handle()를 사용하도록 전환할 수 있습니다.

// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});

// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});

v5에서 handle()request를 필수 매개변수로 취급하며 event.request을 사용하도록 대체되지 않습니다. handle()를 호출할 때 유효한 요청을 전달해야 합니다.

workbox-broadcast-update는 항상 postMessage() 사용

v4에서 workbox-broadcast-update 라이브러리는 지원되는 경우 메시지를 보내는 데 Broadcast Channel API를 기본적으로 사용하고 방송 채널이 지원되지 않는 경우에만 postMessage()를 사용하도록 대체됩니다.

우리는 수신되는 메시지의 두 가지 잠재적인 소스를 수신 대기해야 하는 경우 클라이언트 측 코드 작성이 지나치게 복잡하다는 것을 깨달았습니다. 또한 일부 브라우저에서는 message 이벤트 리스너가 설정될 때까지 클라이언트 페이지로 전송되는 서비스 워커의 postMessage() 호출이 자동으로 버퍼링됩니다. Broadcast Channel API를 사용하는 경우 버퍼링이 없으며, 클라이언트 페이지에서 메시지를 수신할 준비가 되기 전에 전송된 경우 브로드캐스트된 메시지가 삭제됩니다.

이러한 이유로 v5에서 항상 postMessage()를 사용하도록 workbox-broadcast-update를 변경했습니다. 메시지가 현재 서비스 워커의 범위 내에 있는 모든 클라이언트 페이지로 하나씩 전송됩니다.

이 새로운 동작을 수용하려면 BroadcastChannel 인스턴스를 만든 클라이언트 페이지에 있던 코드를 삭제하고 대신 navigator.serviceWorker에서 message 이벤트 리스너를 설정합니다.

// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
  const {cacheName, updatedUrl} = event.data.payload;
  // ... your code here ...
});

// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
  // Optional: ensure the message came from workbox-broadcast-update
  if (event.meta === 'workbox-broadcast-update') {
    const {cacheName, updatedUrl} = event.data.payload;
    // ... your code here ...
  }
});

workbox-window의 내부 로직이 postMessage() 호출을 수신 대기하도록 업데이트되었으므로 사용자가 변경할 필요가 없습니다.

빌드 도구에 Node.js v8 이상 필요

v8 이전의 Node.js 버전은 workbox-webpack-plugin, workbox-build 또는 workbox-cli에서 더 이상 지원되지 않습니다. Node.js 버전 8 미만을 실행하는 경우 런타임을 지원되는 버전으로 업데이트합니다.

workbox-webpack-plugin에는 webpack v4 이상이 필요합니다.

workbox-webpack-plugin를 사용 중인 경우 webpack v4 이상을 사용하도록 webpack 설정을 업데이트합니다.

빌드 도구 옵션 점검

여러 workbox-build, workbox-cli, workbox-webpack-plugin 구성 매개변수가 더 이상 지원되지 않습니다. 예를 들어 generateSW는 항상 로컬 Workbox 런타임 번들을 생성하므로 importWorkboxFrom 옵션은 더 이상 적절하지 않습니다.

지원되는 옵션 목록은 관련 도구의 문서를 참고하세요.

Workbox-build에서 generateSWString 삭제

generateSWString 모드가 workbox-build에서 삭제되었습니다. 주로 workbox-webpack-plugin에서 내부적으로 사용했으므로 영향은 크지 않을 것으로 예상됩니다.

선택적 변경사항

모듈 가져오기 사용

이 변경사항은 a) 선택사항이며 b) Workbox v4를 사용할 때 기술적으로 가능했지만, v5로 이전하는 동안 가장 큰 변화는 Workbox 모듈을 가져와 번들 서비스 워커를 직접 만드는 모델입니다. 이 접근 방식은 서비스 워커 상단에서 importScripts('/path/to/workbox-sw.js')를 호출하고 workbox.* 네임스페이스를 통해 Workbox를 사용하는 대신 사용할 수 있습니다.

빌드 도구 중 하나 (workbox-webpack-plugin, workbox-build, workbox-cli)를 'Generate SW' 모드에서 사용하면 이 변경사항이 자동으로 적용됩니다. 이러한 모든 도구는 서비스 워커 로직을 구현하는 데 필요한 실제 코드와 함께 Workbox 런타임의 로컬 커스텀 번들을 출력합니다. 이 시나리오에서는 workbox-sw 또는 Workbox의 CDN 사본에 더 이상 종속 항목이 없습니다. inlineWorkboxRuntime 구성 값에 따라 Workbox 런타임은 서비스 워커와 함께 배포되어야 하는 별도의 파일로 분할되거나 (기본값 false로 설정된 경우) 서비스 워커 로직과 함께 인라인으로 포함됩니다 (true로 설정된 경우).

'매니페스트 삽입' 모드에서 빌드 도구를 사용하고 있거나 Workbox의 빌드 도구를 전혀 사용하지 않는 경우 기존 Workbox에 번들러 (webpack/Rollup) 사용 가이드에서 자체 Workbox 런타임 번들 만들기에 대해 자세히 알아볼 수 있습니다.

v5에 관한 문서와 예는 모듈이 구문을 가져오는 것으로 작성되었으며, workbox.* 네임스페이스는 Workbox v5에서 계속 지원됩니다.

사전 캐시된 응답 읽기

일부 개발자는 사전 캐시된 응답을 precacheAndRoute() 메서드를 통해 암시적으로 사용하는 대신 캐시에서 직접 읽어야 합니다. v4의 일반적인 패턴은 먼저 사전 캐시된 리소스의 현재 버전과 관련된 캐시 키를 가져온 후 이 키를 사전 캐시의 캐시 이름과 함께 caches.match()에 전달하여 Response를 가져오는 것입니다.

이 프로세스를 단순화하기 위해 v5의 workbox-precaching는 새로운 동일한 메서드인 matchPrecache()를 지원합니다.

// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';

const cachedResponse = await caches.match(
  getCacheKeyForURL(`/somethingPrecached`),
  {
    cacheName: cacheNames.precache,
  }
);

// v5:
import {matchPrecache} from 'workbox-precaching';

const cachedResponse = await matchPrecache(`/somethingPrecached`);

TypeScript 채택

v5에서 Workbox 런타임 라이브러리는 TypeScript로 작성됩니다. TypeScript를 채택하지 않은 개발자를 위해 변환된 자바스크립트 모듈과 번들을 계속 게시할 예정이지만, TypeScript를 사용하는 경우 Workbox 프로젝트에서 직접 항상 최신 상태의 정확한 유형 정보를 얻을 수 있습니다.

이전 예시

이 커밋은 인라인 해설과 함께 상당히 복잡한 이전임을 보여줍니다. Rollup을 사용하여 CDN에서 런타임을 로드하는 대신 최종 서비스 워커에 커스텀 Workbox 런타임을 포함합니다.

모든 브레이킹 체인지를 다루는 것은 아니지만 TypeScript로의 전환을 비롯하여 서비스 워커 파일 하나를 v4에서 v5로 업그레이드하기 를 알려드립니다.

도움말 보기

대부분의 이전은 간단할 것으로 예상됩니다. 이 가이드에서 다루지 않은 문제가 발생하면 GitHub에서 문제를 제기하여 알려주세요.