Razzle: ์ƒˆ ์•ฑ ์‹œ์ž‘

์— ๋งŒ๋“  2017๋…„ 06์›” 05์ผ  ยท  5์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jaredpalmer/razzle

์ด ํ”„๋กœ์ ํŠธ๋Š” ๋ฉ‹์ ธ ๋ณด์ž…๋‹ˆ๋‹ค. ์ €๋Š” ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๋Š”๋ฐ next.js, create-react-app, razzle ์‚ฌ์ด์— ์–ด๋–ค ์ด์ ์ด ์žˆ๋Š”์ง€ ๋˜๋Š” ์žฅ๊ธฐ์ ์œผ๋กœ ๊ฐ€์žฅ ์ข‹์€ ๊ฒƒ์€ ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” SSR์„ ์ •๋ง๋กœ ์›ํ•˜๋ฏ€๋กœ CRA๋Š” ์•„๋งˆ๋„ ๋ฌธ์ œ๊ฐ€๋˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” next๋กœ ์•ฑ์„ ๋งŒ๋“  ๋‹ค์Œ ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋ผ๊ฑด๋Œ€ ์ด๊ฒƒ์€ ์ด๊ฒƒ์„ ์งˆ๋ฌธํ•˜๊ธฐ์— ๊ดœ์ฐฎ์€ ๊ณณ์ด์ง€๋งŒ ์žฅ๊ธฐ์ ์œผ๋กœ ๋ฌด์—‡์ด ์ตœ์„ ์ธ์ง€์— ๋Œ€ํ•œ ์ƒ๊ฐ์„ ์–ป๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

discussion

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@knipferrc ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

