๐ค 25๋ 1๋ถ๊ธฐ ํ๊ณ
์๋ก โ
25๋ 1๋ถ๊ธฐ๊ฐ ๋น ๋ฅด๊ฒ ํ๋ฌ๊ฐ์ต๋๋ค. ํ์ฌ ์งํํ๊ณ ์๋ ํ๋ก์ ํธ์ธ ๋น์ ผ ์์คํ ๊ณผ ๊ด๋ จํด ๊ธฐํ๋ถํฐ ๊ฐ๋ฐ ๋ฐ ์ด์์ ํ๋ฉฐ 1๋ถ๊ธฐ๋ฅผ ๋ณด๋์ต๋๋ค. 1๋ถ๊ธฐ๋ฅผ ๋์๋ณด๋ฉฐ 2๋ถ๊ธฐ์ ๋์๊ฐ ๋ฐฉํฅ์ ์ค๊ณํ๊ณ ์ก์ ํฌ์ธํธ๋ฅผ ๊ธฐ๋กํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
๋ณธ๋ก โ
ํญํด ํ๋ก ํธ์๋ 4๊ธฐ ์๋ฃํ์ต๋๋ค!โ
1๋ถ๊ธฐ๋ฅผ ๋์๋ณด๋ฉด ๊ฐ์ฅ ๋จผ์ ๋ ์ค๋ฅด๋ ๊ฒ์ ์๋ฌด๋๋ ํญํด์ ๋๋ค. 24๋ ์ฐ๋ง ํ๊ฐ๋ฅผ ํตํด ๊ธฐ๋ณธ๊ธฐ๋ฅผ ๋ค์ง๋ ์๊ฐ์ด ํ์ํ๋ค๊ณ ์๊ฐ์ด ๋ค์ด ํฉ๋ฅํ๊ฒ ๋๊ณ ์ด๋ฅผ ํตํด ๋ฆฌ์กํธ์ ๋์ ์๋ฆฌ์ ํด๋ฆฐ ์ฝ๋ ๋ฐ ํ ์คํธ ์ฝ๋์ ๋ํ ํ์ต์ ์งํํ์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ๊ฐ์ธ ๋ธ๋ก๊ทธ๋ฅผ ํตํดย ํ์ธํด ๋ณด์คย ์ ์์ต๋๋ค. ๊ณผ์ ๋ย ์ ์ด๋ ๊ฒย ์ด๋ ต๋์ง์โฆ ใ ใ ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ์ค๋ฌด์ ์ ์ฉํ ์ ์๋ ๊ธฐ์ ๋ค์ ์ตํ ์ ์๋ ์ ์ตํ ์๊ฐ์ด์์ต๋๋ค.
24๋ 12์, ํ ๋๊ฐ์ด,์ ์ฌ์ ์ ์ ์ค๋จ ๊ฒฐ์ โ
๋น๋ก ์๋ ์ ๊ฒฝํํ ๊ฒ์ด์ง๋ง,,, 24๋ 6์์ ์ ์ฌํด์ 12์๊น์ง ํด์ธ ๊ฑฐ๋์ ์ค๊ฐ ํ๋ซํผ ๊ฐ๋ฐ์ ์งํํ์ต๋๋ค.

