Workbox v2에서 v3로 이전

이 가이드에서는 Workbox v3에 도입된 브레이킹 체인지에 중점을 두고 Workbox v2 설정에서 업그레이드할 때 변경해야 하는 내용의 예를 보여줍니다.

현재 기존 sw-precache/sw-toolbox 조합을 사용 중이며 처음으로 Workbox로 전환하려는 경우 다른 이전 가이드를 참고하세요.

v3 배경

Workbox의 v3 출시는 기존 코드베이스의 중요한 리팩터링을 나타냅니다. 주요 목표는 다음과 같습니다.

  • 워크박스의 크기를 최소화합니다. 다운로드 및 실행되는 서비스 워커 런타임 코드의 양을 줄였습니다. 모든 사용자를 모놀리식 번들에 선택하는 대신 사용 중인 특정 기능의 코드만 런타임에 가져옵니다.
  • Workbox에 CDN이 있습니다. Workbox 런타임 라이브러리에 액세스하기 위한 표준 옵션으로 Workbox를 더욱 쉽게 준비하고 실행할 수 있도록 완전하게 지원되는 Google Cloud Storage 기반 CDN 호스팅이 제공됩니다.
  • 디버깅 및 로그 개선. 디버깅 및 로깅 환경이 크게 개선되었습니다. 디버그 로그는 Workbox가 localhost 원본에서 사용될 때마다 기본적으로 사용 설정되고 모든 로깅 및 어설션이 프로덕션 빌드에서 제거됩니다. Workbox v3에서 제공하는 디버그 로깅의 예
  • Webpack 플러그인 개선. workbox-webpack-plugin는 webpack 빌드 프로세스와 더 긴밀하게 통합되어 빌드 파이프라인의 모든 애셋을 사전 캐시하려는 경우 구성 없이 사용할 수 있는 사용 사례가 가능합니다.

이러한 목표를 달성하고, 어색하거나 안티패턴으로 이어진 이전 인터페이스의 일부 측면을 정리하려면 v3 릴리스에 여러 가지 획기적인 변경사항을 도입해야 했습니다.

브레이킹 체인지

빌드 구성

다음 변경사항은 공통 구성 옵션 세트를 공유하는 모든 빌드 도구 (workbox-build, workbox-cli, workbox-webpack-plugin)의 동작에 영향을 미칩니다.

  • 이전에는 'fastest' 핸들러 이름이 유효했으며 runtimeCaching 구성 시 'staleWhileRevalidate'의 별칭으로 처리되었습니다. 더 이상 유효하지 않으며 개발자는 'staleWhileRevalidate'를 직접 사용하도록 전환해야 합니다.
  • 여러 runtimeCaching.options 속성 이름이 업데이트되었으며 잘못된 구성이 사용되면 빌드가 실패하게 되는 추가 매개변수 유효성 검사가 진행되었습니다. 현재 지원되는 옵션 목록은 runtimeCaching 문서를 참고하세요.

workbox-background-sync

  • 이제 maxRetentionTime 구성 매개변수가 밀리초가 아닌 분 단위로 해석됩니다.
  • 이제 대기열 이름을 나타내는 필수 문자열이 있으며, Plugin 또는 독립형 클래스를 구성할 때 첫 번째 매개변수로 전달해야 합니다. 이전에는 옵션의 속성으로 전달되었습니다. 업데이트된 API 노출 영역은 문서를 참고하세요.

workbox-broadcast-cache-update

  • 이제 채널 이름을 나타내는 필수 문자열이 있으며, Plugin 또는 독립형 클래스를 생성할 때 첫 번째 매개변수로 전달해야 합니다.

예를 들어 v2에서는 Plugin 클래스를 다음과 같이 초기화합니다.

new workbox.broadcastCacheUpdate.BroadcastCacheUpdatePlugin({
  channelName: 'cache-updates',
  headersToCheck: ['etag'],
});

이에 해당하는 v3의 사용법은 다음과 같습니다.

new workbox.broadcastUpdate.Plugin('cache-updates', {headersToCheck: ['etag']});

업데이트된 API 노출 영역은 문서를 참고하세요.