๋น„์Šทํ•œ ๊ฒฝํ—˜์„ ํ†ตํ•ด Razzle์„ ๋งŒ๋“ค๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์•ฝ 6๊ฐœ์›” ์ „์— Next.js๊ฐ€ ๋‚˜์˜จ ์งํ›„ ๊ฑฐ๋Œ€ํ•œ ์•ฑ์„ ์‹œ์ž‘ํ–ˆ๋Š”๋ฐ ์•ฑ ์ดํƒˆ์ด ๋„ˆ๋ฌด ์ปค์„œ ๊ฐ๋‹นํ•˜๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. ๋ง ๊ทธ๋Œ€๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋œ ๋ผ์šฐํŒ… ์˜ˆ์ œ(์˜ˆ: /user/:id )์— ๋Œ€ํ•œ PR์„ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฝ๋กœ ๋ณ€๊ฒฝ ์‹œ getInitialProps๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ๋œ ์ด์ƒํ•œ ๋ฒ„๊ทธ๋กœ ์ธํ•ด ์ผ์ฃผ์ผ ๋‚ด๋‚ด ์ž‘์—…์„ ์žƒ์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋ฃจ๊ฐ€ ๋๋‚˜๋ฉด Next.js๋Š” ๋ผ์šฐํŒ…, ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ, ํด๋” ๊ตฌ์กฐ ๋ฐ ์Šคํƒ€์ผ ์ง€์ •๊ณผ ๊ฐ™์€ ๋งค์šฐ ์ค‘์š”ํ•œ ๊ฒฐ์ •์„ ๋งŽ์ด ๋‚ด๋ฆฝ๋‹ˆ๋‹ค. ์ด๊ฒƒ๋“ค์ด ์ข‹์€์ง€ ๋‚˜์œ์ง€๋Š” ์ „์ ์œผ๋กœ ๋‹น์‹ ์ด ๊ตฌ์ถ•ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ข…๋ฅ˜์— ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ €๋Š” ์‹ค์ œ๋กœ ๋ชจ๋“  ๋‹จ์ผ ๊ฒฝ๋กœ(2๊ฐœ๋งŒ)๋ฅผ ์„œ๋ฒ„ ๋ Œ๋”๋งํ•  ํ•„์š”๊ฐ€ ์—†์—ˆ๊ณ  ์ „์ฒด ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•˜๋Š” ๋Œ€์‹  ํด๋ผ์ด์–ธํŠธ ๋กœ๋“œ ์ƒํƒœ๋ฅผ ์›ํ–ˆ์œผ๋ฉฐ ๊ฒฝ๋กœ ๋ณ€๊ฒฝ ์‚ฌ์ด์— ์ „์—ญ ์ƒํƒœ ํŠธ๋ฆฌ๋ฅผ ํŒŒ๊ดดํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ React-Router 4๊ฐ€ ์–‡๊ฒŒ ์ฌ ๋นต ์ดํ›„๋กœ ์ตœ๊ณ ๋ผ๋Š” ์ œ ์˜๊ฒฌ๊ณผ ํ•จ๊ป˜ Next.js๊ฐ€ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋” ์•ˆ์ •์ ์ธ ๊ฒƒ์„ ์ฐพ๋‹ค๊ฐ€ NYT์˜ kyt ํ”„๋กœ์ ํŠธ๋กœ ์˜ฎ๊ฒผ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์•ฝ 2๊ฐœ์›” ๋™์•ˆ ์ถฉ๋ถ„ํ–ˆ์ง€๋งŒ 1) ์•ฑ์ด ์„ฑ์žฅํ•จ์— ๋”ฐ๋ผ ๋นŒ๋“œ ์‹œ๊ฐ„์ด ์—„์ฒญ๋‚˜๊ฒŒ ๋Š๋ ค์กŒ๊ณ (>45์ดˆ), 2) kyt์˜ SCSS ๊ทœ์น™์ด ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜์ง€ ์•Š์•˜๊ณ , 3) kyt์˜ ๋กœ๊น…์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๋ฏธ์นœ ์–‘์˜ ์ด๋ชจํ‹ฐ์ฝ˜) ๊ฝค ์งœ์ฆ๋‚ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” kyt์— ๋Œ€ํ•œ ๋” ์–‡๊ณ  ๋น ๋ฅธ ๋Œ€์ฒด ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์ง€๋งŒ, ๋ฒ”์šฉ HMR๊ณผ Next.js-- create-react-app-ssr ์™€ ์œ ์‚ฌํ•œ ๊ตฌ์„ฑ API๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ฒƒ์„ ๋งํ•˜๊ณ  ์™„๋ฃŒํ•˜๊ณ  ๋‚˜๋ฉด ๊ฑฐ์˜ ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค์—ˆ์œผ๋ฉฐ ์ด ์ˆ˜์ค€์˜ ์ถ”์ƒํ™”๊ฐ€ ๋‚ด ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋” ์ ํ•ฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. "ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š”"์ด๋ผ๋Š” ๋ง์€ Razzle์ด Angular, Vue, Rax, Preact, Inferno, React-XP, RN-Web, Reason-React ๋ฐ _๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€_ ๋‹ค์Œ์— ๋‚˜์˜ค๋Š” ๋ชจ๋“  ๋ฏธ์นœ ๊ฒƒ๋“ค์ด 100% ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. IMHO, ์ ์‘์„ฑ์€ Razzle๊ณผ ๋‚ด๊ฐ€ ๋ณธ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ ์‚ฌ์ด์˜ ์ฃผ์š” ์ฐจ๋ณ„ํ™” ์š”์†Œ์ž…๋‹ˆ๋‹ค. Razzle์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ๋ฌด์–ธ๊ฐ€์— ๋Œ€ํ•ด ์ฝ๊ณ , ํฌํฌ๋ฅผ ๋งŒ๋“ค๊ณ , babel-transform/webpack config/parallel ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ์ถ”๊ฐ€ ํ•˜๊ณ  ์‹œ๋„ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ์š”? Next์™€ ๋‹ฌ๋ฆฌ Razzle์€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์•„๋‹ˆ๋ฉฐ CRA์™€ ๋‹ฌ๋ฆฌ Razzle์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ„๊ธฐํ•˜์ง€ ์•Š๊ณ  ๊ธฐ๋ณธ ๊ตฌ์„ฑ์„ ๋ณด๊ฐ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ๋ฐฐ์šฐ๊ณ , ๊ฐ€๋ฅด์น˜๊ณ , ์‹คํ—˜ํ•˜๊ณ , ์‚ฌ์—…์„ ํ•˜๋Š” ๋ฐฉ์‹์— ์žˆ์–ด์„œ ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