๊ธฐํ์ ํต์ฌ์ โํด์ธ ๊ฑฐ๋์๋ฅผ ์ด์ฉํ๋ ๊ณ ๊ฐ๋ค์ ์์๋ฃ๋ฅผ ์ฐ๋ฆฌ ํ๋ซํผ์ ํตํด ๊ฑฐ๋ํ๋ฉด ๋๋ ค์ฃผ์.โ์์ต๋๋ค. ํด์ธ ๊ฑฐ๋์์ ์์๋ฃ๋ ์๋นํ ๋ถ๋ด์ค๋ฌ์ด๋ฐ์. ๋น์ ์ํฉ์ ์ฐ๋ฆฌ์ ํ๊ฒ์ธ ์๋น ๊ณ ๊ฐ๋ค์ ์ด๋ฏธ ์ฌ๋ฌ ํ๋ซํผ์ ์ฌ์ฉํ์ฌ ์์๋ฃ๋ฅผ ์ ๊ฐํ๊ณ ์์์ต๋๋ค. ๊ทธ๋ผ์๋ ์ฐ๋ฆฌ๋ ํด๋น ํ๋ซํผ์ ๋ง๋ค์ด๋ณด๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๊ทธ๋ค๊ณผ ์ฐจ๋ณํ ํฌ์ธํธ๋ฅผ ๋ง๋ค์ง ์๊ณ ์ฐ์ ๋ง๋ค๊ฒ ๋๋ ๊ฒ์ด ์คํจ์ ํต์ฌ ์์ธ ์ค ํ๋์ด์ง ์์๊น ์ถ์ต๋๋ค.
ํ๋ก ํธ์๋ ๊ธฐ์ ์คํ์ Next.js
, tailwindCss
, zustand
, tanstack-query
, storybook
๋ฑ์ ์ฌ์ฉํ์ต๋๋ค. ๊ทธ ๋น์์ ์๋ฒ ์ปดํฌ๋ํธ์ Next.js์ SSR์ ๋ํ ์ดํด๋ ๋ถ์กฑํ์ ๋์๊ธฐ์ ๋ง๋ค๋ฉด์ ์ด๊ฒ ๋ง๋์ง, ๊ณ ์ํ๋ ๊ธฐ์ต์ด ๋ฉ๋๋ค. ๋ฆฌ์กํธ ์ฟผ๋ฆฌ์ ์ด๋ป๊ฒ ๋ณํํด์ ์ฌ์ฉํด์ผ ํ๋ ๊ฒ์ธ์ง, ์ธ์ฆ๊ณผ ์ธ๊ฐ๋ ์ด๋ป๊ฒ ํด์ผํ๋์ง ์ถ์์ต๋๋ค. Next.js์ ๋ฏธ๋ค์จ์ด๋ฅผ ํ์ฉํ์ต๋๋ค. ์๋ฒ์์ ์ฟ ํค๋ฅผ ๊ฐ์ง๊ณ ์์ ๋์ ํด๋ผ์ด์ธํธ์์ ์ฟ ํค๋ฅผ ๊ฐ์ง๊ณ ์์ ๋, ๊ฐ์ด ๋ฌ๋ผ ๊ณ ์์ ํ๋ ๊ธฐ์ต์ด ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ค ๊ฒฐ๊ตญโฆ ๋ชจ๋ ์ปดํฌ๋ํธ๋ฅผ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ก ๋ณ๊ฒฝํ์ฌ ์ผ์ ์ ๋ง์ท์ต๋๋ค. Next.js๋ฅผ ์ ํํ ์์ง ๋ชปํ๊ณ ํ๋ก์ ํธ๋ฅผ ๋ฐ๋ก ์์ํ๋๊ฒ ๋ถ์ฐฐ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ด๋ฅผ ํตํด ๊ธฐ๋ณธ์ ์ธ ๊ฐ๋
๋ค๊ณผ ์ฌ์ฉ๋ฐฉ๋ฒ์ ์ตํ๊ณ ์ค๋ฌด์ ์ ์ฉํด์ผ ํจ์ ๊ฒฝํํ์ต๋๋ค. MVP๋ฅผ ์์ฅ์ ์ถ์ํ์์ง๋ง ๋ฐ์์ด ์ฐจ๊ฐ์ ์ต๋๋ค. GA์ hotjar์ ํ์ฉํด์ ์ ์
์ถ์ฒ์ ์ดํ๋ฅ ๋ฑ์ ์ดํด๋ณด๋ฉด์ ๊ฐ์ ์ ์ ์ ์ํ๊ณ ์๋ฆผํจ ๊ธฐ๋ฅ๊ณผ ์ฟ ํฐ ๊ธฐ๋ฅ์ ๋์
ํ์์๋ ๋ถ๊ตฌํ๊ณ ๊ณ ๊ฐ ์์ฒด๊ฐ ์ ์
์ด ์๋ผ, ์ฐ๋ฆฌ๊ฐ ์ํ ์ ์๋ ๊ฒ์ ์ง์คํ๊ธฐ๋ก ํ๋ฉฐ ํด๋น ํ๋ซํผ ์ฌ์
์ ์ ์ ์ค๋จํ์ต๋๋ค.
๋์๋ณด๋ฉด ์ด๊ธฐ ์์ฅ ์ ์ ํ์ง ๋ชปํ ๊ฒ / ํ๋ก๋ํธ ํ์ด๋ผ๋ ์ ์ฒด์ฑ์ ๋ถ์ฌ / ๋ง์ผํ ์ ์ ๋ต์ ๋ถ์ฌ / ๋ฎ์ ์ฌ์ ํ๋ค์ด๋ผ๊ณ ์๊ฐ์ด ๋ญ๋๋ค. ๋น์์๋ ์ด์กฐํจ์ด ์ปธ๊ณ ์ฒ์ ํ๋ ํ๋ก์ ํธ์ธ๋ฐ ํ๋ ๋ชป ์จ๋ณด๋ ๋๋์ด๋ผ ๋ง๋งํ๋ ๊ธฐ์ต์ด ๋ฉ๋๋ค. ํ์ง๋ง ์ด ๊ฒฝํ์ผ๋ก ๋น์ ผ ์์คํ ์ด๋๋ฏผ์ ๋ง๋๋๋ฐ ๋์์ด ๋ง์ด ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ฐ๋ฐ์๊ฐ ๊ธฐํ์ ๋ ์ ๊ทน์ ์ผ๋ก ์ฐธ์ฌ ํด์ผํ๋ค. (์๋ ๋ฆฌ์์ค ์์์ ์ต๋ํ ์๋๊ฐ ํ์ํ๋ค.)
์ง๋ 8๊ฐ์๊ฐ ์ง์์ ์ธ ํ์ธ ํฌ์ธํธ๊ฐ ์์์ต๋๋ค.
โ์ฐ๋ฆฌ๋ ๊ธฐํ์๊ฐ ํ์ํ์ง ์์๊น?โ
โ๊ธฐํ์๊ฐ ์ค๋ฉด ์ด ๋ชจ๋ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋๋ ๊ฒ ์๋๊น?โ
โ์ํํธ์จ์ด๋ฅผ ๋ง๋๋๋ฐ ๊ธฐํ์ด๋ผ๋ โ๋จธ๋ฆฌโ๊ฐ ์์ผ๋ฉด ์ ๋๋ ๊ฒ ์๋๊น?โ
๋น์ ์ฌ๋ด์์ ๋ฐ์ดํฐ ๊ธฐ๋ฐ ์์ฌ๊ฒฐ์ , ๊ฐ์ค ๊ฒ์ฆ์ ์ํ ๊ฐ์ค์กฐ์ฐจ ์์ด ๊ทธ๋ฅ ๊ธฐ๋ฅ์ ๋ง๋ค๊ณ ๋ณด๋... ๊ฐ์ด์ด ๋ต๋ตํ ์ํฉ์ด์์ต๋๋ค. ๊ทธ๋์ "๊ธฐํ์ด ํ์ํ๋ค. ๊ธฐํ์ด ํ์ํ๋ค!"๋ ์๊ฒฌ์ ํผ๋ ฅํ๊ณ ๊ฑฐ๊ธฐ์์ ์์ํ์ฌ ์ฐ๋ฆฌ๋ ํ์ฌ ๊ธฐํ์๊ฐ ํ์ํ์ง ์๋? ๋ผ๋ ์๊ฐ์ผ๋ก ์ด์ด์ก์ต๋๋ค.
ํ์ง๋ง โ์ ์๊ฐ์ด ํ๋ ธ์์ ์๊ฒ ๋์ต๋๋ค.โ "์์์ผ ์์์ผ"์ ์ธ์ณค๋ ์ ๊ฐ ์ ์ ์ํ๋ ๊ฒ์ ์ํฐํด ๋ฐฉ์์ ์ผํ๋ ๋ฐฉ์์ด์๋ค๋ ๊ฒ์ ์๊ฒ ๋์ต๋๋ค.
์ ๊ธฐํ โ ๋์์ธ โ ๊ฐ๋ฐ์ ์์ฐจ์ ์ธ ํ๋ก์ธ์ค๋ฅผ ๊ฑฐ์น๋ฉด์, ๊ฐ๋ฐ์๋ง ์ง์คํ๋ ์ญํ ์ ์ํ์ต๋๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ๋์๊ฐ์ผํ ๋ฐฉํฅ์ ๋ ๋น ๋ฅด๊ณ , ์ ์ฐํ๋ฉฐ, ๊ณ ๊ฐ ์ค์ฌ์ ์ธ ๋ฐฉํฅ์ด์์ต๋๋ค.
์ฐ๋ฆฌ๋ ์๋์ ์ผ๋ก ์ง์๋ฐ๋ ์กฐ์ง์ธ๊ฐ? ์๋๋ฉด ๋ฅ๋์ ์ผ๋ก ์์ง์ด๋ ์กฐ์ง์ธ๊ฐ?
๋น์ฐํ ๋ฅ๋์ ์ผ๋ก ์์ง์ด๋ ์กฐ์ง์ด๊ธฐ์ ๋์ฑ ๊ธฐํ์ ์ ๊ทน ์ฐธ์ฌํ๊ณ ๋์๊ฐ์ผํจ์ ๋ ํ๋ฒ ๊นจ๋ฌ์์ต๋๋ค. ๊ทธ๋์ ๋ฌธ์๋ฅผ ์์ฑํ์ฌ ๋๋ฃ๋ค์๊ฒ ๊ณต์ ํ๊ณ ํ๋ก๋ํธํ์ ๋ง๋ค๊ธฐ ์ํด ์๋ํ์ผ๋ ๋ํ๋์ผ๋ก๋ถํฐ ๊ธ์ ์ ์ธ ๋ต๋ณ์ ๋ฃ์ง ๋ชปํ์ผ๋ ๋ ์ข์ ๋ฐฉํฅ์ผ๋ก ๊ฐ๊ณ ์๋ค๊ณ ์๊ฐ์ด ๋ญ๋๋ค.

