PWA - dltmdrbtjd/HANG GitHub Wiki
ํ๋ก๊ทธ๋ ์๋ธ ์น ์ดํ๋ฆฌ์ผ์ด์ ์ ์น์ ํตํด ์ ๋ฌ๋๋ ์์ฉ ์ํํธ์จ์ด์ ์ผ์ข ์ผ๋ก
HTML,CSS,JAVASCRIPT๋ฅผ ํฌํจํ ์ผ๋ฐ ์น ๊ธฐ์ ๋ค์ ์ฌ์ฉํ์ฌ ๋ง๋ค์ด์ง๋ค.
ํ์ค์ ์ค์ํ๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฌ์ฉํ๋ ์ด๋ ํ ํ๋ซํผ์์๋ผ๋ ๋์ํ๋๋ก ๊ณ ์๋์๋ค.
-
PWA์ ํน์ง์ App์ค๋ฌ์์ด๋ผ๊ณ ํ ์ ์๋ค. App์ฒ๋ผ ํ์คํฌ๋ฆฐ์ ์์ด์ฝ์ ์ค์นํ์ฌ App์ฒ๋ผ ์ฝ๊ฒ ๋ฐ๋ก๊ฐ๊ธฐ๋ฅผ ์คํํ ์ ์๋ค.
-
PWA๋ HTTPS์์๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ ์ธํฐ๋ท ๋ฐ์ดํฐ์ ๋นํด ๋ณด์์ด ๊ฐํ๋ ์ํ๋ผ๊ณ ํ ์ ์๋ค.
-
PWA๊ฐ ์บ์ฑ์ด ๋๊ธฐ ๋๋ฌธ์ Offline์ด๊ฑฐ๋ ์๋๊ฐ ๋๋ฆฐ ์ํ์์๋ ๋ฏธ๋ฆฌ ๋ค์ด๋ก๋ ๋์ด ์๋ ์ ๋ณด๋ฅผ ๊ณ์ ๋ณผ ์ ์๋ค.
manifest.json์ ์ค์นํ ๋ ์์ด์ฝ์ ๋ฌด์ผ ์ฌ์ฉํ๊ณ ์์ด์ฝ์ ๋๋ ์๋ ์ ์ํ ํ์ด์ง๋ ๋ฌด์์ธ์ง, ๋ฐฐ๊ฒฝ์์ ๋ฌด์จ์์ผ๋ก ํ ๊ฒ์ธ์ง ๋ฑ๋ฑ..์ ๋ํ ์ค์ ํ์ผ์ด๋ค.
- ๋งค๋ํ์คํธ(Manifest)์ ์ค์ ์ JSON์ผ๋ก ์ค์ ํ๋ค. ํ์ผ์ index.html์ head์์ ๋ฐฐ์นํ๋ค.
// index.html
<head>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
</head>
// manifest.json
{
"short_name": "HANG",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
- App icon: ์ค์น์ ์ฑ์ ์์ด์ฝ ์ด๋ฏธ์ง์ ํฌ๊ธฐ ์ค์
- ์คํ๋์(splash screen)ํ๋ฉด : ๋ก๋ฉํ๋ฉด ์ค์
- start url : ์น์ฑ์ด ์คํ๋ ๋ ๊ฐ์ฅ ์ฒ์ ๋ณด์ฌ์ง url์ค์
- display type: ์น์ฑ์ ํ๋ฉด ํํ(browser, standalone, fullscreen)
- display orientation : ์น์ฑ์ ํ๋ฉด ๋ฐฉํฅ (๊ฐ๋ก/์ธ๋ก)
- short_name ์ง์ : short_name์ ํ์ ์ ๋ ฅ์ฌํญ์ผ๋ก ์ด๊ฒ ์์ด์ผ ๋ฐฐ๋๋ฅผ ์ค์นํ ์ ์๋ค. ์ด๊ฑด ํ๋ก์ ํธ ์ด๋ฆ์ผ๋ก ์ค์น๋ ์์ด์ฝ์ ์ด๋ฆ์ผ๋ก ํ์ ๋๋ค.
- name ์ง์ : name๋ ํ์ ์ ๋ ฅ์ฌํญ์ผ๋ก name์ด ์์ด์ผ ๋ฐฐ๋๋ฅผ ์ค์นํ ์ ์๋ค. ์ด๊ฑด ์ค์น ๋ฐฐ๋์ ํ์๋๋ ์ด๋ฆ์ด๋ฉฐ ๊ฒ์ ํค์๋๋ก ์ฌ์ฉ๋๋ค.
- icons์ง์ : icons๋ ์ฑ์์ ํ์ํ ๋ค์ํ ํฌ๊ธฐ์ ์์ด์ฝ์ ์ง์ ํ๋ค. ๊ทธ์ค์์๋ 192px(128dp)๋ ๊ผญ ์์ด์ผ ํ๋ ํฌ๊ธฐ์ ์์ด์ฝ์ด๋ค. ์ด ์์ด์ฝ์ด ์์ด์ผ ์คํ๋์ ํ๋ฉด์ด ํ์๋๋ค.
- splash screen ์ค์ : ์คํ๋์ ์คํฌ๋ฆฐ์ 3๊ฐ์ง์ ์ค์ ์กฐํฉ์ผ๋ก ๊ตฌ์ฑ๋๋ค. ๋ฐฐ๊ฒฝ์ + ์์ด์ฝ + short_name(์์ด์ฝ์ด๋ฆ) ์ด ์ค์ ๋์ด์๋ค๋ฉด ์คํ๋์ฌ ํ๋ฉด์ด ๋์จ๋ค.
- start_url ์ค์ : start_url์ ํ์ ์์๋ก ์น์ฑ์ด ์คํ๋ ๋ ๊ฐ์ฅ ์ฒ์ ๋์ค๋ ํ๋ฉด์ ์ง์ ํ๋ค. ์ฆ ์คํ๋์ ํ๋ฉด ๋ค์์ ๋์ค๋ ํ๋ฉด์ด๋ค. ๊ธฐ๋ณธ ์ค์ ์ ์๋์ ๊ฐ์ด ์ด์ฉํ๊ณ ๊ทธ ์ธ์ Query String์ ์ฌ์ฉํ ์ ๋ ์๋ค.
"start_url": "./index.html",
"start_url": "./index.html?name=names1123",
- display ์ค์ : display์ ์ค์ ์ ์น์ฑ์ด ์ด๋ค ๋ชจ์์ผ๋ก ๋ณด์ฌ์ง์ง ์ค์ ํ๋ ๊ฐ์ด๋ค.
- browser(normal): ํด๋น ๋ธ๋ผ์ฐ์ ์์ ๊ธฐ๋ณธ ์น์ผ๋ก ์คํ
- standalone: ์๋จ์ url๋ฐ๋ฅผ ์ ๊ฑฐํ์ฌ ๋ค์ดํฐ๋ธ์ฑ์ฒ๋ผ ๋ณด์(๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ)
- fullscreen: ํ๋ฉด ์ ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ดํฐ๋ธ์ฒ๋ผ ๋ณด์
- iOS์์ standalone์ฌ์ฉ์ ํ๊ทธ ์์ ์๋์ ๋ฉํํํฌ๋ฅผ ์ถ๊ฐํด์ผํ๋ค.
<meta name="apple-mobile-web-app-capable" content="yes">
- theme_color ์ค์ : ํ ๋ง ์ปฌ๋ฌ๋ ๋ฐ๋ผ์ฐ์ ์๋จ์ url์ ๋ ฅ๋ฐ์ ์์คํ ๋ฐ๊น์ง ํฌํจํ ์์์ ์ง์ ํ ์ ์๋ค.
"theme_color": "#c4c4c4",
- orientation ์ค์ : orientation์ ๊ธฐ๊ธฐ์ ๋ฐฉํฅ์ ๊ฐ๋ก๋กํ ์ง ์ธ๋ก๋กํ ์ง ์ง์ ํ๋ ๊ฐ์ด๋ค. ๊ฒ์์ด ์๋๋ผ๋ฉด ๊ฑฐ์ ์ธ๋ก๋ชจ๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
// ์ธ๋ก๋ชจ๋ : portrait , ๊ฐ๋ก๋ชจ๋ : landscape
"orientation": "portrait",
service-worker๋ pwa์ ํต์ฌ์ผ๋ก ์บ์ฑ์ ์ด๋ป๊ฒ ํ ๊ฒ์ธ์ง ์์ฒญ์ ์บ์๋ฅผ ๋จผ์ ๋ณด์ฌ์ค์ง ์น์๋ฒ๋ฅผ ํตํด์ ๋จผ์ ๋ณด์ฌ์ค์ง, push๋ฑ๋ฑ์ ๋ํ ํ๋ก๊ทธ๋๋ฐํ๋ ๊ธฐ์ ์ด๋ค. pwa์ ๊ฑฐ์ 8ํ ์ ํด๋นํ๋ ๊ธฐ์ ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
service-worker ํ์ผ์
npx create-react-app my-app --template cra-template-pwa-typescript
์์ ๊ฐ์ด cra๋ฅผ ์คํํ๋ฉด root์ต์๋จ์ ์์ฑ๋๊ณ ํด๋นํ์ผ๋ค๋ก ์บ์ฑ๋ฐ ์คํ๋ผ์ธ์์ ๋ฑ๋ฑ์ ์คํํ ์ ์๋ค.
์ถ์ฒ : https://create-react-app.dev/docs/making-a-progressive-web-app/
๊ธฐ์กด์ JS๋ก ์์ ํ์๋์๋ ์บ์ฑํ ํ์ผ๋ค์ ์ ๋ฆฌํ๊ณ ์ฐ๊ฒฐํ๋๋ฑ์ ๊ณผ์ ์ด ๋ณต์กํ์๋๋ฐ TS๋ก ๋ฆฌํฉํ ๋ง์ ์งํํ๋ฉด์ ์ด๋ค์์ผ๋ก ์์ฑํ๋ฉด ์ข ๋ ํจ์จ์ ์ผ๋ก ์ด๊ฑธ ์ฌ์ฉํ ์ ์์๊น์ ๊ณ ๋ฏผํ๋ฉด์ ์ฐพ์๋ณด๋ค๊ฐ workbox๋ผ๋ ๊ฒ์ ๋ฐ๊ฒฌํ๋ค.
pwa์ ์บ์ฑ(caching)๊ธฐ๋ฅ์ ํธํ๊ฒ ๊ตฌํํ ์ ์๋๋ก ์ง์๋๋ ํ์ค PWA ๋ผ์ด๋ธ๋ฌ๋ฆฌ. [sw-precaching],[sw-toolbox]๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ง์ํ๋ ๊ธฐ๋ฅ๋ค์ ํตํฉํ์ฌ ์ ๊ณตํ๋ค.
npm install workbox-cli --global
์ ๋ช ๋ น์ด๋ก ์ค์น๋ฅผํ๊ณ
worbkox wizard
๋ฅผ ํตํ์ฌ ์ค์น๋ฅผ ์งํํ๋ฉด
- ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฃจํธ๊ฐ ์ด๋์ธ์ง? app/
- ์ด๋ค ํ์ผ ์ ํ๋ค์ ํ๋ฆฌ์บ์ฑ(pre-caching)ํ ๊ฒ์ธ์ง? html, css, js, jpg, png
- ์ ์ต์ ๋ค์ด ์ ์ฉ๋ ์๋น์ค ์์ปค ํ์ผ์ด ์์ฑ๋ ์์น? dist/sw.js
- ์ ๊ตฌ์ฑ ์ ๋ณด๋ค์ ์ด๋์ ์ ์ฅํ ๊ฒ์ธ๊ฐ? workbox-config.js ์์ ๊ฐ์ ์ง๋ฌธ๋ค์ ๋ํด ๋ต์ํ๋ฉด workbox-config.js ํ์ผ์ด ์์ฑ๋๋ค.
workbox generateSW ./workbox-config.js
์ด๋ ๊ฒ ์์ฑ๋ ์๋น์ค ์์ปค ํ์ผ์๋ ์ํฌ๋ฐ์ค์ ํ๋ฆฌ์บ์ฑ๊ณผ ๋ฐํ์ ์บ์ฑ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์๋ค. ( ๋ค๋ง ์นํธ์ฌ ๊ธฐ๋ฅ์ด ํ์ํ๊ฒฝ์ฐ์๋ injectManifest ์ต์ ์ ํ์ฉํด์ผํ๋ค.
์ํฌ๋ฐ์ค CLI์ injectManifest ๋ชจ๋
์ํฌ๋ฐ์ค injectManifest ๋ชจ๋๋ generateSW ๋ชจ๋์๋ ๋ค๋ฅด๊ฒ ๊ฐ๋ฐ์๊ฐ ์ข ๋ ์๋น์ค์์ปค ํ์ผ์ ์ง์ ์กฐ์ํ๊ฑฐ๋ ๋ด์ฉ์ ์์ ํ ์ ์์ต๋๋ค. ํ์ผ ์บ์ฑ ์ด์ธ์ ์น ํธ์ API์ ๊ฐ์ ๋ค์ดํฐ๋ธ API ๊ธฐ๋ฅ์ ๊ตฌํํ๊ณ ์ถ์ ๋ ์ ํฉํ ๋ชจ๋์ ๋๋ค.
๊ฐ๋ฐ์๊ฐ ๊ตฌํํด๋์ ์๋น์ค ์์ปค ํ์ผ์ ์ฝ์ด ์ค์ ํ์ผ(workbox-config.js)์ ์ค์ ๋ ์บ์ฑ ์ ๋ณด๋ฅผ ์ถ๊ฐํ๊ณ ์ ์๋น์ค ์์ปค ํ์ผ์ ์์ฑํด์ค๋๋ค. ๋ช ๋ น์ด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
workbox injectManifest ./workbox-config.js