Razzle์˜ ์œ ์—ฐ์„ฑ๊ณผ ๋ถˆ๊ฐ€์ง€๋ก ์€ ์ด๋ฏธ ๋‚˜์™€ ๋‚ด ํŒ€์— ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • razzle.config.js ์—์„œ 10์ค„ ๋ฏธ๋งŒ์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ถ€๋ถ„์ ์œผ๋กœ ํ๋ฆ„์—์„œ 100% TypeScript๋กœ ์•ฑ์„ ์ ์ง„์ ์œผ๋กœ ์˜ฎ๊ฒผ์Šต๋‹ˆ๋‹ค.
  • ์‹œ๋„์กฐ์ฐจ ํ•˜์ง€ ์•Š๊ณ  Razzle์€ ReasonReact ํ”„๋กœ์ ํŠธ(SSR ๋˜๋Š” SPA)๋ฅผ ๋ถ€ํŠธ์ŠคํŠธ๋žฉํ•˜๋Š” ๊ฐ€์žฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ•์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Razzle์˜ ๋ฏธ๋ž˜์— ๊ด€ํ•ด์„œ. ์ดํ‹€ ์ „ "CRA์— SSR ์ง€์› ์ถ”๊ฐ€"๊ฐ€ React Core ํŒ€์˜ ๋กœ๋“œ๋งต์—์„œ ์ƒ์œ„ 15๊ฐœ ํ•  ์ผ์— ์–ธ๊ธ‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. SSR ์ง€์›์ด CRA์— ์ถ”๊ฐ€๋˜๋ฉด Razzle์ด ๋” ์ด์ƒ ์กด์žฌํ•  ํ•„์š”๊ฐ€ ์—†์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค..._๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์™„์ „ํžˆ ๋ฉ‹์ง‘๋‹ˆ๋‹ค_. ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ๋  ๋•Œ๊นŒ์ง€ Razzle์€ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ ๋ฒ”์šฉ JavaScript๋ฅผ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ๋นŒ๋“œ ๋„๊ตฌ๋กœ ์•ž์œผ๋กœ ๋‚˜์•„๊ฐˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  5 ๋Œ“๊ธ€

๋‚˜๋Š” ์ด๊ฒƒ์ด ๋‹น์‹ ๊ณผ ๋‹น์‹ ์˜ ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ์— ํ•„์š”ํ•œ ๊ฒƒ์— ๋‹ฌ๋ ค ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ์ •๋‹ต์ด๋ผ๋Š” ๋ฐ ๋ชจ๋‘๊ฐ€ ๋™์˜ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์•„๋Š” ํ•œ Next.js๋Š” ZEIT ์ƒํƒœ๊ณ„์˜ ์ผ๋ถ€๋กœ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์™„์ „ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ๋˜๋Š” ํ”Œ๋žซํผ?. ๋ฐ˜๋ฉด Razzle์€ ํ›จ์”ฌ ๋” ๋ฏธ๋‹ˆ๋ฉ€ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฌ๊ธฐ์—๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ์ด ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ๊ณ  ๊ฒฐ๊ตญ์—๋Š” ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒƒ๋„ ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ Next.js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ–ˆ์ง€๋งŒ ๋‚˜๋ฅผ ์งœ์ฆ๋‚˜๊ฒŒ ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์ž‘์€ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Next.js๋Š” HTML ์ถœ๋ ฅ์„ ์ ์ ˆํ•˜๊ฒŒ ์ถ•์†Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ styled-jsx CSS-in-JS๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ €๋Š” Styled Components ๋ฅผ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ๋‚ด ์ƒˆ ํ”„๋กœ์ ํŠธ์˜ ๊ฒฝ์šฐ ๋ผ์šฐํŒ…์ด ํ•„์š”ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค(์•„์ง ๐Ÿ˜„).

๋งˆ์ง€๋ง‰์œผ๋กœ ์šด ์ข‹๊ฒŒ๋„ ๋งŽ์€ ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ•œ ํ›„ Razzle์„ ์ฐพ์•„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ €๋Š” ํ•„์š”ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋ชจ๋“ˆ๊ณผ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๋Š” Razzle Material UI Styled Example ์ด๋ผ๋Š” ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์œผ๋กœ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๊ฑฐ์˜ ๋ป”๋ป”ํ•˜๊ฒŒ ์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ๊ธฐ๋Šฅ ๋˜๋Š” ๊ทธ ์ค‘ ์ผ๋ถ€๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์–ธ๊ธ‰๋œ ์ €์žฅ์†Œ๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

@knipferrc ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