[์ฐธ๊ณ ๋ ธ์ ๊ณต์ ํ์ด์ง]
์ด๋ป๊ฒ ๊ฐ๋ฐ์ ์ฆ๊ธธ ์ ์์๊น?โ
์ ๋ฌด๋ฅผ ํ๋ฉด์ ์คํธ๋ ์ค์ ์ถ์ฒ๋ฅผ ๊ณฐ๊ณฐ์ด ๋์ด์ผ๋ณด๋ฉด 9ํ ์ ๋๋ ๊ณผ๊ฑฐ์ ํ์ฅ์ฑ์ ๊ณ ๋ คํ์ง ์๊ณ ๋์๋งํ๋๋ก ์์ฑํด ๋์ ์ฝ๋โฆ๋ผ๋ ๊ฒ์ ์๊ฒ ๋์ต๋๋ค. ๊ฐ์ฌํ๊ฒ๋ ์์ง ํ๋ก ํธ์๋ ๊ฐ๋ฐ ๋๋ฃ๊ฐ ์์ด ํผ์ ๋ท๊ฐ๋น์ ํ๊ณ ์์ต๋๋ค. ๋ด ์ฝ๋๋ก ์ธํด ๋๋ฃ๋ฅผ ํ๋ค๊ฒ ํ์ง ์์ ์ ์์์ด ์ ๋ง ๋คํ์ด๋ค๋ ์๊ฐ์ดโฆ ๋ญ๋๋ค. ๊ทธ๋์ ์ง๊ธ ์ด ์๊ธฐ์ ๊ฒฝ๊ฐ์ฌ์ ๊ฐ์ง๊ณ ์ฝ๋์ ๊ทผ๊ฑฐ๋ฅผ ๊ณ ๋ฏผํด ๋ณด๋ฉด์ ์์ฑํ๋ ์ฐ์ต์ด ๋ฐ๋์ ํ์ํ๋ค๊ณ ๋๋๋๋ค.
๋์๋ณด๋๋ฅผ ๋ง๋ค๊ณ ์๋ ์ง๊ธ,,, ์ด๋ฐ ์๊ตฌ์ฌํญ์ ๋ฐ๊ณค ํฉ๋๋ค.
โ์ด๋ฐ ๊ธฐ๋ฅ์ ์ด๋ ๊ฒ ์์ ํด ์ฃผ์ธ์.โ
โ์ด๋ฐ ๊ธฐ๋ฅ์ ์ด ๊ธฐ๋ฅ์ ๋ถ์ฌ์ฃผ์ค ์ ์์ผ์ธ์?โ
๊ณ ๊ฐ์ ๊ณ์ข์ ํฌ์ง์ ๊ณผ ์ค๋๋ฅผ ํ ๋์ ํ์ ํ ์ ์์ผ๋ฉด ์ข๊ฒ ์ด์. ์...
๊ทธ๋ํ ํํฐ๋ง ๋ฒํผ ํด๋ฆญํ๋ฉด 1์ด ์๋ค๊ฐ ์์ง์ด๋๋ฐ ์ด๊ฑฐ ์ ์ด๋ฌ์ฃ ?
์์ ๊ฐ์ ์๊ตฌ ์ฌํญ์ ๋ํด ํ์ ์๊ฐ์ ์์๋๋ ์๊ฐ์ ๊ณต์ ํฉ๋๋ค. ๋ด๊ฐ ๊ณต์ ํ ์ผ์ ๋ง๊ฐ์ ์งํค์ง ๋ชปํ ๋, ์์ฌ์ด ๋ง์์ด ๋ค๋๋ผ๊ณ ์... ์ฃ์กํ๊ธฐ๋ ํ๊ณ ๋๊ฐ ๋ญ๋ผ๊ณ ํ์ง ์์๋ ๊ฐ์ธ์ ์ผ๋ก ์ผ์ ์ ๊ผญ ์งํค๋ ์ต๊ด์ ๊ฐ์ถ๊ธฐ ์ํด ๋ ธ๋ ฅํ๊ณ ์๋๋ฐ ์ ์ ๋๋ ๋ชจ์ต์ด ์ค์ค๋ก ํ๋ค์์ต๋๋ค.
๋ค์ ๋์๊ฐ, ๊ฐ๋ฐ์ ์ฆ๊ธฐ๋ ค๋ฉด ๊ฐ๋ฐ์ ์ํด์ผ ํจ์ ๋๊ผ์ต๋๋ค. ๊ฐ์ง ์๊ฐ ๋ ๊ฐ์ง๋ ๊ฒ๊ณผ ๋์ผํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋์ด์ผ๋ณด๋ฉด ์ ๊ฐ ์ข์ํ๋ ๋๊ตฌ๋ ์ฒด์ค, ๋๋ผ ๋ชจ๋ ์ฒ์์๋ ์ฌ๋ฏธ์์์ง๋ง ์๊ฐ์ด ์ง๋๊ณ ๊ทธ ์์์ ๊ท์น์ ์ดํดํ๊ณ ์์ ๋ง์ ๊ท์น์ ๋ง๋ค์ด ๊พธ์คํ ์ฐ์ตํด ๋๊ฐ๋ฉด์ ์ค๋ ฅ์ด ๋ ๋์์์ผ ๋ ์ฌ๋ฐ์ด์ก๋ ๊ธฐ์ต์ด ์์ต๋๋ค. ๊ฐ๋ฐ๋ ๋์ผํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ชปํ ๋ ์ฆ๊ธฐ๋ ๊ฒ์ ์ฌ์น๋ผ๊ณ ์๊ฐ์ด ๋ค์๊ณ ์ญ์ค์ ์ผ๋ก ์ฆ๊ธธ ์๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋ผ ์ด๋ป๊ฒ ํ ๊ฒ์ธ๊ฐ??
์ฃผ์ด์ง ํ๊ฒฝ์์ ์ ๊ฐ ํ ์ ์๋ ๊ฒ์ ํ
์คํธ ์ฝ๋ ๋์
์ด์์ต๋๋ค. ํญํด๋ฅผ ํตํด ํตํฉ ํ
์คํธ, ๋จ์ํ
์คํธ, e2e ํ
์คํธ์ ๋ํ ํ์ต๊ณผ ๊ณผ์ ๋ฅผ ์งํํ์ต๋๋ค. TDD์ ๋ํด์๋ ํ์ต์ ์งํํ์์ฃ . ์ด์ ์ด๋ฐ ์ง์์ ์ค๋ฌด์ ์กฐ๊ธ์ฉ ์ ์ฉํ๋ฉฐ ๋ฆฌํฉํฐ๋ง์ ์งํํด๋ณด๋ ค๊ณ ํฉ๋๋ค. ํ
์คํธ ์ฝ๋ ๋์
์ผ๋ก ํจ์๋ฅผ ๋ณด๋ค ์์ํ๊ฒ ์์ฑํ๊ฒ ๋๊ณ ๊ฐ ํจ์์ ์ญํ ์ ํ๋ฒ ๋ ๊ณ ๋ฏผํ ์ ์๊ฒ ํ๋ ๊ฒ์ด ๊ฐ๋
์ฑ ์ข์ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๊ฒ ๋์์ค ๊ฑฐ๋ผ๊ณ ์๊ฐ์ด ๋ญ๋๋ค.
3์ ์ค์, ๋๋์ด ์ฒ์์ผ๋ก ์ค๋ฌด์ ํ ์คํธ ์ฝ๋๋ฅผ ๋์ ํ๊ฒ ๋๊ณ ๋ณ๊ฑฐ ์๋ ์ ์์ง๋ง ๋๋ฆ ๊ธฐ๋ถ ์ข๊ฒ ํด๊ทผํ๋ ๊ธฐ์ต์ด ๋ฉ๋๋ค. ์ด๋๋ฏผ ํ๋ก์ ํธ์์ ์ฌ์ฉ์์ ๊ถํ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ๋ณด์ด๋ ๋ถ๋ถ๋ค์ด ์์ต๋๋ค. ๊ถํ์ ๋ํด ์๊ตฌ์ฌํญ์ด ๋์ด๋๋ฉด์ ์ผ์ผ์ด ํ์ธํ๋ ๊ฒ๋ค์ด ๋ฒ๊ฑฐ๋ก์์ก์ต๋๋ค. ๊ทธ๋์ ์ด๋ฅผ ํ ์คํธ ์ฝ๋๋ก ์์ฑํ์์ต๋๋ค.
ํตํฉ ํ ์คํธ๋ฅผ ํ์ฉํ์ต๋๋ค. ๋ฉ์ธ ํ์ด์ง์ ์ฌ๋ฌ ๋๋ฉ์ธ์ ๋์์ ํ ์คํธํ๋ ค๊ณ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์์ฑํ๋ฉด์ zustand์ store๋ฅผ ๋ชจํน ํ๋ ๋ฐฉ๋ฒ, ํ์ ์ปดํฌ๋ํธ๋ ๊ฒ์ฌํ์ง ์๊ณ ํด๋น ์ปดํฌ๋ํธ๋ง ๊ฒ์ฌํ๋ ๋ฒ ๋ฑ ์๋กญ๊ฒ ์๊ฒ ๋์ต๋๋ค. ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค. ํผ๋๋ฐฑ์ ์ธ์ ๋ ํ์์ ๋๋ค!! (์๋ง ๋ชจ๋ ์ฝ๋ ๋ผ์ธ์ ํผ๋๋ฐฑ์ด ์์ ๋งํ ์์ค์ ์ฝ๋์ด์ง๋ง ๊ณต๊ฐํฉ๋๋ค..) ๋๊ตฌ๋ ์์ ๋จ๊ณ๋ ์์ผ๋๊น์! ใ ใ
// ์ฌ์ด๋ ๋ค๋น๊ฒ์ด์
์์ญ ( ์ฌ์ฉ์ ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๋ฐ๋ฅธ UI ๋ ๋๋ง ๋ฐ ์ํธ ์์ฉ)
// ์ฌ์ฉ์ ๋ก๊ทธ์ธ ๋ฐ ํ์๊ฐ์
๊ธฐ๋ฅ ํ
์คํธ
import { mockSessionStore } from "@/__mock__/mockZustandStore";
import { render, renderHook, screen } from "@testing-library/react";
import { useState } from "react";
import { MemoryRouter } from "react-router-dom";
import { Sidebar } from "@/pages/home";
import { VIEW } from "@/shared/lib";
vi.mock("../pages/home/ui/sidebar/AccountsSubNav.tsx", () => ({
default: () => <div data-testid="mock-heavy-child">Mocked HeavyChild</div>,
}));
describe("์ฌ์ด๋๋ฐ UI ํ
์คํธ", () => {
it("์ด๋๋ฏผ์ผ ๊ฒฝ์ฐ ์ฌ์ด๋ ๋ฐ UI๊ฐ ๊ถํ์ ๋ง๋ ์์๋ค์ด ์กด์ฌํ๋์?", async () => {
mockSessionStore({
access_token: "admin",
refresh_token: "admin",
access_token_duration: 3600,
role: "administrator",
token_type: "Bearer",
});
const { result } = renderHook(() => useState(false));
render(
<MemoryRouter>
<Sidebar
sidebarOpen={result.current[0]}
setSidebarOpen={result.current[1]}
/>
</MemoryRouter>,
);
// TODO : ์ด๊ฒ ์ต์ ์ ์๋๊ฒ ์ง๋ง ๋ ์ข์ ๋ฐฉ๋ฒ์ด ์์๊น?
expect(screen.getByText(VIEW.HOME)).toBeInTheDocument();
expect(screen.getByText(VIEW.PNL_TRANKING)).toBeInTheDocument();
expect(screen.getByText(VIEW.ORGANIZATIONS)).toBeInTheDocument();
expect(screen.getByText(VIEW.ACCOUNTS)).toBeInTheDocument();
expect(screen.getByText(VIEW.USERS)).toBeInTheDocument();
expect(screen.getByText(VIEW.TRANSFER_RECORDS)).toBeInTheDocument();
expect(screen.getByText(VIEW.RISK_MANAGEMENT)).toBeInTheDocument();
expect(screen.getByText(VIEW.DASHBOARDS)).toBeInTheDocument();
});
it("์คํํ์ผ ๊ฒฝ์ฐ ์ฌ์ด๋ ๋ฐ UI๊ฐ ๊ถํ์ ๋ง๋ ์์๋ค์ด ์กด์ฌํ๋์?", () => {
mockSessionStore({
access_token: "admin",
refresh_token: "admin",
access_token_duration: 3600,
role: "staff",
token_type: "Bearer",
});
const { result } = renderHook(() => useState(false));
render(
<MemoryRouter>
<Sidebar
sidebarOpen={result.current[0]}
setSidebarOpen={result.current[1]}
/>
</MemoryRouter>,
);
expect(screen.getByText(VIEW.HOME)).toBeInTheDocument();
expect(screen.getByText(VIEW.PNL_TRANKING)).toBeInTheDocument();
expect(screen.getByText(VIEW.ORGANIZATIONS)).toBeInTheDocument();
expect(screen.getByText(VIEW.ACCOUNTS)).toBeInTheDocument();
expect(screen.getByText(VIEW.USERS)).toBeInTheDocument();
expect(screen.getByText(VIEW.TRANSFER_RECORDS)).toBeInTheDocument();
expect(screen.getByText(VIEW.RISK_MANAGEMENT)).toBeInTheDocument();
expect(screen.getByText(VIEW.DASHBOARDS)).toBeInTheDocument();
});
it("์ ์ ์ผ ๊ฒฝ์ฐ ์ฌ์ด๋ ๋ฐ UI๊ฐ ๊ถํ์ ๋ง๋ ์์๋ค์ด ์กด์ฌํ๋์?", () => {
mockSessionStore({
access_token: "admin",
refresh_token: "admin",
access_token_duration: 3600,
role: "user",
token_type: "Bearer",
});
const { result } = renderHook(() => useState(false));
render(
<MemoryRouter>
<Sidebar
sidebarOpen={result.current[0]}
setSidebarOpen={result.current[1]}
/>
</MemoryRouter>,
);
expect(screen.getByText(VIEW.HOME)).toBeInTheDocument();
expect(screen.getByText(VIEW.DASHBOARDS)).toBeInTheDocument();
});
});
์ด๋ฅผ ์์์ผ๋ก ํ์ฌ์ ์ค์ํ ๋ก์ง์ ํ ์คํธ ์ฝ๋๋ก ์์ฑํด๋ณด๊ธฐ ์์ํ์ต๋๋ค. 4์ ์ฒซ์งธ์ฃผ์ ์ ๋ฌด ์ ์ฒด AUM ๊ทธ๋ํ ๋ฐ ์ธ์ฆ ๋ถ๋ถ์ ํ ์คํธ ์ฝ๋๋ฅผ ๋์ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
FSD (Feature-Sliced Design)๋ฅผ ์ ์ฉํด๋ณด๊ณ ์์ด์โ
1์์ ํญํด๋ฅผ ํตํด FSD๋ฅผ ์๊ฒ ๋๊ณ 2์๋ถํฐ ์ฐจ์ธฐ ํ๋ก์ ํธ์ ์ ์ฉํด๋ณด๊ณ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ๊ณ ํ์๋ฉด ๋์์ด ๋ ์ ์์ ๊ฒ ๊ฐ์์. FSD ์ ์ฉ๊ธฐ 1ํธ ๊ณ์ ์งํํ๊ณ ์๊ณ ํ์ฌ๋ 2ํธ ๋ธ๋ก๊ทธ๋ฅผ ์์ฑํ๊ธฐ ์ํด ํ์ตํ๊ณ ์์ต๋๋ค.
map ๋งค์๋๋ Array.prototype์๋ง ์์ง ์๋ค. (ํฌ๋ก์ค ๋ธ๋ผ์ฐ์ง ์ด์)โ
์ด๋ ๋ , ์ฌ๋ด ๋ฉ์ ์ ์ ๋๋ฃ์ ํ๊ทธ๊ฐ ์์์ต๋๋ค.

