โ๏ธ PWA๋
- ๊ตฌ๊ธ์์ ๋ฐ๊ณ ์๋ Progressive Web App์ด๋ผ๋๊ฑด๋ฐ ์ด๊ฑด ์น์ฌ์ดํธ๋ฅผ ์๋๋ก์ด๋/iOS ๋ชจ๋ฐ์ผ ์ฑ์ฒ๋ผ ์ฌ์ฉํ ์ ์๊ฒ ๋ง๋๋ ์ผ์ข
์ ์น๊ฐ๋ฐ ๊ธฐ์ ์ด๋ค.
- ๊ทผ๋ฐ iOS, Android ์ฑ์ผ๋ก ๋ฐํํ๋๊ฒ ์๋๋ผ ์น์ฌ์ดํธ ์์ฒด๋ฅผ ์ค๋งํธํฐ ํํ๋ฉด์ ์ค์นํ๋ค.
โ๏ธ ์น์ฌ์ดํธ๋ฅผ PWAํ ์ํค๋๊ฒ ๋ญ๊ฐ ์ข๋๋ฉด
1. ์ค๋งํธํฐ, ํ๋ธ๋ฆฟ ๋ฐํํ๋ฉด์ ์น์ฌ์ดํธ ์ค์น ๊ฐ๋ฅ.
2. ์คํ๋ผ์ธ์์๋ ๋์ ๊ฐ๋ฅ.
- service-worker.js ๋ผ๋ ํ์ผ๊ณผ ๋ธ๋ผ์ฐ์ ์ Cache storage ๋๋ถ
3. ์ค์น ์ ๋ ๋น์ฉ์ด ๋งค์ฐ ์ ์.
- ์น์ฌ์ดํธ ๋ฐฉ๋ฌธ์๋ค์๊ฒ ๊ฐ๋จํ ํ์
์ ๋์์ ์ค์น์ ๋ํ ์ ์์ผ๋ ํจ์ฌ ์ ์ ๋ง์ผํ
๋น์ฉ
โ๏ธ PWA ๋ฐํํ๋ ๋ฒ
- ๊ทธ๋ฅ ์๋ฌด ์ฌ์ดํธ๋ ํ์ผ 2๊ฐ๋ง ์ฌ์ดํธ ๋ก์ปฌ ๊ฒฝ๋ก์ ์์ผ๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ PWA๋ก ์ธ์ํจ(๊ทธ๋ฆฌ๊ณ HTTPS ์ฌ์ดํธ์ฌ์ผํจ!)
- manifest.json๊ณผ service-worker.js๋ผ๋ ์ด๋ฆ์ ํ์ผ ๋๊ฐ๋ฅผ ๋ง๋ค๋ฉด ๋๋ค.
- ํ์ง๋ง ๊ธฐ๋ณธ ํ๋ก์ ํธ๋ฅผ npm build/yarn build ํ์ ๊ฒฝ์ฐ manifest.json ํ์ผ๋ง ์์ฑํด์ค๋ค.
- service-worker.js๊น์ง ์๋์ผ๋ก ์์ฑ์ ์ํ๋ค๋ฉด ํ๋ก์ ํธ๋ฅผ ์ฒ์ ๋ง๋ค ๋ ์๋์ ๊ฐ์ด ํฐ๋ฏธ๋์ ์
๋ ฅํ๋ค.
npx create-react-app ํ๋ก์ ํธ๋ช
--template cra-template-pwa
- ์ฆ, ํ๋ก์ ํธ๋ฅผ ๋ค์ ๋ง๋๋ ๊ฒ!
1. ๋ค๋ฅธ ํดํฐ์ ์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํด ํ๋ก์ ํธ ์๋ก ํ๋ ๋ง๋ ๋ค์์
2. ๊ธฐ์กด ํ๋ก์ ํธ์ App.js App.css index.js ์ด๋ฐ ํ์ผ๋ค์ ์ ํ๋ก์ ํธ๋ก ๋ณต๋ถํ๋ฉด ๋๋ค.(๋ด๊ฐ ๊ฑด๋ ํ์ผ์ ์ ๋ถ!)
3. router, redux ์ด๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์นํ๋ค๋ฉด ๊ทธ๊ฒ๋ ์ํ๋ก์ ํธ์ ๋ค์ ์ค์น
- ๊ทธ๋ฆฌ๊ณ ํ์ผ๋ค ์ค์ index.js ํ๋จ์ ์์ ํ๋ค.
// serviceWorkerRegistration.unregister();
// ↓
serviceWorkerRegistration.register();
- ๊ทธ๋ผ ์ด์ yarn build/npm run build ํ์ ๋ manifest.json๊ณผ service-worker.js ํ์ผ์ด ์๋์ผ๋ก ์์ฑ๋๋ค.
โ๏ธ manifest.json / service-worker.js ํ์ผ ์ดํด๋ณด๊ธฐ
- build ํ๊ณ ๋์๋ฉด build ํด๋ ๋ด์ ์ด ํ์ผ๋ค์ด ์์ ๊ฑฐ๋ค.
- manifest.json ํ์ผ์ ์น์ฑ์ ์์ด์ฝ, ์ด๋ฆ, ํ
๋ง์ ์ด๋ฐ๊ฑธ ๊ฒฐ์ ํ๋ ๋ถ๋ถ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
- ๊ทธ ์์ ๋ค์ด๊ฐ๋ ๋ด์ฉ๋ค์ ๋๋ต ์๋์ ๊ฐ๋ค
{
"version" : "์ฌ๋ฌ๋ถ์ฑ์ ๋ฒ์ .. ์๋ฅผ ๋ค๋ฉด 1.12 ์ด๋ฐ๊ฑฐ",
"short_name" : "์ค์นํ ์ฑ๋ฐ์ฒ๋ ๋ฐํํ๋ฉด์ ํ์ํ ์งง์ 12์ ์ด๋ฆ",
"name" : "๊ธฐ๋ณธ์ด๋ฆ",
"icons" : { ์ฌ๋ฌ๊ฐ์ง ์ฌ์ด์ฆ๋ณ ์์ด์ฝ ์ด๋ฏธ์ง ๊ฒฝ๋ก },
"start_url" : "์ฑ์์ด์ฝ ๋๋ ์ ์ ๋ณด์ฌ์ค ๋ฉ์ธํ์ด์ง ๊ฒฝ๋ก",
"display" : "standalone ์๋๋ฉด fullscreen",
"background_color" : "์ฑ ์ฒ์ ์คํ์ ์ ๊น ๋จ๋ splashscreen์ ๋ฐฐ๊ฒฝ์",
"theme_color" : "์๋จ ํญ์์ ๋ฑ ์ํ๋ ํ
๋ง์์",
}
- service-worker.js ํ์ผ์ ์๋ฅผ ๋ค์ด ์นด์นด์คํก ์ฑ๊ฐ์๊ฑฐ ์ค์นํ ๋ ๊ตฌ๊ธํ๋ ์ด ์คํ ์ด ๊ฐ์ ์ค์นํ๋ฉด ๊ทธ๋ผ ์นดํก ๊ตฌ๋์ ํ์ํ ์ด๋ฏธ์ง, ๋ฐ์ดํฐ๋ค์ด ์ ๋ถ ํ๋์ ์ค์น๋๋ค.
- ๊ทธ๋ฆฌ๊ณ ์นดํก์ ์ผ๋ฉด ์นดํก ๋ก๊ณ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์นดํก ์๋ฒ์ ์์ฒญํ๋๊ฒ ์๋๋ผ ํ๋์ ์ด๋ฏธ ์ค์น๋์ด ์๋๊ฑธ ๊ทธ๋๋ก ๊ฐ์ ธ์์ ์ด๋ค.
- ์ด๊ฑธ ํ๋ด๋ด๋๋ก ๋์์ฃผ๋ ํ์ผ์ด ๋ฐ๋ก service-worker ๋ผ๋ ํ์ผ์ด๋ค.
- ์ด ํ์ผ์ ์ค์ ์ ์ ํด์ฃผ๋ฉด ์ด์ ์น์ฑ์ ์ค์นํ์ ๋ ์ด๋ค CSS, JS, HTML, ์ด๋ฏธ์ง ํ์ผ์ด ํ๋์ ์ค์น๋ ์ง ๊ฒฐ์ ํ ์ ์๋ค.
- ๊ทธ๋ผ ์ด์ ๋ค์์ ์ฑ์ ์ผค ๋๋ง๋ค ์๋ฒ์ CSS,JS,HTML ํ์ผ์ ์์ฒญํ๋๊ฒ ์๋๋ผ Cache Storage์ ์ ์ฅ๋์ด์๋ CSS,JS,HTML ํ์ผ์ ์ฌ์ฉํ๊ฒ ๋๋ค.(๊ทธ๋ผ ์ด์ ์คํ๋ผ์ธ์์๋ ์ฌ์ฉ์ด ๊ฐ๋ฅ!)
โ๏ธ ๊ฐ๋ฐ์๋๊ตฌ๋ก PWA ๋๋ฒ๊น
ํ๊ธฐ
- ๋ด๊ฐ build ํ๋ ํ๋ก์ ํธ๊ฐ PWA์ธ์ง ์๋์ง ์ดํด๋ณด๊ณ ์ถ์ผ๋ฉด ์ผ๋จ ์ฌ์ดํธ๋ฅผ ํธ์คํ
๋ฐ์ ์ฌ๋ฆฌ๊ฑฐ๋ (Github pages ์ด๋ฐ ๊ฒ๋ ๋จ)
- VScode ์ต์คํ
์
์ค์ live server ์ด๊ฑธ ๊ฒ์ํด์ ์ค์นํ ๋ค
1. build ํด๋๋ฅผ ์๋ํฐ๋ก ์คํํ๊ณ
2. ๊ฑฐ๊ธฐ ์๋ index.htmldmf ์ฐํด๋ฆญ-live server๋ก ๋์ฐ๊ธฐ ๋๋ฅด๋ฉด ๋จ
- ๋์ ์ฌ์ดํธ์์ ํฌ๋กฌ ๊ฐ๋ฐ์๋๊ตฌ๋ฅผ ํค๋ฉด Application์ด๋ผ๋ ํญ์ด ์๋ค. ์ฌ๊ธฐ ๋ค์ด๊ฐ๋ฉด PWA์ ๊ด๋ จ๋ ๋ชจ๋ ๊ฑธ ์ดํด ๋ณผ ์ ์๋ค. (๋ด ์ฌ์ดํธ ์์ผ๋ฉด flipkart.com ์ด๋ฐ PWA ์ฌ์ดํธ ๋ค์ด๊ฐ์ ๋ฐ๋ผํด๋ ๋จ)
- Manifest ๋ฉ๋ด์์ manifest.json ๋ด์ฉ๋ค์ ํ์ธ๊ฐ๋ฅํ๊ณ
- Service Worker ๋ฉ๋ด์์ service-worker ํ์ผ์ด ์ ์๋์ง, ์คํ๋ผ์ธ์์ ์ ๋์ํ๋์ง ํ
์คํธ ๊ฐ๋ฅํ๊ณ ํธ์์๋ฆผ ๊ธฐ๋ฅ์ ๊ฐ๋ฐํด๋จ๋ค๋ฉด ํธ์์๋ฆผ๋ ์ํ๋ก ์ ์กํด๋ณผ ์ ์๋ค.
- Cache Storage ๋ฉ๋ด์์ service-worker ๋๋ถ์ ํ๋์ ์ค์น๋ CSS, JS, HTML ํ์ผ๋ค์ ํ์ธํ ์ ์๋ค. ์บ์๋ ํ์ผ ์ ๊ฑฐ๋ ๊ฐ๋ฅ.
โ๏ธ ๋์ PWA๋ฅผ ์ปค์คํฐ๋ง์ด์งํ๋ ค๋ฉด
- ์ง๊ธ PWA ๋ฐํ์ด ์ฝ๊ณ ๊ฐ๋จํ ์ด์ ๋ ๊ตฌ๊ธ์ workbox ๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋๋ถ์ธ๋ฐ
- ์ด๊ฒ create-react-app ์ค์นํ ๋ ํจ๊ป ์ค์น๋์๊ธฐ ๋๋ฌธ์ด๋ค.
- ๊ทธ๋์ PWA ๋ฐํ๋ฐฉ์ ๊ฐ์๊ฑธ ์ปค์คํฐ๋ง์ด์ง ํ๊ณ ์ถ์ผ๋ฉด workbox ์ฌ์ฉ๋ฒ์ ์ตํ์ผ ํ๋๋ฐ ๊ตฌ๊ธ์ ๊ฐ๋ฐ๋ฌธ์๋ ์กฐ๊ธ ์ด๋ ต๋ค.
- ๊ทธ๋์ ๋น ๋ฅด๊ฒ ์ปค์คํฐ๋ง์ด์ง ๋ฐฉ๋ฒ์ผ๋ก
Q) ๋ง์ฝ ํ๋์ ์ค์นํ ํ์ผ ์ค์ HTML์ ์ ์ธํ๊ณ ์ถ๋ค๋ฉด?
- ๋์ ํ๋ก์ ํธ ํด๋ ๋ด์ node_modules/react-scripts/config/webpack.config.js ํ์ผ์ ์ฐพ์์ ํ๋จ์ ๋ณด๋ฉด
// ๊ตฌ๋ฒ์
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true,
exclude: [/\.map$/, /asset-manifest\.json$/],
})
// ์ ๋ฒ์
new WorkboxWebpackPlugin.InjectManifest({
swSrc,
dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
- ์ฌ๊ธฐ์ exclude๋ผ๋ ํญ๋ชฉ์ด ์ด๋ค ํ์ผ์ ์บ์ฑํ์ง ์์๊ฑด์ง ๊ฒฐ์ ํ๋ ๋ถ๋ถ์ด๋ค.
- ์ ๊ท์์ผ๋ก ์์ฑํ๋๋ฐ ์ ๊ท์๊ณผ ์ผ์นํ๋ ํ์ผ๋ช
์ ์ ์ธํ๋ค. ๊ทธ๋์ ์ํ๋ HTML ํ์ผ์ ์ฌ๊ธฐ ๋ฑ๋กํ๋ฉด ๋๋ค.
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true,
exclude: [/\.map$/, /asset-manifest\.json$/, /index\.html/],
})
- ์ด๊ฑฐ ๋ง๊ณ ๋ "๋ชจ๋ .css๋ก ๋๋๋ ํ์ผ" "a๋ผ๋ ๊ธ์๋ก ์์ํ๋ ํ์ผ" ์ด๋ฐ ์์ผ๋ก ์ ๊ท์์ผ๋ก ์์ฑํ ์๋ ์๋๋ฐ ๊ทธ๊ฒ์ ์ ๊ท์ ๋ฌธ๋ฒ์์ ์ฐพ์๋ณด๋ฉด ๋๋ค.
- ๊ทผ๋ฐ ๋ง์ฝ ๋์ ์ฌ์ดํธ๊ฐ ์ ํ๋ธ๋ ์ธ์คํ๊ทธ๋จ์ฒ๋ผ ์
์ฅ๊ณผ ๋์์ Ajax๋ก ์ด๊ธฐ๋ฐ์ดํฐ๋ค์ ์ ๋ถ ๋ฐ์์ค๋ ์ฌ์ดํธ๋ผ๋ฉด ๊ตณ์ด HTML์ ์์ ํ ํ์๊ฐ ์๋ค.
๋ณธ ํฌ์คํ ์ << React ๋ฆฌ์กํธ ๊ธฐ์ด๋ถํฐ ์ผํ๋ชฐ ํ๋ก์ ํธ๊น์ง! >> ๊ฐ์๋ฅผ ์ฐธ๊ณ ํฉ๋๋ค.