아예 처음부터 pwa가 포함된 템플릿으로 다운받으면 되는데 어쩌다보니 따로따로 하게 됐다...
1.
yarn create vite '프로젝트 명' --template react-ts
yarn add vite-plugin-pwa -D
vite.config.ts에 해당 코드 작성import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { VitePWA } from "vite-plugin-pwa";
// https://vite.dev/config/
export default defineConfig({
plugins: [
react(),
VitePWA({
registerType: "autoUpdate",
injectRegister: "inline",
}),
],
});
sw.js 커스텀 서비스 워커 만들고 /public에 매니페스트 만들기.self.addEventListener("install", (e) => {
console.log("[Service Worker] installed");
});
// activate event
self.addEventListener("activate", (e) => {
console.log("[Service Worker] actived", e);
});
// fetch event
self.addEventListener("fetch", (e) => {
console.log("[Service Worker] fetched resource " + e.request.url);
});
// public/manifest.json
{
"name": "ob-hle",
"short_name": "ob-hle",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#485EEE",
"lang": "en",
"scope": "/",
"icons": [
{
"src": "icons/icon-48x48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
서비스워커 설정으로 injectRegister: "inline"를 해줬기 때문에 인라인으로 서비스워커를 등록해준다.
서비스워커 등록 참고
추가로 매니페스트도 html에 link 연결해준다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="manifest" href="manifest.json" />
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("/sw.js", { scope: "/" })
.then((registration) => {
console.log("서비스 워커 등록 성공:", registration);
})
.catch((error) => {
console.log("서비스 워커 등록 실패:", error);
});
});
}
</script>
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>


일단 잘 뜬다.