๋ฌธ์ ์ ์๋ฅผ ์ํด ํด๋น ๋ฒ๊ทธ ํ๊ฒฝ์ ์ฌํํด ๋ณด๋ ๋ฐ์คํฌํ์์ ๋ชจ๋ฐ์ผ Viewport๋ก ์ถ์ํ ๊ฒฝ์ฐ๋ ์ ์ ์๋ํ์ง๋ง ๋ชจ๋ฐ์ผ์์๋ ๋ณด์ด์ง ์๋ ๊ฒ์ ํ์ธํ์ต๋๋ค. ๋ํ ๋ธ๋ผ์ฐ์ ์ฌํ๋ฆฌ์์ ํด๋น ํ์ด์ง๊ฐ ๋์ํ์ง ์๋ ๊ฒ์ ํ์ธํ์ฃ .
์๋ฌ๋ฅผ ๋๋ฒ๊น ํ๊ธฐ ์ํด ๋ชจ๋ฐ์ผ ์๋ฌ๋ฅผ ํ์ธํ ์ ์๋ ๋๋ฒ๊ฑฐ๋ฅผ ์ฌ์ฉํด์ผ ํ์ต๋๋ค. ๊ตฌ๊ธ์ ๊ฒ์ํด ๋ณด๋ ๋ชจ๋ฐ์ผ ๋๋ฒ๊ฑฐ (chrome://inspect/#devices)๊ฐ ์กด์ฌํ๊ณ ํด๋น ๋ชจ๋ฐ์ผ ๋๋ฒ๊ฑฐ๋ฅผ ํ์ฉํ์ฌ console.log()๋ฅผ ํ์ธํ์์ต๋๋ค.
์๋ฌ ๋ฉ์์ง๋ฅผ ํ์ธํด ๋ณด๋ ํ ์ด๋ธ ํค๋ ์ฝ๋์ ๋ฌธ์ ๊ฐ ์๋ค๋ ๊ฒ์ ์๊ฒ ๋์ต๋๋ค. ํค๋๋ฅผ ํํฐ๋งํ๋ ๋ก์ง์ด ๋ฌธ์ ์์ฃ . ์ฐ์ ํํฐ๋ง ๊ธฐ๋ฅ์ ์ ์ธํ๊ณ hotfix๋ฅผ ๋ง๋ค์ด ๋ฐฐํฌ๋ฅผ ์งํํ๊ณ main์ develop์ ๊ฐ๊ฐ merge๋ฅผ ์งํํ์์ต๋๋ค.
์ฐ์ Filter ์ปดํฌ๋ํธ๋ฅผ ์ ๊ฑฐํ๋ ์ ์ ์๋ํ๋ ๊ฒ์ ํ์ธํ์ผ๋ ๋ฒ์๊ฐ ์ข์์ก์ต๋๋ค.
const PnlTable = () => {
return (
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id} className="text-center font-bold">
<div className="flex w-full items-center justify-center gap-2">
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
{header.column.getCanFilter() ? (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className="flex items-center">
<ChevronDown />
</button>
</DropdownMenuTrigger>
{/* HERE : ๋ชจ๋ฐ์ผ์์ ์๋ฌ๊ฐ ๋จ๋๋ฐ ๋ฐ์คํฌํ์์๋ ์ ์ ์๋ํจ... */}
<DropdownMenuContent align="end">
<Suspense fallback={"error in Filter Component"}>
{/* HERE : ์๋์ Filter ์ปดํฌ๋ํธ ์ ๊ฑฐํ์ฌ ์ฐ์ ๋ฌธ์ ํด๊ฒฐ */}
<Filter column={header.column} />
</Suspense>
</DropdownMenuContent>
</DropdownMenu>
) : null}
</div>
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>...</TableBody>
</Table>
);
};
์ฐ์ Filter ์ปดํฌ๋ํธ๋ฅผ ์ฃผ์ ์ฒ๋ฆฌํ์ฌ ์์๋ก ํด๊ฒฐํ ํ ์์ธํ ์ดํด๋ณด๋
// HERE!
function Filter({ column }: { column: Column<any, unknown> }) {
return (
<>
{Array.from(
column
.getFacetedUniqueValues()
.keys()
.map((option) => {
return <>123</>;
}),
)}
</>
);
}
map ๋ฉ์๋๊ฐ ์ด์ํจ์ ๋ฐ๊ฒฌํ์ต๋๋ค. ์์ ์ฝ๋๋ ๊ณต์ ๋ฌธ์์ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ์ฌ ๊ตฌํํ ๊ฒ์ธ๋ฐ,,, ํด๋น ํ์ ์ ๋ณด๋,
column.getFacetedUniqueValues(); // Type: Map<any, number>
Map ์๋ฃ๊ตฌ์กฐ์๋ keys ๋ฉ์๋๊ฐ ์กด์ฌํฉ๋๋ค. MDN ๊ณต์๋ฌธ์๋ฅผ ํตํด ํ์ธํด๋ณด๋ keys ๋งค์๋๋ ์๋ก์ด map interator ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค๊ณ ํฉ๋๋ค. ์ดํฐ๋ ์ดํฐ๋ฅผ ๋ฐํํ๊ณ ์์์ต๋๋ค!
๊ทธ๋ผ iterator์๋ map ๋ฉ์๋๊ฐ ์์๋ ๊ฒ์ธ๊ฐ?
๊ทธ๋ ์ต๋๋ค. map ๋ฉ์๋๋ ๋์ผํด๋ณด์ด์ง๋ง, ๋๊ฐ์ง๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
Iterator ๊ฐ์ฒด์ ๋ฉ์๋์ธ map์ Limited availability yet์ด๋ผ๊ณ ํฉ๋๋ค. ์ฌํ๋ฆฌ์์ ์์ง ํธํ๋์ง ์๋๋ค๊ณ ํฉ๋๋ค. ๊ทธ๋์ ๋ชจ๋ฐ์ผ ๋ฒ์ ์์ ํด๋น ๊ธฐ๋ฅ์ด ์๋ ํ์ด์ง์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค๋ ๊ฒ์ ์๊ฒ ๋์ต๋๋ค.