๋น„์Šทํ•œ ๊ฒฝํ—˜์„ ํ†ตํ•ด Razzle์„ ๋งŒ๋“ค๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์•ฝ 6๊ฐœ์›” ์ „์— Next.js๊ฐ€ ๋‚˜์˜จ ์งํ›„ ๊ฑฐ๋Œ€ํ•œ ์•ฑ์„ ์‹œ์ž‘ํ–ˆ๋Š”๋ฐ ์•ฑ ์ดํƒˆ์ด ๋„ˆ๋ฌด ์ปค์„œ ๊ฐ๋‹นํ•˜๊ธฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. ๋ง ๊ทธ๋Œ€๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜ํ™”๋œ ๋ผ์šฐํŒ… ์˜ˆ์ œ(์˜ˆ: /user/:id )์— ๋Œ€ํ•œ PR์„ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฝ๋กœ ๋ณ€๊ฒฝ ์‹œ getInitialProps๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ๋œ ์ด์ƒํ•œ ๋ฒ„๊ทธ๋กœ ์ธํ•ด ์ผ์ฃผ์ผ ๋‚ด๋‚ด ์ž‘์—…์„ ์žƒ์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋ฃจ๊ฐ€ ๋๋‚˜๋ฉด Next.js๋Š” ๋ผ์šฐํŒ…, ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ, ํด๋” ๊ตฌ์กฐ ๋ฐ ์Šคํƒ€์ผ ์ง€์ •๊ณผ ๊ฐ™์€ ๋งค์šฐ ์ค‘์š”ํ•œ ๊ฒฐ์ •์„ ๋งŽ์ด ๋‚ด๋ฆฝ๋‹ˆ๋‹ค. ์ด๊ฒƒ๋“ค์ด ์ข‹์€์ง€ ๋‚˜์œ์ง€๋Š” ์ „์ ์œผ๋กœ ๋‹น์‹ ์ด ๊ตฌ์ถ•ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ข…๋ฅ˜์— ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ €๋Š” ์‹ค์ œ๋กœ ๋ชจ๋“  ๋‹จ์ผ ๊ฒฝ๋กœ(2๊ฐœ๋งŒ)๋ฅผ ์„œ๋ฒ„ ๋ Œ๋”๋งํ•  ํ•„์š”๊ฐ€ ์—†์—ˆ๊ณ  ์ „์ฒด ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•˜๋Š” ๋Œ€์‹  ํด๋ผ์ด์–ธํŠธ ๋กœ๋“œ ์ƒํƒœ๋ฅผ ์›ํ–ˆ์œผ๋ฉฐ ๊ฒฝ๋กœ ๋ณ€๊ฒฝ ์‚ฌ์ด์— ์ „์—ญ ์ƒํƒœ ํŠธ๋ฆฌ๋ฅผ ํŒŒ๊ดดํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ React-Router 4๊ฐ€ ์–‡๊ฒŒ ์ฌ ๋นต ์ดํ›„๋กœ ์ตœ๊ณ ๋ผ๋Š” ์ œ ์˜๊ฒฌ๊ณผ ํ•จ๊ป˜ Next.js๊ฐ€ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋” ์•ˆ์ •์ ์ธ ๊ฒƒ์„ ์ฐพ๋‹ค๊ฐ€ NYT์˜ kyt ํ”„๋กœ์ ํŠธ๋กœ ์˜ฎ๊ฒผ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์•ฝ 2๊ฐœ์›” ๋™์•ˆ ์ถฉ๋ถ„ํ–ˆ์ง€๋งŒ 1) ์•ฑ์ด ์„ฑ์žฅํ•จ์— ๋”ฐ๋ผ ๋นŒ๋“œ ์‹œ๊ฐ„์ด ์—„์ฒญ๋‚˜๊ฒŒ ๋Š๋ ค์กŒ๊ณ (>45์ดˆ), 2) kyt์˜ SCSS ๊ทœ์น™์ด ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•˜์ง€ ์•Š์•˜๊ณ , 3) kyt์˜ ๋กœ๊น…์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๋ฏธ์นœ ์–‘์˜ ์ด๋ชจํ‹ฐ์ฝ˜) ๊ฝค ์งœ์ฆ๋‚ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” kyt์— ๋Œ€ํ•œ ๋” ์–‡๊ณ  ๋น ๋ฅธ ๋Œ€์ฒด ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์ง€๋งŒ, ๋ฒ”์šฉ HMR๊ณผ Next.js-- create-react-app-ssr ์™€ ์œ ์‚ฌํ•œ ๊ตฌ์„ฑ API๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ฒƒ์„ ๋งํ•˜๊ณ  ์™„๋ฃŒํ•˜๊ณ  ๋‚˜๋ฉด ๊ฑฐ์˜ ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค์—ˆ์œผ๋ฉฐ ์ด ์ˆ˜์ค€์˜ ์ถ”์ƒํ™”๊ฐ€ ๋‚ด ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋” ์ ํ•ฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. "ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š”"์ด๋ผ๋Š” ๋ง์€ Razzle์ด Angular, Vue, Rax, Preact, Inferno, React-XP, RN-Web, Reason-React ๋ฐ _๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€_ ๋‹ค์Œ์— ๋‚˜์˜ค๋Š” ๋ชจ๋“  ๋ฏธ์นœ ๊ฒƒ๋“ค์ด 100% ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. IMHO, ์ ์‘์„ฑ์€ Razzle๊ณผ ๋‚ด๊ฐ€ ๋ณธ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ ์‚ฌ์ด์˜ ์ฃผ์š” ์ฐจ๋ณ„ํ™” ์š”์†Œ์ž…๋‹ˆ๋‹ค. Razzle์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ๋ฌด์–ธ๊ฐ€์— ๋Œ€ํ•ด ์ฝ๊ณ , ํฌํฌ๋ฅผ ๋งŒ๋“ค๊ณ , babel-transform/webpack config/parallel ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ์ถ”๊ฐ€ ํ•˜๊ณ  ์‹œ๋„ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ์š”? Next์™€ ๋‹ฌ๋ฆฌ Razzle์€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์•„๋‹ˆ๋ฉฐ CRA์™€ ๋‹ฌ๋ฆฌ Razzle์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ„๊ธฐํ•˜์ง€ ์•Š๊ณ  ๊ธฐ๋ณธ ๊ตฌ์„ฑ์„ ๋ณด๊ฐ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ๋ฐฐ์šฐ๊ณ , ๊ฐ€๋ฅด์น˜๊ณ , ์‹คํ—˜ํ•˜๊ณ , ์‚ฌ์—…์„ ํ•˜๋Š” ๋ฐฉ์‹์— ์žˆ์–ด์„œ ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

