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);

이 논의에서 설명한 바와 같이, Google은 이러한 변경을 통해 더 단순한 환경을 제공하는 동시에 커스텀 서비스 워커 코드 내에서 삽입된 매니페스트가 사용되는 방식을 개발자가 더 세밀하게 제어할 수 있다고 생각합니다. 필요한 경우 injectionPoint 구성 옵션을 통해 이 대체 문자열을 변경할 수 있습니다.

이전에 경로 탐색에 지원되었던 두 가지 옵션인 blacklistwhitelist의 이름이 denylistallowlist로 변경되었습니다.

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

  1. 지정된 fetch 이벤트에 mode 'navigate'가 있는지 감지했습니다.
  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()를 호출할 필요가 없습니다.

workbox-strategies에서 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를 사용하고 Broadcast Channel이 지원되지 않는 경우에만 postMessage()를 사용하도록 대체되었습니다.

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

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

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

// 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를 사용하는 대신 사용할 수 있습니다.

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

'매니페스트 삽입'에서 빌드 도구를 사용하는 경우 Workbox의 빌드 도구를 전혀 사용하지 않는 경우 기존 Workbox와 함께 Bundler (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를 채택하지 않은 개발자를 위해 트랜스파일된 JavaScript 모듈과 번들을 계속 게시할 예정이지만, TypeScript를 사용 중이라면 Workbox 프로젝트에서 직접 정확하고 항상 최신 상태의 유형 정보를 제공받을 수 있습니다.

이전 예

이 커밋 인라인 해설과 함께 상당히 관련된 마이그레이션의 예를 보여줍니다. Rollup을 사용하여 CDN에서 런타임을 로드하는 대신 최종 서비스 워커에서 커스텀 Workbox 런타임을 실행합니다.

모든 브레이킹 체인지를 다루지는 않지만 TypeScript로의 전환을 포함하여 서비스 워커 파일 하나를 v4에서 v5로 업그레이드하기 는 다음과 같습니다.

도움말 보기

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