๊ธฐ์กด์๋ ๋ชจ๋ ๋ฉ์๋๋ฅผ ํตํด ๋์จ ๊ฒฐ๊ณผ๋ฅผ ๋ฐฐ์ด๋ก ๋ฐํํ์๋ค๋ฉด, map์ Array ํ๋กํ ํ์ ์ map์ ์ฌ์ฉํ๋๋ก ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ฌ ์ค๋ฅ๋ฅผ ํด๊ฒฐํ์ต๋๋ค.
๋ฆฌํ๋ ์ ๋์ ์ ๋ฐ๋ฅธ API ์ค๋ณต ํธ์ถ ๋ฌธ์ โ
ํ์ฌ ํ๋ก์ ํธ์์๋ react-router-dom์ loader ํจ์๋ฅผ ํ์ฉํ์ฌ ํ์ด์ง์ ๋ํ ๊ถํ ์ฒ๋ฆฌ์ prefetch ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ค๋ ๋ก์ง์ ์ถ๊ฐํ์ฌ ํ ๊ณณ์์ ๊ด๋ฆฌํ๊ณ ์์ต๋๋ค.
export const router: ReturnType<typeof createBrowserRouter> = createBrowserRouter([
{
//public route
path: publicPathKeys.root,
element: <DefaultLayout />,
//HERE!
loader: DefaultLayoutLoader.AuthLayoutPage,
errorElement:<ErrorPage>,
children:{
...
}},
{
// private route
path: privatePathKeys.root,
element: <AuthLayout />,
//HERE!
loader: AuthLayoutLoader.AuthLayoutPage,
errorElement:<ErrorPage>,
children:{
...
},
}
])
loader ํจ์๋ฅผ ํ์ฉํ ์ด์ ๋ Cumulative Layout Shift๋ฅผ ์ค์ด๊ธฐ ์ํจ์ด์์ต๋๋ค. react-router-dom ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๊ฐ ๋ฐ์์ ์ง ๊ฒฝ์ฐ ํด๋น ํ์ด์ง๋ฅผ ๋ ๋๋ง ํ๋ ๋ก์ง์ ์คํ์ํค๊ธฐ ๋๋ฌธ์ ๋ค์ ๋๋ฆฌ๊ฒ ๋ณด์ด๋๋ผ๊ณ ์ฌ์ฉ์๋ ๋ฐ์ดํฐ์ UI๊ฐ ๊ฒฐํฉ๋ ์ํ๋ก ๋ณผ ์ ์๊ฒ ๋ฉ๋๋ค.
ํ์ฌ ํ๋ก์ ํธ์์ axios๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ axios์ ๊ธฐ๋ฅ ์ค ํ๋์ธ ์์ฒญ๊ณผ ์๋ต์ ๊ฐ๋ก์ฑ๋ ๋ฐฉ์์ผ๋ก 401 ์๋ฌ๊ฐ ์์ ๋, ์ก์ธ์ค ํ ํฐ์ ์ฌ๋ฐ๊ธํ๋ ๊ณผ์ ์ ํตํด ์๋ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ์ต๋๋ค.
ํ์ง๋ง ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ก๊ทธ์ธ์ ํ๋ฉด ์ฌ๋์ผ๋ก ์๋ฆผ์ด ์ค๋ ๊ตฌ์กฐ์ ๋๋ค. ์ก์ธ์ค ํ ํฐ์ด ๋ง๋ฃ๋ ์ดํ ์๋ ๋ก๊ทธ์ธ์ด ๋์ด๋ ์ฌ๋์ผ๋ก ์๋ฆผ์ด ์ต๋๋ค. ๋ฌธ์ ๋ ์ก์ธ์ค ํ ํฐ ๊ฐฑ์ ์ ํ๋ฉด 3๋ฒ์ ์๋ฆผ์ด ๊ฐ๋ ๊ฒ์ธ๋ฐ ์ฐ์ ์ ๊ทธ๋ฐ์ง ํ์ ํด ๋ณด๋ ๋ฉ์ธ ํ์ด์ง์ 3๊ฐ์ API๋ฅผ ํธ์ถํ์ต๋๋ค.
ํ์ด์ง ์ง์ ๋ ์ธ์ฆ ๊ฒ์ฆ๊ณผ prefetch ํ๋๋ก ํด์ ํ์ด์ง๊ฐ ๋ณด์ผ ๋ CLS๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํด์ ์ฌ์ฉํ๋๋ฐ ๋ฆฌํ๋ ์ ํ ํฐ์ ๋์ ํ๊ณ ์๋ก์ด ์ก์ธ์ค ํ ํฐ์ ๋ฐ๊ธ๋ฐ์ ๋ ์ฌ๋์ผ๋ก 3๋ฒ ๋ก๊ทธ์ธ ์์ฒญ์ด ๋ณด๋ด์ง๋ ๊ฒ์ ์๊ฒ ๋์ด ๊ทธ๋์ ์ด ๋ถ๋ถ์ด ์๋ prefetchQuery์๋๋ฐ fetchQuery๋ก ๋ฐ๊ฟ์ ์๋ฌ๋ฅผ ๋ฆฌํดํ๋๋ก ํด์ ์ด๋ interceptor๊ฐ ์คํ๋๋๋ก ํด์ 1๋ฒ๋ง ๊ฐ๊ฒ ํ๋๋ฐ ์ด ๋ฐฉ๋ฒ๋ ๊ด์ฐฎ์ ๋ฐฉ๋ฒ ๊ฐ์๋ฐ ์ ๋ต์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค. 4์์ ์ ๋๋ก ํด๊ฒฐํ๊ณ ๋์ด๊ฐ๋ ค๊ณ ํฉ๋๋ค.
Git ์ธ์ ์ ๋ง๋ค๊ณ ๊ณต์ ํ๊ธฐ๋ก ํ๋ค.โ

