개요
CRA(Create React App)를 통하여 생성된 프로젝트는 서비스 워커(serviceWorker) 기능을 제공합니다.
CRA에서 기본적으로 제공되는 service-worker.js
파일은 아래와 같습니다.
CRA에서 서비스워커를 재구성하는 방법은 여러 가지 방법이 있겠지만 workbox
를 사용하여 서비스워커를 재구성하는 방법을 설명하고자 합니다.
환경 구성
프로젝트 생성
CRA를 사용하여 프로젝트를 생성합니다.
npx create-react-app rca-workbox-customize-deploy
모듈 설치
workbox-build
, npm-run-all
모듈을 설치합니다.
npm install --save-dev workbox-build npm-run-all
workbox-build 모듈
서비스 워커에서 사용할 service-worker.js
파일을 재정의할 때 사용하기 위하여 해당 모듈을 설치합니다.
npm-run-all 모듈
package.json의 스크립트를 작성하기 위하여 해당 모듈을 설치합니다.
파일 생성
CRA로 생성한 프로젝트에서 src폴더 안에
sw-build.js
, sw-custom.js
파일을 생성
precaching 될
리소스 파일 경로 및 리스트의 수정이 필요한 것을 직접 작성하였기 때문에 workbox-build
의 injectMenifest
를 사용하였습니다. 좀 더 자세한 내용을 확인하시고 싶으신 분은 module-workbox-webpack-plugin.InjectManifest에서 확인 부탁드립니다.
index.js
에서 serviceWorker
를 사용 및 업데이트 시 postMessage
를 전달하도록 코드를 작성합니다.
// serviceWorker.unregitser();
serviceWorker.register({
onUpdate: registration => {
if (registration.waiting) {
registration.waiting.postMessage({ type: 'SKIP_WAITING' });
} else {
window.location.reload();
}
},
});
생성된 sw-build.js
에 다음과 같이 코드를 작성합니다.
const workboxBuild = require('workbox-build');
const buildSW = () => {
return workboxBuild
.injectManifest({
globDirectory: 'build',
globPatterns: ["**/*.{js,css,html,png,jpg,svg}"],
swDest: 'build/sw.js', // 빌드가 완료된 후 생성되는 파일 위치
swSrc: 'src/sw-custom.js' // 커스텀할 service-worker.js 파일
})
.then(({ count, size, warnings }) => {
// Optionally, log any warnings and details.
// warnings.forEach(console.warn);
});
};
buildSW();
sw-custom.js
의 파일에는 workbox
의 전략
및 라우팅
을 원하시는 방향으로 작성하시면 됩니다.
/* eslint-disable no-undef */
/* eslint-disable no-restricted-globals */
if ("function" === typeof importScripts) {
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js');
// Global workbox
if (workbox) {
console.log("Workbox is loaded");
// Disable logging
workbox.setConfig({ debug: false });
self.addEventListener('message', event => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
})
// Manual injection point for manifest files.
// All assets under build/ and 5MB sizes are precached.
workbox.precaching.precacheAndRoute([]);
// js caching
workbox.routing.registerRoute(
/\.js$/,
new workbox.strategies.NetworkFirst({
cacheName: 'js',
})
);
// css cacing
workbox.routing.registerRoute(
/\.css$/,
new workbox.strategies.NetworkFirst({
cacheName: 'css',
})
);
// font caching
workbox.routing.registerRoute(
new RegExp("https://fonts.(?:.googlepis|gstatic).com/(.*)"),
new workbox.strategies.NetworkFirst({
cacheName: 'fonts',
})
);
// image caching
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
new workbox.strategies.NetworkFirst({
cacheName: 'images',
})
);
} else {
console.error("Workbox could not be loaded. No offline support");
}
}
스크립트 구성
package.json의 스크립트를 정리하기 위하여 npm-run-all
모듈을 설치 후 아래와 같이 스크립트 코드를 변경합니다.
...
"build": "npm-run-all build-js clean-cra-sw build-sw ",
"build-js": "react-scripts build",
"clean-cra-sw": "rm -f build/precache-manifest.*.js && rm -f build/service-worker.js",
"build-sw": "node ./src/sw-build.js"
...
npm run build
이후 생성된 build
폴더 내에 파일을 서빙하여 실행 시 아래와 같이 사용되는 리소스 파일이 캐시 되는 것을 확인할 수 있습니다.
결론
CRA를 사용하여 생성된 프로젝트를 eject 하여
직접 service-worker.js
파일을 변경할 수 있으나, eject
를 사용하여 변경하기에는 CRA에서 제공하는 이점을 사용할 수 없기 때문에, 위와 같은 과정을 통해 재구성하였습니다.
해당 과정이 적용된 프로젝트는 여기에서 확인 가능합니다.
'Develope > React' 카테고리의 다른 글
Recoil - Cannot update a component (`Batcher`) while rendering a different component 에러에 대하여 (2) | 2020.07.02 |
---|---|
[React]반복문으로 컴포넌트 렌더링시 고유값을 부여하는 이유 (0) | 2020.06.23 |