์๋ ํ์ธ์,
gatsby.js๋ฅผ ์ฌ์ฉํ์ฌ ์น ์ฑ์ ๋น๋ ํ ๋ค์ AWS S3 ๋ฐ CloudFront๋ฅผ ํตํด ์ ๊ณตํ๋ ๊ฒ์ ๊ณ ๋ คํ๊ณ ์์ต๋๋ค.
node.js ์ฑ์ ๋ง๋๋ ๊ฒ๊ณผ ๋น๊ตํ ๋ ๋ฐ์ํ ์์๋ ๋ฌธ์ ๊ฐ ์์ต๋๊น?
gatsby.js๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์ฌ ๊ฐ๋จ ํด ๋ณด์ด๋ฉฐ ์ด๋ ๊ฒํ๋ฉด ๋ด ์ฝํ ์ธ ์น ์ฌ์ดํธ๋ฅผ ๋ด ์ฑ๊ณผ ์ฝ๊ฒ ํตํฉ ํ ์ ์์ต๋๋ค.
์น์ ํ๋,
๋ค๋์
๊ทํ์ ์๊ฒฌ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค, @barbush. 68 ๋จ์ด๊ฐ ๋๋ฌด ๋ง์ ์ค์ ๋ชฐ๋์ต๋๋ค.
ํค๋ ๋ผ์ธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ๊ฒ์ ๋งํฉ๋๋ค. gatsby.js๋ก ์ฑ์ ๋น๋ ํ ๋ ์ด๋ค ๋จ์ ์ด ์์ต๋๊น?
์ฑ์ ๋ง๋๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. ๋ด ์ง๋ฌธ์-gatsby.js๊ฐ ์ ์ ์น ์ฌ์ดํธ ์์ฑ์ ์ต์ ํ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ด๋ค ๋จ์ ์ด ์์ต๋๊น? ๋์ค์ ์ ๋ฅผ ๋ฌผ๋ฆด ๊ฒ์ด ์์ต๋๊น?
๋์๊ฒ ๊ฝค ๊ตฌ์ฒด์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
Woah woah woah @barbush ๋๋ ์ ๋ง๋ก ๋น์ ์ด ์ด๋ฐ ์ง๋ฌธ์ ์น์ํ๋ ๊ฒ์ ์ํ์ง ์์ต๋๋ค. ๋์ฐํ ์ง๋ฌธ (์ด๊ฒ์ด ์๋)์ด๋ผ๋ฉด ๋ฌด์ํ๊ณ ๊ทธ ์ฌ๋์๊ฒ ๋งํ๋ ๊ฒ์ด ๋ซ์ต๋๋ค. ๋ค์๋ ์ด์ ๊ฐ์ ์ง๋ฌธ์ ์๋ตํ์ง ๋ง์ญ์์ค.
๊ทํ์ ์ง๋ฌธ์ @bolus . Gatsby๋ ๋ฐ์ ์ฑ ๋ฐ ๊ธฐํ ์นํฉ / ๋ฐ์ ์ค์ ์ ์์ฑํ๋ ๊ฒ๊ณผ ์๋นํ ์ ์ฌํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. ๋ฐ๋ผ์ ์น ์ฑ์ ๋น๋ํ๋ ๋ฐ ์๋ฒฝํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. examples ๋๋ ํ ๋ฆฌ๋ฅผ ๋ณด๋ฉด redux ์์ ๊ฐ ์์ต๋๋ค. ์ฌ๋๋ค์ Apollo์ ํจ๊ป ๊ทธ๊ฒ์ ์์ฃผ ์ฑ๊ณต์ ์ผ๋ก ์ฌ์ฉํ๋ค๊ณ ํฉ๋๋ค. ์ฐ๋ฆฌ์ graphql ์ฌ์ฉ์ด ๊ทธ๋ค์ ๊ฒ๊ณผ ์ถฉ๋ํ๊ธฐ ๋๋ฌธ์ Relay๋ gatsby์ ํจ๊ป ์ฌ์ฉํ ์ ์์ง๋ง ์์ผ๋ก๋ ์ฝ๊ฒ ํด๊ฒฐํ ์์์ ๊ฒ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค.
๋ด๊ฐ ์๋ ๊ฐ์ฅ ํฐ ๋จ์ ์ ๋น์ ์ด "ํ์ด์ง"๋ฅผ ๋ง๋ค๊ณ ์๋ค๊ณ ๊ฐ์ ํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋์ ๋ง์ฝ ๋น์ ์ด ํ์ด์ง๊ฐ์๋ ์ง์ ์ ์ธ ์ฑ์ ๋ ๋ง์ด ๋น๋ํ๋ค๋ฉด ๊ทธ๊ฒ์ ๋น์ ์๊ฒ ๋ง์ ๊ฒ์์ฃผ์ง ์๊ณ ๋น์ ์ ์์ ๋ ์ด๋ ์ ๋ ์ ํ ํ ๊ฒ์ ๋๋ค. ์ด ๊ฒฝ์ฐ CRA์ ๊ฐ์ ๋ ๋ฐ๋๋ผ ์ค์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๊ทธ๋ฌ๋ "ํ์ด์ง"๋ฅผ ๊ตฌ์ถํ๋ ๊ฒฝ์ฐ gatsby๋ ์ฑ์ ๋น ๋ฅธ ๋ถํ ์ ์ํด ์๋ ์ฝ๋ ๋ถํ ๋ฐ ์ ์ SSR์ ์ป์ ์ ์์ผ๋ฏ๋ก ํ๋ฅญํฉ๋๋ค.
์ข ๋ ๊ณต์์ ์ธ ํธ๋ ์ด๋ ์คํ ๋ฌธ์๋ฅผ ์์ฑํ๊ณ ์ถ์ง๋ง ๊ทธ๋์ ์ฌ๊ธฐ์์ ์ง๋ฌธ์ ๋ฐ๊ฒ๋์ด ๊ธฐ์ฉ๋๋ค.
@KyleAMathews : ๊ฐ์ฌํฉ๋๋ค. ์ ๊ฐ ์ฐพ๋ ๋ฐ๋ก ๊ทธ๊ฒ์ ๋๋ค.
์ฝํ ์ธ ์ค์ฌ ์น ์ฌ์ดํธ (๋ธ๋ก๊ทธ, ํ๋งค ํ์ด์ง, ๋ฌธ์ ๋ฑ)๋ฅผ ๋ง๋ค ๊ณํ์ด๋ฉฐ, ๋จ์์ฑ์ ์ํด ๋์ผํ ๋๋ฉ์ธ์ ๋ช ๊ฐ์ ์์ ๋จ์ผ ํ์ด์ง ์ฑ์ ํธ์คํ ํ๊ณ ์ถ์ต๋๋ค.
Gatsby๊ฐ ์ด๊ฒ์ ์ด์์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๋ํ ๋น์ ์ ์์ ๋ฅผ ๋ค์ ์ ํ ํ ๊ฒ์ ๋๋ค
์ ์ฌ์ฉ ์ฌ๋ก์๋ ๋ฌธ์ ๊ฐ๋์ง ์์ง๋ง ์ด๋ค ์ ํ ์ฌํญ์ ์์ ํ ์ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด ์ผ๋ง๋ ์ด๋ ค์ด์ง ๋ง์ํด ์ฃผ์๊ฒ ์ต๋๊น?
Gatsby๋ฅผ ๋ง๋ค์ด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค, btw., Gatsby๋ ์ ๋ง ๋ฉ์ ธ ๋ณด์ ๋๋ค! :)
ํ์ง๋ง ์ ๊ฐ ๊ธฐ๋ํ ์์๋ ์ ํ ์ฌํญ๊ณผ์ด๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด ์ผ๋ง๋ ์ด๋ ค์ด์ง ๋ง์ํด ์ฃผ์๊ฒ ์ต๋๊น?
Gatsby๋ ๊ฐ๋ฅํ ํ ๋จ์ํ๊ณ ๊ฒธ์ ํด ์ง๋ ค๊ณ ๋ ธ๋ ฅํ๋ฏ๋ก ํนํ Gatsby๊ฐ ์ค๊ณ ํ ์ฝํ ์ธ / ํ์ด์ง ์น ์ฌ์ดํธ๋ฅผ ์ํ ํ ๋ ์ ํ์ ๋ถ๋ชํ์ง ์์์ผํฉ๋๋ค.
Gatsby๋ ์น ์ฑ๊ณผ ์ฌ์ดํธ ์์ด๋์ด๋ฅผ ํผํฉํ์ฌ ๊ฐ๋ฅํ ํ ์ฝ๊ฒ ์ ๋ง ๋น ๋ฅธ ์ฌ์ดํธ๋ฅผ ๊ตฌ์ถํ๊ธฐ์ํ ์ด์์ ์ธ ๊ฐ๋ฐ ๋ฐ ์์ฐ ๋๊ตฌ๋ฅผ ์ฐ๋ฆฌ ๋ง์ ์์ ๋ง๋ค์ด ๋ด๋๋ก ์ค๊ณ๋์์ต๋๋ค.
"ํ์ด์ง"๋ชจ๋ธ์์ ๋ฒ์ด๋๋ ๋ฐฉ์์ผ๋ก React๋ฅผ ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ์๋ง ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค (์ : ๋ ๋ง์ ์์ ํ ์ฑ). ํ์ง๋ง ๊ฑฐ๊ธฐ์์๋ Gatsby์๋ ๋ ํฐ ์ฌ์ดํธ https://www.gatsbyjs.org/docs/creating-and-modifying-pages/#creating -client-only-routes ๋ด์ ์ฑ์ ์ฝ๊ฒ ํฌํจ ํ ์์๋ ํ์ถ๊ตฌ๊ฐ ์์ต๋๋ค.
์๋ฒฝ ํด ๋ณด์ ๋๋ค. ๋ค์ ํ ๋ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
์๋ ํ์ธ์ @KyleAMathews ์ @bolus
์ฌ๊ธฐ์ ์๋ก์ด ๋ฌธ์ ๋ฅผ ์ฌ๋ ๋์ ์ปจํ ์คํธ์ ๊ธฐ์์ ์ฃผ์ heheh
๋ด /app
(ํด๋ผ์ด์ธํธ ์ ์ฉ ๊ฒฝ๋ก) ๋ด๋ถ์์ SPA (๋ก๊ทธ์ธ / ๋ก๊ทธ ์์ / ๋์ ๋ณด๋)๋ฅผ ์์ฑํ๋ ค๋ ๊ฒฝ์ฐ ๋ด๋ถ์ ์ ๋ผ์ฐํฐ๋ฅผ ์์ฑํด์ผํ๋ค๊ณ ๊ฐ์ ํ๋ฉด ์ด๋ป๊ฒ๋ฉ๋๊น? ๋ง์ต๋๊น?
์ด ์ ์ค ์ผ์ด์ค @KyleAMathews ์์ ๋ฌด์์ ๊ถ์ฅํฉ๋๊น? ์๋๋ฉด _ ๋ ๋ฐ๋๋ผ ์ ๊ทผ ๋ฐฉ์ _์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ข์๊น์?
๊ฐ์ฌํฉ๋๋ค
@fernandes checkout https://www.gatsbyjs.org/docs/creating-and-modifying-pages/#creating -client-only-routes โ ์ง๋ฌธ์ด ๋ ์์ผ๋ฉด ์๋ ค์ฃผ์ธ์!
์๋ ํ์ธ์, @KyleAMathews ๋น ๋ฅธ ๋ต์ฅ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค
ํ ์์ผ ๋ด๋ด ๊ฐ์ธ ๋น์ ๋์๊ณ ,์ด ์์ ๋ฅผ ํ์ธํ๊ณ ๋ค์ ํ๋ ...
๋ด๊ฐํ๋ ค๋ ๊ฒ์ https://github.com/fernandes/react-boilerplate๋ฅผ ๊ฐ์ ธ ์์ /app
์ ํด๋ผ์ด์ธํธ ์ ์ฉ ๊ฒฝ๋ก๋ก ๋ฃ์ผ์ญ์์ค.
์ด ์์ฉ๊ตฌ๋ ๋ค์์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
๋ฐ์ / redux (ํซ ๋ฆฌ๋ก๋ฉ ํฌํจ) / ๋ฐ์ ๋ผ์ฐํฐ redux
๋๋ JS์ ๋ํ ๊ฒฝํ์ด ๋ง์ง ์์ต๋๋ค. ๋ด๊ฐ ๋์น ์ธ๋ถ ์ฌํญ ์ผ ์๋ ์์ต๋๋ค .. ๋ค์ ๊ฐ์ฌํฉ๋๋ค!
react-boilerplate์ ๊ฐ์ ๋ด๋ถ์ Gatsby๋ฅผ ๋ฃ์ ์ ์์ต๋๋ค. Gatsby๋ ๋น๋๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ฌ์ดํธ๋ฅผ ์คํํ๋ ค๊ณ ํฉ๋๋ค. ๋์ Gatsby ์์ "์ฑ"๋ถ๋ถ์ ๋ฃ์ผ์ญ์์ค.
์, ๊ทธ๊ฒ ์ ๊ฐ ์๋ฏธ ํ ๋ฐ์
๋๋ค ... ๊ฐ์ธ ๋น๋ ๋ด ๋ชจ๋ ์น ์ฌ์ดํธ์ ํ์ด์ง๋ฅผ ์ฒ๋ฆฌํ๊ณ react-boilerplate
์ ํด๋ผ์ด์ธํธ ์ ์ฉ ๊ฒฝ๋ก๋ก /app
์๋์ ๊ฐ์ธ ๋น ๋ด๋ถ์ ๋ค์ด๊ฐ๋๋ค. ๊ทธ ์คํ, ํนํ react-router-redux)?
Gatsby๋ ์ด๋ฏธ ๋ชจ๋ webpack / Babel / ๊ธฐํ ๊ตฌ์ฑ์ ์ฒ๋ฆฌํ๋ฏ๋ก ๋ถํธ ์คํธ๋ฉ ํ๋ก์ ํธ๊ฐ ํ์ํ์ง ์์ต๋๋ค.
@KyleAMathews ๋๋ redux + apollo ํด๋ผ์ด์ธํธ๊ฐ ์๋ํ๋ ํด๋ผ์ด์ธํธ ์ ์ฉ ์ฑ์ ์ป๋ ๋ฐฉ๋ฒ์ ์์ ๋์ต๋๋ค .. ๋ต์ฅ์ ๋ณด๋ด ์ฃผ์ ์ ๋๋จํ ๊ฐ์ฌํฉ๋๋ค ๐ ๐
@KyleAMathews ์ฌ๊ธฐ์ ์์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ ์ ์ฉ ํ์ด์ง ๋ด์์ graphql apollo ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ๊ณ ์์ง๋ง ํด๋ผ์ด์ธํธ ์ธก์๋ง ํด๋น๋ฉ๋๋ค (๋ก๊ทธ์ธํด์ผํ๋ ๊ฒฝ์ฐ).ํ์ง๋ง Gatsby๋ ์ธ๋ฑ์ค ํ์ผ์ ์์ฑํ๋ ค๊ณ ํฉ๋๋ค. ๋น๋์; ๋ฌผ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๊ฒ
์ด HTML
์์ฑ์ ๊ฑด๋ ๋ฐ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ ์์ด ์์ต๋๊น?
์ต์ ์ ๋ณด:
https://www.gatsbyjs.org/packages/gatsby-plugin-create-client-paths/๋ฅผ ์ฌ์ฉํ๊ณ
๊ทธ ํ๋ฌ๊ทธ์ธ ์์ฑ deletePage
์ ๋ฐ๋ผ page.path
... ํ์คํ์ง๊ฐ ๐ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ,ํ์ง๋ง ๋ด ์ฌ์ฉ ์ฌ๋ก์ ๋ํด ์์
ํ๋ ๊ฒฝ์ฐ (์, ์ง๊ธ์ ๋ง๋ค ํ์, ๊ทธ๊ฒ์ ์๋ฒฝํ๊ฒ ์๋ํ๊ณ ๋ฅผ ํญ์ ๋ด app/index.html
๋ณด๋ด๋ nginx์ ๋ฆฌ๋๋ ์
๊ท์น์ด์ง๋ง ์ด์ ์ฑ์์ ์ ํํ ์ํ ํ ์์
์
๋๋ค ...
๋๋ ๊ฐ์ธ ๋น์ ์ ์ ๋ ์ต์ํด์ง๊ณ ์๊ณ , ๋ด๊ฐํ๋ ๋ชจ๋ ์ง์ ์ด ๋ ํ๋ณตํ๋ค๋ ๊ฒ์ ๊ณ ๋ฐฑ ํ ํ์๊ฐ์๋ค ... ๊ต์ฅํ ์์ @KyleAMathews !! ๐
@KyleAMathews ์ฌ๊ธฐ ๊ท์ฐฎ๊ฒํด์ ๋ฏธ์ํ์ง๋ง ํด๋ผ์ด์ธํธ ์ธก ๋ผ์ฐํ ์ ๋ํด ๋ฌผ์ด๋ณผ ์์๋ ์ข์ ์ฅ์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฐ๋ผ์ ๋ด ์ฌ์ฉ ์ฌ๋ก์์๋ firebase์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์์ง๋ง ์ฌ์ฉ์๊ฐ ์์ ํ ์ ์๊ธฐ ๋๋ฌธ์์ด ๋ฐ์ดํฐ๋ ๋น๋์ ๋ชจ๋ ์ฌ์ฉํ ์์๋ ๊ฒ์ ์๋๋๋ค.
๋ฐ๋ผ์ Gatsby Page (์ : / podcasts)์์ cDM์ firebase์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ์ฟผ๋ฆฌ ํ ์ โโ์์ต๋๋ค. ํ์ง๋ง ์ธ๋ถ ์ ๋ณด ํ์ด์ง (์ : / podcast / : id)๋ก ์ด๋ํ๊ณ ์ถ์ต๋๋ค. ์กฐ๊ธ ์์ด๋ฒ๋ฆฐ ๋ถ๋ถ์ด ์์ต๋๋ค. ํด๋น ๊ฒฝ๋ก๋ฅผ ํด๋ผ์ด์ธํธ ์ธก ๋ผ์ฐํ ์ ์์ํด์ผํฉ๋๊น?
/app
ํ๊ฒฝ ํด์น์ ๋ํ ์์ด๋์ด๋ ๊ทธ ์๋์ SPA๋ฅผ ๋ ์์๋ ์ฅ์๋ฅผ ๊ฐ๋ ๊ฒ์์ ์ดํดํ์ง๋ง ๋ด๊ฐํ๋ ค๋ ์์
์ ๋ํด์๋ ๊ณผ์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๊ฐ์ธ ๋น์์ ์ผ ํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋ชจ๋ ๊ณณ์์ ํ๋ฅญํ ๊ฒฝํ์ด์์ต๋๋ค. :)
@gafemoyano ๊ฐ /podcast/:id
๋ํ ๊ฒฝ๋ก๋ฅผ ๋ง๋๋ ๊ฒ์ ์ฌ์ฉ์๊ฐ ์์
ํ๋ ๋์ ๋ง๋ ํ ์บ์คํธ๊ฐ ์๋ค๋ฉด ์์ ํ ์๋ฏธ๊ฐ ์์ต๋๋ค. ํ ๊ฐ์ง ๋จ์ ์ ํ ์บ์คํธ ํ์ด์ง๋ฅผ ์ง์ ๋ฐฉ๋ฌธํ๋ ์ฌ๋๋ค์ TTFP ์๋๊ฐ ๋๋ ค์ง๋ค๋ ๊ฒ์
๋๋ค. ์ด์ ์๋ฒ์์ HTML์๋ก๋ํ์ฌ๋ก๋ ํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๋น๋์ ์กด์ฌํ๋ ํ ์บ์คํธ ํ์ด์ง๋ฅผ ์ ์ ์ผ๋ก ๋ ๋๋ง ํ ๋ค์ ์ฌ๋๋ค์ด ๋ง๋ค ๋ ๋ธ๋ผ์ฐ์ ์์ ๋ ๋ง์ ๊ฒ์ ์ฆ์์์ ์์ฑ ํ ์ ์์ต๋๋ค.
์ด ํ์ด์ง์์๋ ์ฌ๋๋ค์๊ฒ ํฅ๋ฏธ ๋ก์ โ Gatsby https://www.gatsbyjs.org/docs/building-apps-with-gatsby/๋ก ์ฑ์ ๋น๋ํ๋ ๋ฐฉ๋ฒ์ ๋ํ์ด ์ ๋ฌธ์ ํ์ด์ง๋ฅผ ์์ฑํ์ต๋๋ค.
ํค์ด @KyleAMathews ์ด๊ฒ์ด ๊ณต์์ ์ธ "ํด๋ผ์ด์ธํธ ์ธก ๋ฌธ์ "๊ฐ ๋์๊ธฐ ๋๋ฌธ์ hahah ํ ์บ์คํธ ํ๋ก ํธ ์๋์ ๋ฐฑ์๋๋ฅผ ๋ชจ๋ ์ ์ด ํ ์ ์๋ค๋ ์ ์ ๊ณ ๋ คํ ๋์ด ํ ์บ์คํธ ๋ฌธ์ ์ ๋ํด ๊ณ ๋ คํด ์๋ ๋ ๋ค๋ฅธ ์ฌํญ์ ํน์ ํ์ด์ง ๋ง ์ฌ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? ? ๋๋ ๋น๋๋ฅผ ์บ์ํ๊ณ ์์ ๋ ๋ด์ฉ ๋ง ๋ณ๊ฒฝํฉ๋๋ค. ์ด๋ป๊ฒ ์๋ ํ ์ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
https://github.com/gatsbyjs/gatsby/issues/3444 ๊ด๋ จ ๊ฐ๋ฅ
https://github.com/gatsbyjs/gatsby/issues/3260#issuecomment -352856214์ ์ ์ฅํ ํค / ๊ฐ ์บ์ API์ ๋ํด ๋๊ธ์ ๋ฌ์์ต๋๋ค. ๋ ์ด์์ + ํ์ด์ง ์ฝํ ์ธ ๊ฐ์๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ๋ฐ ์๊ฐ)
@KyleAMathews ๋ต์ฅ์ ํ์ง ์์์ผํฉ๋๋ค .
` // page.matchPath is a special key that's used for matching pages
// only on the client.
if (page.path.match(/^\/podcasts/:id/)) {
page.matchPath = "/podcasts/:id";
// Update the page.
createPage(page);
}
๊ทธ๋ฌ๋ ์คํ๋ ค ์์ ์ ํ์๋ ๊ฒ์ ์ฌ์ฉํ์ญ์์ค.
```
// page.matchPath๋ ํ์ด์ง ์ผ์น์ ์ฌ์ฉ๋๋ ํน์ ํค์
๋๋ค.
// ํด๋ผ์ด์ธํธ์์๋ง.
if (page.path.match (/ ^ / app /)) {
page.matchPath = "/ app / : path";
// Update the page.
createPage(page);
}
And on app/index.js I would define my routes by importing from ReactRouter directly:
'react-router-dom'์์ {Switch, Route} ๊ฐ์ ธ ์ค๊ธฐ
const AppIndex = () => (
)
```
/ app / podcasts / : id๋ฅผ ๋ฐฉ๋ฌธํ์ฌ ๊ตฌ์ฑ ์์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ ์ค๊ธฐ ์ํด ๊ฒฝ๋ก์ : id ๋ถ๋ถ์ ์ก์ธ์ค ํ ์์๋ PodcastDetails๋ฅผ ๋ ๋๋ง ํ ์์๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น?
๊ฐ๋จํ ์๋๋ฆฌ์ค๋ก ๋ถํธ์ ๋ผ์ณ ๋๋ ค ์ฃ์กํฉ๋๋ค. ๊ธฐ์กด ์์ ๋ก๋ ์์๋ผ ์ ์์์ต๋๋ค. ์ฌ๋๋ค์ด ๊ฐ์ธ ๋น๋กํ๋ ์ผ์ด ์๋นํ ํํ๋ค๋ฉด ํ์ด๋ธ๋ฆฌ๋ ์ฑ์ ์๋ฅผ ํฌํจํด์ผํ ๊น์? ํ์ํ ๊ฒฝ์ฐ ๊ธฐ๊บผ์ด ๋์ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ @KyleAMathews๋ฅผ ๊ตฌ์ถํ๊ณ ์ง์ ํด์ฃผ์ ์ ๋ค์ ํ ๋ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
์์ ์์ ๊ฒฝ๋ก์ app
๋ถ๋ถ์ ์์์ ์
๋๋ค. ํ์ํ ๋ชจ๋ ์ด๋ฆ์ ์ฌ์ฉํ ์ ์์ต๋๋ค (์ : podcasts
.
์์ ์ฌ์ดํธ๊ฐ ์ข์ ๊ฒ์ ๋๋ค. :-) ๊ณง ์๊ฐ์ด ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ์ด๋ฏธ ํด๊ฒฐ ํ ๋ค๋ฅธ ์ฌ๋์ ์ด๋ํ์ฌ ์ํ ์ฝ๋๋ฅผ ๊ณต์ ํ์ธ์!
์ฌ๊ธฐ์ ๋ช ๊ฐ์ง ์ํ ์ฝ๋๋ฅผ ์๋ํ๊ณ
ํ์ง๋ง ์ฌ์ ํ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
๋ด๊ฐ ์ฌ๊ธฐ์ ์ค๋ช
ํ ํ๋
๊ฐ๋จํ ๋งํด, ํ๋ก๋์
์ฉ์ผ๋ก ๋น๋ํ๊ณ /app/
๋๋ ํ ๋ฆฌ ์๋์ ๊ฒฝ๋ก (์ : localhost:9000/app/posts/1
๋ค์ด๊ฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋ก ๊ณ ์น๋ฉด 404 ๋น ํ์ด์ง๊ฐ ํ์๋ฉ๋๋ค.
localhost:9000/app/
์์ ํ์ด์ง๋ฅผ ์๋ก ๊ณ ์น๋ฉด ์ ๋๋ก ์๋ํฉ๋๋ค.
gatsby-plugin-create-client-paths
๋ํ prefixes
๊ตฌ์ฑ์ด ์๋ชป๋์์ ์ ์์ต๋๋ค.
module.exports = {
...
plugins : [
{
resolve: `gatsby-plugin-create-client-paths`,
options: {prefixes: [`/app/*`]},
},
...
};
๋ ๋ค๋ฅธ ๋ฌธ์ ๋ (๋ฌธ์ ์ธ์ง ํ์คํ์ง ์์) <Route />
์ <BrowserRouter>
๋ํ ํ ์ ์์ต๋๋ค.
ํ๋ก๋์
์ฉ์ผ๋ก ๋น๋ ํ ๋ (๊ฐ๋ฐ์ด ์ ์๋ ํจ) "๋ธ๋ผ์ฐ์ ๊ธฐ๋ก์ DOM์ด ํ์ํฉ๋๋ค"๋ผ๋ ์ค๋ฅ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค. Gatsby๊ฐ ๋
ธ๋ ํ๊ฒฝ์์ ์คํ๋๊ณ ๋ธ๋ผ์ฐ์ ๊ฐ ์์ผ๋ฏ๋ก window
๋ฑ์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ง์ง๋ง์ผ๋ก <BrowserRouter>
๋ฉ์ ์ ๊ฑฐํ๋๋ฐ ์ ๋๋ก ์๋ํฉ๋๋ค.
์ ๋ React๋ฅผ ์ฒ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ์ ๋ํ ์ ์ ํ ํด๊ฒฐ์ฑ
์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
๋์์ ๋ฐ๊ณ ์ถ์ด์ :)
@danielemesh ์๋
ํ์ธ์ Daniel. ๋ด ๊ฐ์ธ ๋น ์ฑ์ ๋ค์ ์์
ํ ์๊ฐ์ด ์์์ง๋ง ์์ค ์ฝ๋์์ ๋ณผ ์์๋ ๊ฒ์ /pages
๋ด์ /app/*
๋๋ ํฐ๋ฆฌ๋ฅผ ๋ฐฐ์นํ๋ค๋ ๊ฒ์
๋๋ค.
์ด๊ฒ์ด ์ด๋๋ก ๊ฐ์ผํ ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. src/
๋๋ ํ ๋ฆฌ์ ๋ฃ์ด ๋ณด๊ฒ ์ต๋๋ค.
์๋ํ๋์ง ์๋ ค์ฃผ์ธ์!
๊ฑด๋ฐฐ!
@gafemoyano๊ฐ ์๋ํ์ง๋ง ์๋ํ์ง ์์์ต๋๋ค.
๊ฐ์ธ ๋น๋ ์ธ์ํ์ง ๋ชปํฉ๋๋ค ..
๊ฐ์ฌ!
๋๋ ๋ช๋ช ํ๋ฌ๊ทธ์ธ์ ์ง๋ฉดํ์ฌ ๋ด ๊ฒ์ ์์ฑํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค (์๋ ํ๋ฌ๊ทธ์ธ์์ 100 % ๋น๋ ค ์ด), ์ด ์ข๊ฒ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ๊ฐ์ธ ๋น ํ๋ฌ๊ทธ์ธ์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ธ ์์์์ต๋๋ค.
๋๋ ์์ฉ ํ๋ก๊ทธ๋จ์์ ์ถ์ถํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ๋ฌธ์ ๋ app
๋ด๋ถ์ bc์ SSR์์ ์ฒ๋ฆฌํด์๋ ์๋๋ graphql ์ฟผ๋ฆฌ๊ฐ ์์ต๋๋ค.
@KyleAMathews ์์ ์ฌ์ดํธ์ ์๋ฏธ๋ ๋ฌด์์ ๋๊น? ์ด๋๊ฐ์ ์ถ๊ฐ ํ์๊ฒ ์ต๋๊น? ๋ด๊ฐ ํ ์์์ด ..
plugins: [
`app-layout`, // I set my layout
{
resolve: `app-client-only`, // I handle app pages
options: { prefixes: [`/app/*`] },
},
],
// Implement the Gatsby API โonCreatePageโ. This is
// called after every page is created.
exports.onCreatePage = ({ page, boundActionCreators }) => {
const { createPage } = boundActionCreators;
if (page.path.match(/^\/app/)) {
// It's assumed that `app.js` exists in the `src/layouts/` directory
page.layout = "app";
}
return true;
};
// Prefixes should be globs (i.e. of the form "/*" or "/foo/*")
const validatePrefixEntry = prefix => {
if (!prefix.match(/^\//) || !prefix.match(/\/\*$/)) {
throw Error(
`Plugin "gatsby-plugin-client-only-paths" found invalid prefix pattern: ${
prefix
}`
)
}
}
exports.onCreatePage = ({ page, store, boundActionCreators }, { prefixes }) => {
const { createPage, deletePage } = boundActionCreators
const re = {}
prefixes.forEach(validatePrefixEntry)
return new Promise(resolve => {
// Don't set matchPath again if it's already been set.
if (page.matchPath || page.path.match(/dev-404-page/)) {
resolve()
}
prefixes.some(prefix => {
if (!re[prefix]) {
// Remove the * from the prefix and memoize
const trimmedPrefix = prefix.replace(/\*$/, ``)
re[prefix] = new RegExp(`^${trimmedPrefix}`)
}
// Ensure that the path ends in a trailing slash, since it can be removed.
const path = page.path.match(/\/$/) ? page.path : `${page.path}/`
if (path.match(re[prefix])) {
page.matchPath = prefix.replace(/\*$/, `:path`)
if (path != '/app/') {
// <<<<<<<<<<<<<<<<< here is my modification >>>>>>>>>>>>>>>>>>>>>>>
// do not try to process on SSR, user needs to be logged to
// consume GraphQL API and render `app` pages correctly
deletePage(page)
// <<<<<<<<<<<<<<<<< here is my modification >>>>>>>>>>>>>>>>>>>>>>>
}
// createPage(page)
return true
}
return false
})
return resolve()
})
}
๋ฐ๋ผ์์ด ๋ฌธ์ ๊ฐ @KyleAMathews ์ 100 % ๊ด๋ จ๋์ด ์๋์ง ํ์คํ์ง
import CreateSchedule from './components/CreateSchedule'
import ViewSchedule from './components/ViewSchedule'
...
<ApolloProvider client={client}>
<Provider store={store}>
<Switch>
<Route exact path="/app" component={CreateSchedule} />
<Route path="/app/:id" component={ViewSchedule} />
</Switch>
</Provider>
</ApolloProvider>
exports.onCreatePage = async ({ page, boundActionCreators }) => {
const { createPage } = boundActionCreators
// page.matchPath is a special key that's used for matching pages
// only on the client.
if (page.path.match(/^\/app/)) {
page.matchPath = '/app/:path'
// Update the page.
createPage(page)
}
}
์ด์์ด gatsby-plugin-create-client-paths
ํ๋ฌ๊ทธ์ธ๋ ์ฌ์ฉํด ๋ณด์์ต๋๋ค.
๋ด CreateSchedule ๊ตฌ์ฑ ์์๋ 404ing ์์ด๋ ์ ์๋ํฉ๋๋ค : https://www.appointmentscheduler.org/app
ViewSchedule ๊ฒฝ๋ก / ๊ตฌ์ฑ ์์์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค : https://www.appointmentscheduler.org/app/1b42d8e8-66b5-4a8d-a0b5-fd4bb13bed09
์ ๊ทธ๋ฆฌ๊ณ 404๋ ๋น๋ ๋ ํ์ ๋ง โโ๋ฐ์ํฉ๋๋ค. ๊ฐ๋ฐ ์๋ฒ์๋์ด ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์ด๋ค ์์ด๋์ด?
@rozenmd ์๋ฒ ๋ผ์ฐํ
์ด ํ์ํฉ๋๋ค. netlify๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ gatsby-plugin-netlify
์ (๋ฅผ) ์ค์นํ ์ ์์ผ๋ฉฐ ์๋์ผ๋ก ์๋ฒ ๋ผ์ฐํ
๊ตฌ์ฑ์ ์์ฑํฉ๋๋ค (netlify-identity-widget์ด ์์์ ์ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ์ฌ์ดํธ๋ฅผ ์ ๊ณตํ๋ ๋ฐ ์ ํํ ์ฌ์ฉํ๊ณ ์๋์ง ํ์คํ์ง ์์ต๋๋ค)
๋๋ฐ!
๊ฐ์ฌํฉ๋๋ค @pieh!
๋ด๊ฐ ์ฌ์ฉํ netlify ์คํํฐ (https://github.com/konsumer/gatsby-starter-bootstrap-netlify)์ gatsby-config.js์ 'gatsby-plugin-netlify'
๊ฐ)์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ทธ๊ฒ์ ์ถ๊ฐํ๊ณ ๋ฐฐํฌํ๋ฉด์ด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค .๐
@KyleAMathews Gatsby๋ฅผ ์ฌ์ฉํ ๋ ์ ์ฌ์ ์ผ๋ก ํ ๊ฐ์ง ์ถ๊ฐ ๋ฌธ์ ๋ Gatsby์ ์ ์ฒด API๋ฅผ ํ ๋ฒ์ ๋น ๋ ํน์ฑ์ผ๋ก ์ธํด API๊ฐ ํธ์คํ ๋๋ ์๋ฒ์์ 503 (์๋น์ค ๊ฑฐ๋ถ) ์๋ต์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ ๋๋ค. ์ ๊ทผํ๋ค. ๋๋ ํ์ฌ GoDaddy ํธ์คํ ์์ ์ด๊ฒ์ ๊ฒฝํํ๊ณ ์์ต๋๋ค. 'gatsby develop'์ ์คํํ๋ฉด ์ต๋ ๋์ ์ฐ๊ฒฐ ์ ํ์ ์ฆ์ ๋๋ฌํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๊ฒ์ด ์ค์ ๋ก ์งํ๋๊ณ ์์ต๋๊น? ๋ก์ปฌ์์๋ ํ๋ฅญํ๊ฒ ์๋ํ์ง๋ง (๋ถ๋ฆฌ ๋ Drupal> Gatsby) GoDaddy์์ ํธ์คํ ํ ๋๋ ์๋ํ์ง ์์ต๋๋ค. ์ด๋ค ํ์ด๋ผ๋ ๋๋จํ ๊ฐ์ฌํฉ๋๋ค.
@ cf73 GoDaddy DNS๋ฅผ Netlify์ ๊ฐ์ Gatsby์ ๋ ์ ํฉํ ๊ฒ์ผ๋ก ์ง์ ํด ๋ณด์ จ์ต๋๊น?
@rozenmd ๋ฅผ ๋ช ํํํ๊ธฐ ์ํด drupal ํค๋๋ฆฌ์ค CMS๋ GoDaddy์์ ํธ์คํ ๋ฉ๋๋ค. Gatsby ์ฌ์ดํธ๋ ์ฌ์ ํ ๋ก์ปฌ์์ ์คํ ์ค์ ๋๋ค. ๊ทธ๋์ ๋ด๊ฐ ๋น์ ์ ์คํดํ์ง ์๋ ํ, Netlify๊ฐ ์ด๋ป๊ฒ ๋์ธ ์ ์๋์ง ๋ชจ๋ฅด๊ฒ ์ด์?
@ cf73 https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-drupal/src/gatsby-node.js๋ ์๋ง๋ ์ด๋ค ์ข
๋ฅ์ ๋๊ธฐ์ด์ ์ฌ์ฉํ ์ ์์ต๋๋ค (์ฐ๋ฆฌ๋ better-queue
๋ค๋ฅธ ๊ณณ์์๋) Promise.all
๋์ ๋์ ์์ฒญ์๋ณด๋ค ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ๊ฒ์ผ๋ก ์ ํํฉ๋๋ค. ๊ตฌํํ ์ ์๋ค๊ณ ์๊ฐํ์ญ๋๊น?
@pieh yes ๋๋ ๋ ๋์ ๋๊ธฐ์ด์ ์ฌ์ฉ์ ๋ณด์๊ณ ๊ด์ฐฎ์ ์๋ฃจ์ ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. ๊ทธ๋๋ ๋ด๊ฐ ์ค์ค๋ก ํ ์๋ ์์ ๊น๋ด ๋๋ ต๋ค. ๋ด๊ฐ ์์ ์ค์ธ ๋ํ ํด๋ผ์ด์ธํธ ํ๋ก์ ํธ์ 503 ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ์ฌ๊ธฐ์์ ์ฐ์ฐํ ์ฐ์ฐํ ๋ฐ๊ฒฌํ๋ค. Gatsby๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๋ค. ๋ง๊ฐ์ผ์ด ์ด๋ฐํ๊ธฐ ๋๋ฌธ์ ์์ผ๋ก ๋ช ์๊ฐ ๋๋ ๊ธฐ๊ปํด์ผ ๋ค์ ๋ ์ ๋์์ด ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋ค๋ฉด ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ์ฐพ์์ผํฉ๋๋ค. ๋๊ตฌ๋ ์ง์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฆ์ ํ ์์๋ ์์ (ํ์ํ ๊ฒฝ์ฐ ํธ์คํ ์ ํ ํฌํจ)์ ์ ์ ํ ์ ์์ต๋๊น? ๊ฒ์ฆ ๋ drupal + ํธ์คํ + Gatsby ์ํฌ ํ๋ก๊ฐ ์์ต๋๊น?
@ cf73 ๋ง๊ฐ์ผ์ ๋ํด ๋๋๋๋ค
@pieh ๋๋จ ํ ๊ฒ์ ๋๋ค, ๊ฐ์ฌํฉ๋๋ค !!
@KyleAMathews ์ ๋ ํด๋ผ์ด์ธํธ ์ฌ์ดํธ์์ ์์
ํ๋ ๋์ ์ ๋ฐํ ๋ฌธ์ ์ ์ง๋ฉดํ๊ณ ์์ต๋๋ค. Stack์ Gatsby์ graphiql์ ๋ํ Drupal JSON-API์
๋๋ค. ๋
ธ๋์ ์ธ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค (์ฒจ๋ถ ์ฐธ์กฐ). ๋ด๊ฐ ๋งํ ์์๋ ํ, ์ด๊ฒ์ Gatsby์ Drupal ์คํค๋ง๊ฐ ์์ ํ ๊ตฌ์ฒดํ๋์ง ์์๊ธฐ ๋๋ฌธ์
๋๊น? ์๋๋ฉด ๋จ๊ณ๋ฅผ ๋์น๊ณ ์์ต๋๊น? ๊ธด๊ธํ๊ณ ๋ง์ ๋์์ ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค!
์ฟผ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์์ผํฉ๋๋ค.
NodeArticle(id: { eq: GUID }) {
id
...otherFields
}
ID๋ก allNodeArticle
๋ฅผ ํํฐ๋ง ํ ์๋ ์์ง๋ง ํ๋๋ง ์ ํํ๋ ๊ฒฝ์ฐ NodeArticle
์ง์ ์ฟผ๋ฆฌํ๋ ๊ฒ์ด ๋ ๊น๋ํฉ๋๋ค.
@KyleAMathews ์ ๋ง ๊ฐ์ฌํฉ๋๋ค! ์ด๊ฒ์ด ๋ค๋ฃจ๋ ๋ฌธ์๋ฅผ ์๋ ค์ค ์ ์์ต๋๊น? ๋๋ ์ง๊ธ๊น์ง ์ด๊ฒ์ ๋ณด์ง ๋ชปํ์ต๋๋ค ... Gatsby๊ฐ Drupal๊ณผ ๋ํํ๋ ๋ฐฉ์์ ๊ณ ์ ํฉ๋๊น, ์๋๋ฉด ๋ฐฉ๊ธ ๋์น GraphQL์ ํต์ฌ ํ์ค ๋์์ ๋๊น? ์์ค ํ๋ฌ๊ทธ์ธ๊ณผ ํจ๊ป ์ด์ ๊ฐ์ ์์ค ๋ณ ๋ฌธ์๋ฅผ ๋ ๋์ ๋๊ฒ ํ๋ณดํ๋ ์์ด๋์ด๊ฐ ๋ ์ ์์ต๋๊น?
์ด๊ฒ์ drupal ํน์ ์ด ์๋ gatsby ํต์ฌ ๊ธฐ๋ฅ (๋ฃจํธ ์ฟผ๋ฆฌ ์์ค ํํฐ๋ง ์ํ)์ ๋๋ค. ์์ค ํ๋ฌ๊ทธ์ธ์ graphql ์คํค๋ง๋ฅผ ์ ์ ํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ํ๋ฌ๊ทธ์ธ์ด ์ ๊ณตํ๋ "์์"๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก gatsby core๊ฐ ์ํํ๋ ์์ ์ ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
Woah woah woah @barbush ๋๋ ์ ๋ง๋ก ๋น์ ์ด ์ด๋ฐ ์ง๋ฌธ์ ์น์ํ๋ ๊ฒ์ ์ํ์ง ์์ต๋๋ค. ๋์ฐํ ์ง๋ฌธ (์ด๊ฒ์ด ์๋)์ด๋ผ๋ฉด ๋ฌด์ํ๊ณ ๊ทธ ์ฌ๋์๊ฒ ๋งํ๋ ๊ฒ์ด ๋ซ์ต๋๋ค. ๋ค์๋ ์ด์ ๊ฐ์ ์ง๋ฌธ์ ์๋ตํ์ง ๋ง์ญ์์ค.
๊ทํ์ ์ง๋ฌธ์ @bolus . Gatsby๋ ๋ฐ์ ์ฑ ๋ฐ ๊ธฐํ ์นํฉ / ๋ฐ์ ์ค์ ์ ์์ฑํ๋ ๊ฒ๊ณผ ์๋นํ ์ ์ฌํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. ๋ฐ๋ผ์ ์น ์ฑ์ ๋น๋ํ๋ ๋ฐ ์๋ฒฝํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. examples ๋๋ ํ ๋ฆฌ๋ฅผ ๋ณด๋ฉด redux ์์ ๊ฐ ์์ต๋๋ค. ์ฌ๋๋ค์ Apollo์ ํจ๊ป ๊ทธ๊ฒ์ ์์ฃผ ์ฑ๊ณต์ ์ผ๋ก ์ฌ์ฉํ๋ค๊ณ ํฉ๋๋ค. ์ฐ๋ฆฌ์ graphql ์ฌ์ฉ์ด ๊ทธ๋ค์ ๊ฒ๊ณผ ์ถฉ๋ํ๊ธฐ ๋๋ฌธ์ Relay๋ gatsby์ ํจ๊ป ์ฌ์ฉํ ์ ์์ง๋ง ์์ผ๋ก๋ ์ฝ๊ฒ ํด๊ฒฐํ ์์์ ๊ฒ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค.
๋ด๊ฐ ์๋ ๊ฐ์ฅ ํฐ ๋จ์ ์ ๋น์ ์ด "ํ์ด์ง"๋ฅผ ๋ง๋ค๊ณ ์๋ค๊ณ ๊ฐ์ ํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋์ ๋ง์ฝ ๋น์ ์ด ํ์ด์ง๊ฐ์๋ ์ง์ ์ ์ธ ์ฑ์ ๋ ๋ง์ด ๋น๋ํ๋ค๋ฉด ๊ทธ๊ฒ์ ๋น์ ์๊ฒ ๋ง์ ๊ฒ์์ฃผ์ง ์๊ณ ๋น์ ์ ์์ ๋ ์ด๋ ์ ๋ ์ ํ ํ ๊ฒ์ ๋๋ค. ์ด ๊ฒฝ์ฐ CRA์ ๊ฐ์ ๋ ๋ฐ๋๋ผ ์ค์ ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๊ทธ๋ฌ๋ "ํ์ด์ง"๋ฅผ ๊ตฌ์ถํ๋ ๊ฒฝ์ฐ gatsby๋ ์ฑ์ ๋น ๋ฅธ ๋ถํ ์ ์ํด ์๋ ์ฝ๋ ๋ถํ ๋ฐ ์ ์ SSR์ ์ป์ ์ ์์ผ๋ฏ๋ก ํ๋ฅญํฉ๋๋ค.
์ข ๋ ๊ณต์์ ์ธ ํธ๋ ์ด๋ ์คํ ๋ฌธ์๋ฅผ ์์ฑํ๊ณ ์ถ์ง๋ง ๊ทธ๋์ ์ฌ๊ธฐ์์ ์ง๋ฌธ์ ๋ฐ๊ฒ๋์ด ๊ธฐ์ฉ๋๋ค.