ํจ๋ฉ์ ๊ฐ๋ฐ ๋ฌธํ๋ฅผ ๋ง๋ค์ด ๋๊ฐ๋๋ฐ ํ์ ์ฐ๊ธฐ๋ก ํ์ต๋๋ค. ๋ฐฑ์๋ ๋๋ฃ์๊ฒ Git์ ์๋ฆฌ์ ์ฌ์ฉ๋ฒ์ ๊ณต์ ํ๋ ์๊ฐ์ ๊ฐ์ก์ต๋๋ค. 2์ ์ค์์ ์ฝ 3์ฃผ๊ฐ ์งํํ๋ค๊ฐ ์ต๊ทผ ๋ฐ๋ป์ ๋ชปํ์ง๋ง 4์์๋ ๋ค์ ์งํํด์ ๋ง๋ฌด๋ฆฌํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
๋ณด์์ ๊ฒฝ๊ฐ์ฌ์ ๊ฐ์ง์. ํด๋ผ์ด์ธํธ ์ฌ์ด๋์ ์ทจ์ฝ์ฑ์ ๋ํดโ
25๋ 1๋ถ๊ธฐ์ ๋ฐ์ด๋นํธ ์ฌ๊ฑด ๋ฐ ๊ฐ์ ์์ฐ ์ ๊ณ์ ํด์ปค์ ๊ณต๊ฒฉ์ด ์๋นํ๋ ๊ฒ์ ์๊ฒ ๋์ต๋๋ค. ํผ๋ถ๋ก ๋ง์ด ๋๋ผ๋ฉฐ ๋ณด์์ด๋ผ๋ ํค์๋์ ๊ด์ฌ์ ๋๊ธฐ ์์ํ์ต๋๋ค. ํจ๋ฉ์ ๋น์ ผ ์์คํ ๊ณผ ์ถํ์ ์งํํ ์ฌ๋ฌ ํ๋ก์ ํธ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์์ ๋์ํ๊ฒ ๋ ๊ฒ์ธ๋ฐ ์ ์์ ์ธ ํด์ปค๋ค์ ์ฃผ์ ํ์ผ์ด๊ธฐ ๋๋ฌธ์ ๋ฐ๋์ ๋ณด์์ ์ฐ์ ์์๋ฅผ ๋์ฌ ๊ฐ๋ฐํด์ผ๊ฒ ๋ค๊ณ ์๊ฐํ์ต๋๋ค. ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ก์ ์น ๋ธ๋ผ์ฐ์ ์ ๋๊ตฌ๋ณด๋ค ์นํด์ง๋ ค๊ณ ํฉ๋๋ค. ๋ณด์ ๊ด๋ จํ ๊ฐ๋ ์ ํ๋์ฉ ์ดํดํ๊ณ ๋์ด๊ฐ๋ ค๊ณ ํฉ๋๋ค.
2๋ ๋ง์ ์ฌ๋ ๋ฆฝ์ ํ์ต๋๋ค.โ
์ทจ์ ์ค๋น๋ฅผ ํ๋ฉฐ ๋ถ๋ชจ๋ ๋์ ์ ์ ๋ค์ด๊ฐ๊ฒ ๋์ต๋๋ค. 24๋ 6์ ์ทจ์ ์ดํ ์ฌํด ์ข์ ๊ณต๊ฐ์ ๋ฐ๊ฒฌํ๊ณ ๋ค์ ๋ ๋ฆฝ์ ์์ํ์ต๋๋ค. ๋ถ๋ชจ๋๊ณผ ํจ๊ป ์ง๋ด๋ฉด ์ข์ ์ ์ด ๋๋ฌด ๋ง์ง๋ง, ์ฃผ๋์ ์ผ๋ก ์ถ์ ๋ง๋ค์ด๊ฐ๊ณ ์ถ์๋ ๋ง์์ด ๋๋ฌด ์ปค์, ์ทจ์ ํ๊ณ 6๊ฐ์์ด ์ง๋ ๋ ๋ฆฝํ๊ฒ ๋์ต๋๋ค. ๋๋ฌด ๊ฐ์ฌํ๊ฒ ์ด๋ฆฐ์ด ๋๊ณต์ ์ฃผ๋ณ์ ๋๋ฌด ์ ๋ ดํ ๋ฐฉ์ ์ฐพ์ ์ด์ฌํ๊ฒ ๋๊ณ ์๋นํ ๋ง์กฑํ๋ฉฐ ์ง๋ด๊ณ ์์ต๋๋ค. ๋งค์ผ ์ด๋ํ ์ ์์์ ๊ฐ์ฌํ์ฃ !
๊ตํ ๋๋ผ ๋ฐ์ฃผ ๋ค์ ์์โ