workbox-build

  • 기본적으로 glob 패턴 매칭이 이제 옵션 follow: true (심볼릭 링크를 따름) 및 strict: true('비정상적인' 오류를 덜 허용하지 않음)를 사용하여 수행됩니다. 빌드 구성에서 globFollow: false 또는 globStrict: false를 설정하여 둘 중 하나를 사용 중지하고 이전 동작으로 돌아갈 수 있습니다.
  • workbox-build의 함수는 모두 반환되는 응답에서 추가 속성인 warnings을 반환합니다. v2에서 치명적인 오류로 처리되었던 일부 시나리오가 이제 허용되지만 문자열 배열인 warnings를 통해 보고됩니다.

v2에서는 다음과 같이 generateSW를 호출할 수 있습니다.

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size}) => console.log(`Precached ${count} files, totaling ${size} bytes.`))
  .catch((error) => console.error(`Something went wrong: ${error}`));

v3에서 동일한 코드를 사용할 수 있지만 warnings가 있는지 확인하고 로깅하는 것이 좋습니다.

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size, warnings}) => {
    for (const warning of warnings) {
      console.warn(warning);
    }
    console.log(`Precached ${count} files, totalling ${size} bytes.`);
  })
  .catch((error) => console.error(`Something went wrong: ${error}`));
  • v2에서 자체 맞춤 ManifestTransform 함수를 작성한 개발자는 객체에 매니페스트 배열을 반환해야 합니다 (즉, return manifestArray; 대신 return {manifest: manifestArray};를 사용해야 함). 이렇게 하면 플러그인이 선택적 warnings 속성을 포함할 수 있습니다. 이 속성은 심각하지 않은 경고 정보를 포함하는 문자열 배열이어야 합니다.

v2에서 맞춤 ManifestTransform를 작성하는 경우 다음과 같이 코딩합니다.

const cdnTransform = manifestEntries => {
  return manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
};

다음과 같은 v3의 값을 가집니다.

const cdnTransform = manifestEntries => {
  const manifest = manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
  return {manifest, warnings: []};
};
  • getFileManifestEntries() 함수의 이름이 getManifest()로 변경되었으며 반환된 프로미스에는 사전 캐시된 URL에 관한 추가 정보가 포함됩니다.

코드는 v2에서 다음과 같습니다.

const manifestEntries = await workboxBuild.getFileManifestEntries({...});

는 v3에서 다음과 같이 다시 작성될 수 있습니다.

const {manifestEntries, count, size, warnings} = await workboxBuild.getManifest({...});

// Use manifestEntries like before.
// Optionally, log the new info returned in count, size, warnings.
  • generateFileManifest() 함수가 삭제되었습니다. 개발자는 대신 getManifest()를 호출하고 응답을 사용하여 데이터를 적절한 형식으로 디스크에 쓰는 것이 좋습니다.

workbox-cache-expiration

  • 플러그인 API는 동일하게 유지되었으며, 이는 대부분의 개발자가 사용하게 될 모드입니다. 그러나 독립형 클래스로 사용하는 개발자에게 영향을 주는 중요한 API 변경사항이 있습니다. 업데이트된 API 노출 영역은 문서를 참고하세요.

workbox-cli

개발자는 지원되는 전체 매개변수 집합에서 --help 플래그를 사용하여 CLI를 실행할 수 있습니다.

  • 바이너리 스크립트의 workbox-cli 별칭 지원이 삭제되었습니다. 이제 바이너리는 workbox로만 액세스할 수 있습니다.
  • v2 명령어 generate:swinject:manifest의 이름이 v3에서 generateSWinjectManifest로 변경되었습니다.
  • v2에서는 기본 구성 파일 (명시적으로 제공되지 않았을 때 사용됨)이 현재 디렉터리에서 workbox-cli-config.js인 것으로 가정했습니다. v3에서는 workbox-config.js입니다.

종합하면 v2에서는 다음과 같습니다.

$ workbox inject:manifest

'매니페스트 삽입'을 실행하고 빌드 프로세스, workbox-cli-config.js에서 읽은 구성 사용, v3에서는 다음과 같습니다.

$ workbox injectManifest

동일하게 실행되지만 workbox-config.js에서 구성을 읽습니다.