Razzle์˜ ์œ ์—ฐ์„ฑ๊ณผ ๋ถˆ๊ฐ€์ง€๋ก ์€ ์ด๋ฏธ ๋‚˜์™€ ๋‚ด ํŒ€์— ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • razzle.config.js ์—์„œ 10์ค„ ๋ฏธ๋งŒ์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ถ€๋ถ„์ ์œผ๋กœ ํ๋ฆ„์—์„œ 100% TypeScript๋กœ ์•ฑ์„ ์ ์ง„์ ์œผ๋กœ ์˜ฎ๊ฒผ์Šต๋‹ˆ๋‹ค.
  • ์‹œ๋„์กฐ์ฐจ ํ•˜์ง€ ์•Š๊ณ  Razzle์€ ReasonReact ํ”„๋กœ์ ํŠธ(SSR ๋˜๋Š” SPA)๋ฅผ ๋ถ€ํŠธ์ŠคํŠธ๋žฉํ•˜๋Š” ๊ฐ€์žฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ•์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Razzle์˜ ๋ฏธ๋ž˜์— ๊ด€ํ•ด์„œ. ์ดํ‹€ ์ „ "CRA์— SSR ์ง€์› ์ถ”๊ฐ€"๊ฐ€ React Core ํŒ€์˜ ๋กœ๋“œ๋งต์—์„œ ์ƒ์œ„ 15๊ฐœ ํ•  ์ผ์— ์–ธ๊ธ‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. SSR ์ง€์›์ด CRA์— ์ถ”๊ฐ€๋˜๋ฉด Razzle์ด ๋” ์ด์ƒ ์กด์žฌํ•  ํ•„์š”๊ฐ€ ์—†์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค..._๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์™„์ „ํžˆ ๋ฉ‹์ง‘๋‹ˆ๋‹ค_. ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ๋  ๋•Œ๊นŒ์ง€ Razzle์€ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ ๋ฒ”์šฉ JavaScript๋ฅผ ์œ„ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š” ๋นŒ๋“œ ๋„๊ตฌ๋กœ ์•ž์œผ๋กœ ๋‚˜์•„๊ฐˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์™€!! ๋ฉ‹์ง„ ๋‹ต๋ณ€๋“ค ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” Jared, ์ €๋Š” Razzle์„ ์‚ฌ์šฉํ•˜์—ฌ SPA Angular ํ”„๋กœ์ ํŠธ๋ฅผ SSR๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ํžŒํŠธ๋‚˜ ์ง€์นจ์„ ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์ •๋ง ๊ณ ๋ง™์Šต๋‹ˆ๋‹ค.

Razzle Angular ์†”๋ฃจ์…˜์˜ ๊ฒฝ์šฐ +1์ž…๋‹ˆ๋‹ค. https://github.com/jaredpalmer/razzle/issues/1109

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