์ด๋ฆด ์ , ๋ถ๋ชจ๋์ ๋ฐ๋ผ ๊ตํ๋ฅผ ๋ค๋ ๊ณ ๋๋ผ๊ณผ ๋ฒ ์ด์ค๋ฅผ ํ๋ค์๊ฒ ๋ฐฐ์ธ ์ ์์์ต๋๋ค. ๋ฒ์จ ๊ทธ๊ฒ 15๋ ์ ๋๊ฐ ์ง๋ ์ด๋์ 29์ด์ด ๋์๋ค์โฆ ์๊ฐ์ด ์ฐธ ๋น ๋ฅธ ๊ฒ ๊ฐ์ต๋๋ค. ๋ฌด์์ธ๊ฐ ๊พธ์คํ ํ๋ค๋ ๊ฒ์ ์ฝ์ง ์์ ๊ฒ ๊ฐ์ง๋ง, ์ ์๊ฒ ๋ช ์๋๊ฒ ์ค๋ซ๋์ ๋์ง ๋ชปํ ๊ฒ ์ค ํ๋์ ๋๋ค... ๋๊ณ ์ถ์๋ ์ ์ด ์๋๋ฃฉ ๋นฝ๋นฝ์ ๋๋ค. ๋ค์ ์ฃผ๋ง์ด๋ฉด ๋ฉํธ๋ก๋ ์ฐ์ต์ ์์ํ๊ฒ ๋์ต๋๋ค. ์ด๋ ๋ถ์ผ๋ ๊ธฐ๋ณธ๊ธฐ๋ ๊ทธ ์ฌ๋์ ์ฑ์ฅ ๊ฐ๋ฅ์ฑ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ผ๋งฅ ์ํตํ๊ฒ ๊ฐ๋ฐ์์ ๊ธฐ๋ณธ๊ธฐ์ ์ง์คํด ๋ณด๊ฒ ์ต๋๋ค!
์ด๋ ์ํ ๋ฅ๋ ฅ ํฅ์, ํฑ๊ฑธ์ด 2๊ฐ โ 8๊ฐโ
์ ์๋์ ์ผ๋ก ๋ฑ์ด ์ฝํ์์ต๋๋ค. ๊ทธ๋์ 1๋ถ๊ธฐ์๋ ํฑ๊ฑธ์ด์ ์ง์คํ์ต๋๋ค. ํ์ฌ ๊ฑด๋ฌผ ์งํ์ ์๋ ํฌ์ค์ฅ์์ ์ฃผ๋ก ์ฐ์ตํ๊ณ ๋ ํ ๋ค์ด๋ถํฐ ๋ค์ ์์ํด์ ๋์ด์ฌ๋ ธ๊ณ 3๊ฐ์ ๋์ ํ ๊ฒฐ๊ณผ ํ์ฌ๋ 8๊ฐ ์ ๋ ํ ์ ์๊ฒ ๋์ต๋๋ค. 2๋ถ๊ธฐ์๋ ์กฐ๊ธ ๋ ์์ธ์ ์ ๊ฒฝ ์จ์ 10๊ฐ ์ ๋ ํ๋ ๊ฒ ๋ชฉํ์ ๋๋ค. ๋ณด๋ค ์ฒ์ฒํ ์ ํํ๊ฒ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
์ดํ์ ํ์ ํธ๋ ์ปค ์ฌ์ฉ ํ๊ธฐโ
24๋ ์ฐ๋ง ํ๊ฐ๋ฅผ ํตํด ๊ธฐ๋ณธ๊ธฐ๋ฅผ ์์์ผ๊ฒ ๋ค๋ ์๊ฐ์ผ๋ก ์งํํ ํญํด ํ๋ฌ์ค, 1๋ถ๊ธฐ์ ํญํด ํ๋ฌ์ค๋ฅผ ์งํํ๋ฉด์ ์๊ฐ ๊ด๋ฆฌ์ ์ด๋ ค์์ ๋๊ผ๊ณ ์ฃผ์ด์ง ํ๋ฃจ์ ๋ ๋ง์ ๊ฒ๋ค์ ํ๊ธฐ ์ํด์ ์๊ฐ์ ์ด๋ป๊ฒ ์ฌ์ฉํ๋์ง ๊ธฐ๋กํ๋ ์ต๊ด์ด ํ์ํ๋ค๋ ๊ฒ์ ์ ์คํ ๋๊ผ์ต๋๋ค.
2์ 3์, ํ์ ํธ๋์ปค๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋๋ ์ ์ ์๊ฐ์ ๊ธฐ๋กํ๋ฉด์ ๋ญ๋นํ ์๊ฐ์ด ์ผ๋ง๋ ๋ง์์ง์ ๋ํ ๊ฐ๊ฐ์ด ์๊ธด๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ ๊ฒ ์ ์พํ ์ผ์ ์๋์์ต๋๋ค. ๋งค์ผ ๋์ ์คํจ๋ฅผ ๋ง์ฃผํด์ผ ํ์ต๋๋ค. ๊ทธ๋ก ์ธํด 1๋ถ๊ธฐ์ ๋ด๊ฐ ์ผ๋ง๋ ์๊ฐ์ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ์ง ๋ชปํ๋์ง๋ฅผ ์๊ฒ ๋๊ณ ํ๊ณ ํ ์ ์๊ฒ ๋์ต๋๋ค. ํ์ง๋ง ๋ญ๋นํ ์๊ฐ๋ ์์์ง๋ง ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ์ง์ผ๋ธ ์๊ฐ๋ ๋ง์๋ 1๋ถ๊ธฐ์ ๋๋ค.
์์ง ํด๋น ์บ๋ฆฐ๋๋ฅผ ์ ์ฌ์ฉํ๋์ง ๋ชจ๋ฅด๊ฒ ์ง๋ง ๋ถ๋ช 2๋ถ๊ธฐ์๋ 1๋ถ๊ธฐ๋ณด๋ค ์๊ฐ์ ์ ์ฌ์ฉํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ค ์ผ์ด ์๋ค๋ฉด์โฆ ์ธ์์ ๋ณ์์ ์ฐ์!
๊ฒฐ๋ก โ
4์ ์ก์ ํฌ์ธํธ
- ์ค๋ฌด์์ ๋ง๋ ๋ฌธ์ ๊ทผ๋ณธ์ ์ผ๋ก 2๊ฐ ์ด์ ํด๊ฒฐ
- Git ๋ฌธ์ ์ ๋ฆฌํ๊ณ Merge์ rebase ์ธ์ ์ ๋ฆฌ ๋ฐ ๊ณต์
- ๋ฐฑ์๋ CI/CD ํ์ฉํ์ฌ ECS์ ์ปจํ ์ด๋ ์๋ ๋ฐฐํฌ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ
- FSD์ Public API ๋ฐฉ์์ ๋ฒ๋ค๋ฌ ์ฐ๊ด์ง์ด ์ธ์ฌ์ดํธ ์ ๋ฆฌ
- HTTP ์ ์ก ๊ณ์ธต์ ๋ํด ์ ํํ ์ ๋ฆฌ
- ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ณด์ ๋ฌธ์ํํ๊ธฐ (XSS ๋ฐ CSRF ๊ณต๊ฒฉ)
- FSD ์ ์ฉ๊ธฐ ํฌ์คํธ 2ํธ ์์ฑํ๊ธฐ
- ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๋ํด ํ์ต ์์ํ๊ธฐ
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๋ํด ํ์ต ์์ํ๊ธฐ
4์์ 1๋ถ๊ธฐ๋ฅผ ๋ฐ์ด๋์ด ๋ ์น์ดํ๊ฒ ํ์ตํ๊ณ ์ ์ฉํ๋ ์๊ฐ์ ๊ฐ์ง๋ฉฐ ์ฌ๋ด์ ๋ ๋ง์ ๊ธฐ์ฌ์ ์ฑ์ฅ์ ๊ธฐ๋ํด๋ด ๋๋ค.