사전 캐싱 워크박스

  • 이전에 precache() 메서드는 캐시를 수정하고 캐시된 항목을 제공하도록 라우팅을 설정했습니다. 이제 precache()는 캐시 항목만 수정하며 이러한 캐시된 응답을 제공할 경로를 등록하기 위해 새 메서드 addRoute()가 노출되었습니다. 이전의 투인원 기능을 원하는 개발자는 precacheAndRoute() 호출로 전환할 수 있습니다.
  • WorkboxSW 생성자를 통해 구성되던 여러 옵션이 이제 workbox.precaching.precacheAndRoute([...], options)에서 options 매개변수로 전달됩니다. 이러한 옵션의 기본값은 구성되지 않은 경우 참조 문서에 나열되어 있습니다.
  • 기본적으로 파일 확장자가 없는 URL은 .html 확장자가 포함된 캐시 항목과 일치하는지 자동으로 확인됩니다. 예를 들어 /path/to/index (사전 캐시되지 않음)에 대한 요청이 발생하고 /path/to/index.html에 대해 사전 캐시된 항목이 있는 경우 해당 사전 캐시된 항목이 사용됩니다. 개발자는 옵션을 workbox.precaching.precacheAndRoute()에 전달할 때 {cleanUrls: false}를 설정하여 이 새로운 동작을 사용 중지할 수 있습니다.
  • workbox-broadcast-update이(가) 더 이상 사전 캐시된 애셋의 캐시 업데이트를 알리도록 자동으로 구성되지 않습니다.

v2의 다음 코드는 다음과 같습니다.

const workboxSW = new self.WorkboxSW({
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
  precacheChannelName: 'precache-updates',
});
workboxSW.precache([...]);

다음과 같은 v3의 값을 가집니다.

workbox.precaching.addPlugins([
    new workbox.broadcastUpdate.Plugin('precache-updates')
]);

workbox.precaching.precacheAndRoute([...], {
  cleanUrls: false,
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
});

워크박스-라우팅

  • 이전에 WorkboxSW 객체의 workbox.router.* 네임스페이스를 통해 workbox-routing를 사용한 개발자는 새 네임스페이스인 workbox.routing.*로 전환해야 합니다.
  • 이제 경로가 처음 등록한 낙찰 순서로 평가됩니다. 이는 v2에서 사용된 Route 평가의 반대 순서이며, 마지막으로 등록된 Route가 우선 적용됩니다.
  • ExpressRoute 클래스 및 '빠른 스타일' 지원 와일드 카드가 삭제되었습니다. 이렇게 하면 workbox-routing의 크기가 상당히 줄어듭니다. 이제 workbox.routing.registerRoute()의 첫 번째 매개변수로 사용되는 문자열이 정확히 일치하는 것으로 취급됩니다. 와일드 카드 또는 부분 일치는 RegExp에서 처리해야 합니다. 요청 URL의 일부 또는 전부와 일치하는 RegExp를 사용하면 경로를 트리거할 수 있습니다.
  • Router 클래스의 addFetchListener() 도우미 메서드가 삭제되었습니다. 개발자는 자체 fetch 핸들러를 명시적으로 추가하거나 workbox.routing에서 제공하는 인터페이스를 사용하여 암시적으로 fetch 핸들러를 만들 수 있습니다.
  • registerRoutes()unregisterRoutes() 메서드를 삭제했습니다. 단일 Route에서 작동하는 메서드의 버전은 변경되지 않았으며, 한 번에 여러 경로를 등록 또는 등록 취소해야 하는 개발자는 대신 일련의 registerRoute() 또는 unregisterRoute()를 호출해야 합니다.

v2의 다음 코드는 다음과 같습니다.

const workboxSW = new self.WorkboxSW();

workboxSW.router.registerRoute(
  '/path/with/.*/wildcard/',
  workboxSW.strategies.staleWhileRevalidate()
);

workboxSW.router.registerRoute(
  new RegExp('^https://example.com/'),
  workboxSW.strategies.networkFirst()
);

다음과 같은 v3의 값을 가집니다.

workbox.routing.registerRoute(
  new RegExp('^https://example.com/'),
  workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
  new RegExp('^/path/with/.*/wildcard'),
  workbox.strategies.staleWhileRevalidate()
);

workbox-strategies (이전 명칭: workbox-runtime-caching)

  • workbox-runtime-caching 모듈이 이제 공식적으로 workbox-strategies로 알려졌으며 새 이름으로 npm에 게시되었습니다.
  • 캐시 이름을 제공하지 않고 전략에서 캐시 만료 시간을 사용하는 것은 더 이상 유효하지 않습니다. v2에서는 다음과 같은 작업이 가능했습니다.
workboxSW.strategies.staleWhileRevalidate({
  cacheExpiration: {maxEntries: 50},
});

이로 인해 기본 캐시의 항목이 만료되며 이는 예상치 못한 결과입니다. v3에서는 캐시 이름이 는 필수 항목입니다.

workboxSW.strategies.staleWhileRevalidate({
  cacheName: 'my-cache',
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});
  • cacheWillMatch 수명 주기 메서드의 이름이 cachedResponseWillBeUsed로 변경되었습니다. 개발자가 cacheWillMatch에 반응하는 자체 플러그인을 작성하지 않는 한 개발자에게 눈에 띄는 변화는 없습니다.
  • 전략을 구성할 때 플러그인을 지정하는 문법이 변경되었습니다. 각 플러그인은 전략 구성의 plugins 속성에 명시적으로 나열되어야 합니다.

v2의 다음 코드는 다음과 같습니다.

const workboxSW = new self.WorkboxSW();

const networkFirstStrategy = workboxSW.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  cacheExpiration: {
    maxEntries: 50,
  },
  cacheableResponse: {
    statuses: [0, 200],
  },
});

다음과 같은 v3의 값을 가집니다.

const networkFirstStrategy = workbox.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  plugins: [
    new workbox.expiration.Plugin({maxEntries: 50}),
    new workbox.cacheableResponse.Plugin({statuses: [0, 200]}),
  ],
});

자세한 내용은 '플러그인 사용'을 참조하세요.

Workbox-SW

  • 내부적으로 workbox-sw가 경량 '로더'로 다시 작성되었습니다. 이 인터페이스는 기본 구성을 취하고 런타임에 필요한 다른 모듈을 가져오는 역할을 합니다. 개발자는 WorkboxSW 클래스의 새 인스턴스를 생성하는 대신 전역 네임스페이스에 자동으로 노출되는 기존 인스턴스와 상호작용합니다.

이전 v2의 경우:

importScripts('<path to workbox-sw>/importScripts/workbox-sw.prod.v2.1.3.js');

const workbox = new WorkboxSW({
  skipWaiting: true,
  clientsClaim: true,
  // etc.
});

workbox.router.registerRoute(...);

v3에서는 workbox-sw.js 스크립트를 가져오기만 하면 바로 사용할 수 있는 인스턴스가 전역 네임스페이스에서 자동으로 workbox로 제공됩니다.

importScripts('<path to workbox-sw>/3.0.0/workbox-sw.js');

// workbox is implicitly created and ready for use.
workbox.routing.registerRoute(...);
  • skipWaitingclientsClaim는 더 이상 WorkboxSW 생성자에 전달되는 옵션이 아닙니다. 대신 workbox.clientsClaim()workbox.skipWaiting() 메서드로 변경되었습니다.
  • v2 생성자에서 이전에 지원되었던 handleFetch 옵션이 v3에서 더 이상 지원되지 않습니다. 가져오기 핸들러를 호출하지 않고 서비스 워커를 테스트하는 데 유사한 기능이 필요한 개발자는 'Bypass for network'를 사용할 수 있습니다. Chrome 개발자 도구에서 사용할 수 있습니다.
Chrome DevTools의 네트워크 우회 옵션

workbox-webpack-plugin

플러그인은 대대적으로 재작성되었으며 대부분의 경우 '구성되지 않은' 상황에서 사용할 수 있습니다. 있습니다. 업데이트된 API 노출 영역은 문서를 참고하세요.

  • 이제 API는 GenerateSWInjectManifest라는 두 가지 클래스를 노출합니다. 이렇게 하면 swSrc의 존재 여부에 따라 동작이 변경된 v2 동작과 달리 모드 간의 전환이 명시적으로 이루어집니다.
  • 기본적으로 webpack 컴파일 파이프라인의 애셋은 사전 캐시되며, 더 이상 globPatterns를 구성할 필요가 없습니다. globPatterns를 계속 사용해야 하는 유일한 이유는 webpack 빌드에 포함되지 않은 애셋을 사전 캐시해야 하는 경우입니다. 일반적으로 v3 플러그인으로 이전할 때는 이전의 glob 기반 구성을 모두 삭제하는 것으로 시작하고 특별히 필요한 경우에만 다시 추가해야 합니다.

도움 받기

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