
์ฃผ๋ชฉํ ๋งํ โK-์คํ์์คโ ํ๋ก์ ํธ
์ฃผ๋ชฉํ ๋งํ โK-์คํ์์คโ ํ๋ก์ ํธ ๊ด๋ จ
์ ํต์ฌ ์ฝ๋๋ฅผ ๊ณต๊ฐํ ๊น์?
์คํ์ง๋ฐฅ์ ๋์ค๋ ํ๋ํฌํค์ ๊ธฐ์ตํ์๋์? ๊ฒ์ด๋ฒ๊ฑฐ์ ๋น๋ฐ ๋ ์ํผ๋ฅผ ํ์น๋ ค๊ณ ์๋ฐฑ ๋ฒ ์๋ํ๋ ๊ทธ ์บ๋ฆญํฐ ๋ง์ด์ฃ . ํต์์ ์ผ๋ก ๊ธฐ์ ์ ๋ณดํธํ๊ณ ๊ฐ์ถฐ์ผ ์์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ํนํ๋ฅผ ๋ด๊ณ , ์์ ๋น๋ฐ๋ก ์ง์ ํ๋ฉฐ, NDA๋ฅผ ๋งบ๊ณ ์ฒ ์ ํ ๋ณดํธํ๋ ๊ฒ์ด ์์์ด์ฃ .
๊ทธ๋ฐ๋ฐ ์คํ์์ค๋ ์ ๋ฐ๋์ ๊ธธ์ ๊ฑท์ต๋๋ค. ๋น๋ฐ ๋ ์ํผ๋ฅผ ๋ชจ๋์๊ฒ ๊ณต๊ฐํด ๋ฒ๋ฆฌ๋ ๊ฒ์ด๋๊น์. ๊ฐ์ธ ๊ฐ๋ฐ์๋ค์ ์์ ์ด๋ผ๊ณ ๋ง ์๊ฐํ์๋์? ๋๋๊ฒ๋ ๊ธฐ์ ๋ค๋ ํต์ฌ ์ฝ๋๋ฅผ ์คํํ๊ณ ์์ต๋๋ค. ๋ฅ๋ง์ธ๋๋ LLM์ธ ์ ฌ๋ง ๋ชจ๋ธ์, ๋ฉํ(Meta)๋ ํ๋ก ํธ์๋ ํ๋ ์์ํฌ ๋ฆฌ์กํธ(React)๋ฅผ, ๋ฒ์ (Vercel)์ ๋ฆฌ์กํธ ํ๋ ์์ํฌ์ธ Next.js๋ฅผ ๊ณต๊ฐํ์ต๋๋ค.
๊ธ๋ก๋ฒ ๋น ํ ํฌ ๊ธฐ์ ๋ค์ ์ด์งธ์ ์์ ๋ค์ ๋น๋ฒ ์์ค๋ฅผ ๋จ๋ค์๊ฒ ๊ณต๊ฐํ๋ ๊ฑธ๊น์? ๊ทธ๋ค์ด ์ ๋ํ๊ณ ์๋น์ฌ์ด ๋์ณ์ ์ธ๋ฅ๋ฅผ ์ด๋กญ๊ฒ ํ์๋ ํ์ต์ธ๊ฐ ์ ์ ์ ๊ฐ์ง๊ณ ์๋ ๊ฑธ๊น์? ์๋ง ๊ทธ๊ฑด ์๋ ๊ฒ๋๋ค. ์น์ดํ ๋น์ฆ๋์ค ์ธ๊ณ์์ ์ดํ์ฃผ์๋ณด๋ค๋ ์น๋ฐํ ์ ๋ต์ด ์๊ธฐ ๋ง๋ จ์ด๋๊น์.
์ฝ๋๋ฅผ ๊ณต๊ฐํ๋ฉด ๋ง์ผํ ์ด ๋ฉ๋๋ค
์์ ์ ๊ธฐ์ ์ด ๊ฑด์คํ๊ณ , ์ค๋ ฅ ์๊ณ , ๊ธฐ์ ์ด ์ ๋งํจ์ ์๋ฆฌ๋ฉด์๋ ์ด๋ฏธ ์๋ฆฌ ์ก์ ๋๊ธฐ์ ๋ค ์ฌ์ด์์ ์์ฅ์ ์กด์ฌ๊ฐ์ ๋ณด์ด๊ธฐ ์ํดํด ํ ์ ์๋ ๊ฐ์ฅ ํจ๊ณผ์ ์ธ ์ ๋ต์ ๋ฌด๋ฃ ๋ง์ผํ ์ ๋๋ค. ์์ ์ ๊ธฐ์ ์ด ์๋ฌด๋ฆฌ ํ๋ฅญํด๋ ์ฌ๋๋ค์ด ์์์ฃผ์ง ์์ผ๋ฉด ๋ฌด์จ ์์ฉ์ผ๊น์? ๊ทธ๋์ ์์ ์คํํด๋ฒ๋ฆฌ๋ ์ ํ์ ํ๋ ๊ฒ๋๋ค.
์ฐ๋ฆฌ ํ์ฌ์์๋ โ์ด๋ฆฐ์๊ฐโ์ด๋ผ๋ ์ถ๋ก AI ๋ชจ๋ธ ํ์ต ๋ฐ์ดํฐ์ ์ ํ๊น ํ์ด์ค(Hugging Face)์ ์คํํ ์ ์ด ์์ต๋๋ค. ์คํ์์ค๋ ๊ฐ์ฅ ํ๋ฅญํ ๋ง์ผํ ์ ๋๋ค. ํนํ ์คํํธ์ ์ด๋ ์๋ก์ด ๊ธฐ์ ์ ๊ฐ๋ฐํ ๊ธฐ์ ์๊ฒ๋ ๋์ฑ ๊ทธ๋ ์ฃ .
์ด๊ฒ์ ๋จ์ํ ๋ ธ์ถ ์ด์์ ํจ๊ณผ๋ฅผ ์ป์ ์๋ ์๋ ์ ๋ต์ ๋๋ค. ๊ฐ๋ฐ์ ์ปค๋ฎค๋ํฐ์์ ์ธ์ง๋๋ฅผ ๋์ด๊ณ , ํ์ฌ์ ๊ธฐ์ ๋ ฅ์ ์ ์ฆํ๋ฉฐ, ์ฌ์ง์ด ์ฑ์ฉ ์์ฅ์์๋ ์ฐ์๋ฅผ ์ ํ ์ ์๊ฒ ๋ฉ๋๋ค. "์ฐ๋ฆฌ๋ ์ด๋ฐ ๊ธฐ์ ์ ๋ง๋ค ์ ๋๋ก ์ค๋ ฅ์ด ์์ด์."๋ผ๊ณ ์ง์ ๋งํ๋ ๊ฒ๋ณด๋ค, ์ฝ๋๋ฅผ ๊ณต๊ฐ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๋ ๊ฒ์ด ํจ์ฌ ๋ ์ค๋๋ ฅ ์์ผ๋๊น์.

์ํ๊ณ ์ฃผ๋๊ถ์ ์ฅ๋ ๋๋ํ ๋ฐฉ๋ฒ
"์คํํ๋ฉด ๊ธฐ์ ์ ๋บ๊ธฐ๋ ๊ฑฐ ์๋๊น?" ์ฐ๋ ค์ ๋ชฉ์๋ฆฌ๊ฐ ๋์ฌ ์ ์์ต๋๋ค. ๋ง์ต๋๋ค, ๋บ๊ธธ ์๋ ์์ฃ โฆ ๋ง์ฝ ์คํํ ๋ค ๊ธฐ์ ๊ฐ๋ฐ์ ๋ฉ์ถ๋ค๋ฉด ๋ง์ ๋๋ค. ํ์ง๋ง ์คํ์์ค๋ก ๊ณต๊ฐํ๋ ์ชฝ์ ์ง์์ ์ผ๋ก ๊ธฐ์ ์ ๊ณ ๋ํํฉ๋๋ค. ์ฌ๋ด์๋ ๋ ๋์ ๋ฒ์ ์ ํ๋ผ์ด๋นํ๊ฒ ๊ฐ์ง๊ณ ์์ ์๋ ์๊ณ ์. ์ด๋ ๋ฐ์ ์๋๋ ์คํํ์ง ์์์ ๋๋ณด๋ค ์คํํ์ ๋๊ฐ ๋ ๋น ๋ฆ ๋๋ค. ์ฌ๋ด ์ง์๋ค์ ํผ๋๋ฐฑ๋ฟ๋ง ์๋๋ผ ํด์ธ์ ๊ธ๋ก๋ฒ ๊ฐ๋ฐ์๋ค๋ก๋ถํฐ ๊ณต์ง๋ก QA๋ฅผ ๋ฐ์ ์ ์์ผ๋๊น์. ๋์ฑ์ด ๊ทธ๋ค์ ๋ฒ๊ทธ๊น์ง ์ง์ ์์ ํด์ ์ฌ๋ ค์ค๋๋ค. ๊ทธ๊ฒ๋ ๋ฌด๋ฃ๋ก์!
๊ธฐ์ ์ ๋ฒ ๋ผ๋ ค๊ณ ํ๋ ๊ธฐ์ ๋ค์ ์คํ์์ค๊ฐ ๋น ๋ฅด๊ฒ ๋ฐ์ ํ๋ ๋ชจ์ต์ ๋ณด๊ณ , ์ค์ค๋ก ๋ฐ๋ก ๋ง๋ค์ด์ ๊ด๋ฆฌํ๋ ๊ฒ๋ณด๋ค ์คํ์์ค๋ฅผ ๊ทธ๋๋ก ์ฐ๋ ์ชฝ์ด ์์ ํจ์จ์ด ๋๋ค๊ณ ํ๋จํ ๊ฒ์ ๋๋ค. ์ด๋ ๊ฒ ์ฌ๋ฌ ๊ธฐ์ ๋ค์ด ์ฐ๋ฆฌ ํ์ฌ์ ๊ธฐ์ ์ ์ข ์๋๋ ๊ฒ์ด์ฃ .
๋ ๋์๊ฐ ๊ทธ๋ค์ ์์ ๋ค์ ์๊ตฌ ์ฌํญ์ ๊ตฌํํ๊ธฐ ์ํด ์ฐ๋ฆฌ ๊ธฐ์ ์ ํฌ์ํ ์๋ ์์ต๋๋ค. ์ง์ ์ ์ธ ๊ฐ๋ฐ ๊ธฐ์ฌ๋ ๋ฌผ๋ก , ์คํฐ์์ญ(sponsorship)์ด๋ผ๋ ๊ธ์ ์ ์ธ ํํ๋ก๋ ์ฐธ์ฌํฉ๋๋ค. ์คํ์์ค ์ฌ์ ์ ๊ธฐ์ ๋ค์๊ฒ ํ์ํ ๊ธฐ์ ์ ๋ฌด๋ฃ๋ก ์ ๊ณตํ๋ ๋์์, ์คํฐ์ ๊ธฐ์ ์ ์๊ตฌ ์ฌํญ์ ์ฐ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ผ๋ก ์ด๋ฃจ์ด์ง๋๋ค. ์ฝ๊ฒ ๋งํด, "๋ ๋ด๋ฉด ๊ทธ๊ฑฐ๋ถํฐ ํด์ค๊ฒ."๊ฐ ๋๋ ์ ์ ๋๋ค.
์ด๋ ์ํ๊ณ์ ์ฃผ๋๊ถ์ ํ๋ณดํ๋ ๋๋ํ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ฆฌ์กํธ๋ฅผ ๊ณต๊ฐํจ์ผ๋ก์จ ๋ฉํ๋ ์น ๊ฐ๋ฐ์ ํจ๋ฌ๋ค์์ ๋ฐ๊พธ์๊ณ , ์ ๊ณ ํ์ค์ ์ฃผ๋ํ๊ฒ ๋์์ต๋๋ค. ์ด๋ ๋จ์ํ ๊ธฐ์ ๊ณต์ ๊ฐ ์๋๋ผ ๋์งํธ ์ํ๊ณ์ ๋ฐฉํฅ์ฑ์ ๊ฒฐ์ ํ๋ ํ์ ์ป๋ ๊ฒ์ ๋๋ค.
์จ ์ธ์์ด ๋น์ ์ ๊ธฐ์ ์ ๊ฐ๋ฅด์นฉ๋๋ค
๋ฉํ๋ ๋ฆฌ์กํธ๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ณต๊ฐํ๊ณ ๋ฒ์จ ๋ฒ์ 19๊น์ง ๋ฐ์ ์์ผฐ์ต๋๋ค. ๋ค์ํ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋๋ฉฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ๋ฒ์ ๋์ฑ ๋ณต์กํด์ก์ฃ . ํ์ฌ ๋ฉํ ๋ด์ ์น ์๋น์ค๋ค์ ๋ชจ๋ ๋ฆฌ์กํธ๋ก ๋ง๋ค์ด์ง๊ณ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ค์ ์ ์ ์ง์์๊ฒ ์ฌ๋ด ๊ธฐ์ ์ฌ์ฉ๋ฒ์ ๋ฐ๋ก ๊ฐ๋ฅด์น ํ์๊ฐ ์์ต๋๋ค. ์จ ์ธ์์ด React๋ฅผ ์ฐ๊ณ ์๊ณ , React ๊ฐ์์ ๋ถํธ์บ ํ, ๋ค์ํ ํ์ฉ ์ฌ๋ก๊ฐ ํ๋ฐํ ๊ณต์ ๋๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ฌ์ง์ด ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ๋ ์์ํฌ์กฐ์ฐจ๋ React๋ฅผ ์ฐ์ ์ผ๋ก ๊ณ ๋ คํ์ฌ ๋ง๋ค์ด์ง๋๋ค. ์ด๋ฐ ์ํ๊ณ๋ฅผ ๋ง๋ค์ด๋ธ ๋ฉํ์ ์ ๋ต, ์ ๋ง ๋๋จํ์ง ์๋์?
์ด๋ฌํ ์ ๋ต์ ๋ฒ์ ์์๋ ๋ณผ ์ ์์ต๋๋ค. Vercel์ Next.js๋ผ๋ ๋ฆฌ์กํธ ํ๋ ์์ํฌ๋ฅผ ์คํ์์ค๋ก ๊ณต๊ฐํ๋ฉด์ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)๊ณผ ์ ์ ์ฌ์ดํธ ์์ฑ(SSG)์ ํ์ค์ ๋ง๋ค์ด๊ฐ๊ณ ์์ต๋๋ค. ๊ฐ๋ฐ์๋ค์ด Next.js๋ฅผ ์ฌ์ฉํ ์๋ก ์์ฐ์ค๋ฝ๊ฒ Vercel์ ํธ์คํ ์๋น์ค์ ์ํ๊ณ์ ์์กดํ๊ฒ ๋๋ ์๋ฆฌํ ์ ๋ต์ ๋๋ค. ์ด์ ๋ง์ ๊ธฐ์ ๋ค์ด Vercel ์ค์ฌ์ ๊ฐ๋ฐ ํ๊ฒฝ์์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ณ ์์ต๋๋ค.
์คํ์์ค๊ฐ ๋ชจ๋์๊ฒ ์ฃผ๋ ์ ๋ฌผ
์ด๋ฌํ ์คํ์์ค ์ํ๊ณ๋ ์ฐธ์ฌํ๋ ๋ชจ๋ ์ด์๊ฒ ๋ค์ํ ํํ์ ์ ๊ณตํฉ๋๋ค. ๊ฐ๋ฐ์๋ค์ ์ต์ ๊ธฐ์ ์ ๊น์ด ์ดํดํ๊ณ ์ค๋ฌด์ ๋ฐ๋ก ์ ์ฉํ ์ ์์ผ๋ฉฐ, ๊ธ๋ก๋ฒ ์ปค๋ฎค๋ํฐ์ ๋คํธ์ํฌ๋ฅผ ํ์ฑํ๊ณ , ์ฑ์ฉ ์์ฅ์์ ๊ฒฝ์๋ ฅ ์๋ ํฌํธํด๋ฆฌ์ค๋ฅผ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ์คํํธ์ ์ ์ด๊ธฐ ๊ฐ๋ฐ ๋น์ฉ ์ ๊ฐ์ผ๋ก ๋น ๋ฅด๊ฒ ์์ฅ์ ์ง์ ํ๊ณ , ๊ฒ์ฆ๋ ๊ธฐ์ ์คํ์ ํตํด ์์ ์ ์ธ ์๋น์ค๋ฅผ ๊ตฌ์ถํ๋ฉฐ, ๋๊ธฐ์ ๊ณผ์ ๊ธฐ์ ๊ฒฉ์ฐจ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ขํ ์ ์์ต๋๋ค.
IT ์ํ๊ณ ์ ์ฒด๋ก ๋ณด๋ฉด ๊ธฐ์ ๋ฐ์ ์ด ๋์ฑ ๊ฐ์ํ๋๊ณ , ์ค๋ณต ๊ฐ๋ฐ์ด ๋ฐฉ์ง๋์ด ํจ์จ์ฑ์ด ์ฆ๊ฐํ๋ฉฐ, ๊ธฐ์ ํ์คํ๋ฅผ ํตํด ํธํ์ฑ์ด ๋์์ง๋ ํจ๊ณผ๋ฅผ ์ป์ต๋๋ค.
ํ๊ตญ์ธ์ด ํ ํ๋ก์ ํธ๋ ์๋์?
"ํ๊ตญ์ IT ๊ฐ๊ตญ์ธ๋ฐ ์ ๊ธ๋ก๋ฒ ์คํ์์ค ํ๋ก์ ํธ๋ ์์๊น?"๋ผ๊ณ ์๊ฐํ์๋์? ์ฌ์ค ํ๊ตญ์ ๊ฐ๋ฐ์๋ค์ ์คํ์์ค ์ํ๊ณ์์ ํ๋ฐํ ํ๋ํ๊ณ ์์ต๋๋ค. ๋ค๋ง, ๋ง์ ์ฌ๋๋ค์ด ๊ทธ ๊ฐ๋ฐ์๋ค์ด ํ๊ตญ์ธ์ด๋ผ๋ ์ฌ์ค์ ์ ๋ชจ๋ฅผ ๋ฟ์ด์ฃ .
๊ทธ๋์ ํ๊ตญ์ ๊ธ๋ก๋ฒ ์คํ์์ค ์ํ๊ณ์์ ์ฃผ๋ก '์๋น์' ์ญํ ์ ํด์์ต๋๋ค. ํด์ธ์์ ๋ง๋ค์ด์ง ์คํ์์ค ๊ธฐ์ ์ ํ์ฉํ๋ ๋ฐ๋ ์ต์ํ์ง๋ง, ๊ธ๋ก๋ฒํ ์ํฅ๋ ฅ์ ๊ฐ์ง ์คํ์์ค๋ฅผ ์ง์ ๋ง๋ค์ด๋ด๋ ์ฌ๋ก๋ ์๋์ ์ผ๋ก ์ ์์ต๋๋ค.
ํ์ง๋ง ์ต๊ทผ ๋ช ๋ ๊ฐ, ์ด ๊ตฌ๋๊ฐ ๋น ๋ฅด๊ฒ ๋ณํ๊ณ ์์ต๋๋ค. ๊ฐ์ธ ๊ฐ๋ฐ์๋ค์ด ๊ฐ์ ํฅ๋ฏธ๋ก์ด ์คํ์์ค ํ๋ก์ ํธ๋ฅผ ํ๋ฐํ ์งํํ๊ณ ์์ต๋๋ค. ํ์ ์คํฌ๋ฆฝํธ(TypeScript) ์ปดํ์ผ๋ฌ๋ฅผ ์์ฉํ ์์ ๋ถํฐ ๋ฅ๋ฌ๋์ฉ ์๋ก์ด ์ธ์ด ๊ฐ๋ฐ, ๊ทธ๋ํฝ ๋ ๋๋ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊น์ง, ๋ค์ํ K-์คํ์์ค ํ๋ก์ ํธ๋ค์ด ์กด์ฌํฉ๋๋ค. ๊ทธ์ค์๋ ์ด๋ฏธ ๋ค์ด๋ณธ ์คํ์์ค๋ ์์ ๊ฒ๋๋ค. "๊ทธ๊ฒ ํ๊ตญ์ธ์ด ๋ง๋ ๊ฑฐ์์ด?"๋ผ๋ฉฐ ๋๋ผ๊ฒ ๋ ์๋ ์์ต๋๋ค.
์ด ๊ธ์์๋ ์ฃผ๋ชฉํ ๋งํ ํ๊ตญ์ ์คํ์์ค ํ๋ก์ ํธ 5๊ฐ์ง๋ฅผ ์๊ฐํด๋ณด๋ ค๊ณ ํฉ๋๋ค. ๊ฐ๊ฐ์ ํ๋ก์ ํธ๊ฐ ์ด๋ค ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ง๋ค์ด์ก๋์ง, ๊ทธ๋ฆฌ๊ณ ๊ฐ๋ฐ์๋ค์ ์ผ์์ ์ด๋ป๊ฒ ๋ ํธ๋ฆฌํ๊ฒ ๋ง๋ค์ด์ฃผ๋์ง ์ดํด๋ณผ ์์ ์ ๋๋ค. ์ฌ๋ฌ๋ถ๋ ์ด ๊ธ์ ์ฝ๊ณ ์คํ์์ค ๊ฐ๋ฐ์ ํฅ๋ฏธ๊ฐ ์๊ธฐ๋ฉด ์ข๊ฒ ์ต๋๋ค.
Typia: ํ์ ์คํฌ๋ฆฝํธ๋ก ์ด๋ฐ ๊ฑฐ๊น์ง ๋๋ค๊ณ ์?
"ํ์ ์คํฌ๋ฆฝํธ์ ํ์ ์ฒดํฌ๋ ๋ฐํ์์์ ๊ฐ๋ฅํ ๊น์?"
์ด ์ง๋ฌธ์ ๋ง์ ์ฃผ๋์ด ๊ฐ๋ฐ์๋ค์ด ๋ฉด์ ์์ ๋ง์ฃผํ ์ ์๋ ์ง๋ฌธ์
๋๋ค. ์ ๋ํ ์ด ์ง๋ฌธ์ ๋ฐ์ ์ ์ด ์์ฃ . ๋๋ถ๋ถ์ ๊ฐ๋ฐ์๋ "๋ถ๊ฐ๋ฅํฉ๋๋ค. ํ์
์คํฌ๋ฆฝํธ์ ํ์
์ ์ปดํ์ผ ํ์์๋ง ์กด์ฌํ๊ณ ๋ฐํ์์์๋ ์ฌ๋ผ์ง๋๋ค."๋ผ๊ณ ๋ตํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋๋ต์โฆ ๋ง์์ต๋๋ค. ์ ์ด๋ ํ๊ตญ์ธ ๊ฐ๋ฐ์์ samchon์ typia (samchon/typia
)๊ฐ ๋ฑ์ฅํ๊ธฐ ์ ๊น์ง๋์.

์ฌ๋ผ์ง๋ ํ์ , ๋จ๊ฒจ์ง๋ ๋ถ์ํจ
ํ์ ์คํฌ๋ฆฝํธ(TypeScript)์ ๊ฐ์ฅ ํฐ ์์ด๋ฌ๋๋ ๋ฐ๋ก ์ด๊ฒ์ ๋๋ค. ์ด์ฌํ ์์ฑํ ํ์ ์ ์๊ฐ ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์คํ๋ ๋๋ ์์ ํ ์ฌ๋ผ์ง๋ค๋ ์ ์ด์ฃ . ๊ฐ๋ฐํ ๋๋ ํ์ ์์ ์ฑ์ด๋ผ๋ ๋ ๋ ํ ์ธํ๋ฆฌ๊ฐ ์์ง๋ง, ๋น๋ํ ์ดํ์๋ ๊ทธ ์ธํ๋ฆฌ๊ฐ ์ฆ๋ฐํด ๋ฒ๋ฆฝ๋๋ค.
API๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ๋, ํ์ผ์ ๋ถ๋ฌ์ฌ ๋, ๋๋ ์ฌ์ฉ์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ ๋์ ๊ฐ์ ์ํฉ์์ ์ธ๋ถ ๋ฐ์ดํฐ๋ ํญ์ ๋ถํ์ค์ฑ์ ๋ดํฌํ๊ณ ์์ต๋๋ค. "๊ณผ์ฐ ๋ด๊ฐ ๊ธฐ๋ํ ํํ๋ก ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ฌ๊น?"๋ผ๋ ๋ถ์๊ฐ์ ํด์ํ๊ธฐ ์ํด ๊ฐ๋ฐ์๋ค์ ๋ฐํ์(runtime)์์ ํ์ ์ ๊ฒ์ฆํ๋ ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด ์์ต๋๋ค.
// ํ์
์ ์
interface User {
id: string;
email: string;
age: number;
}
// Zod ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ ์คํค๋ง ์ฌ์ ์
const userSchema = z.object({
id: z.string(),
email: z.string().email(),
age: z.number().min(0)
});
// ๋ฐ์ดํฐ ๊ฒ์ฆ
const isValidUser = userSchema.safeParse(userData).success;
๋ณด์ด์๋์? ๊ฐ์ ๋ด์ฉ์ ๋ ๋ฒ์ด๋ ์์ฑํด์ผ ํฉ๋๋ค. ํ ๋ฒ์ ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ํด, ๋ ํ ๋ฒ์ ๋ฐํ์ ๊ฒ์ฆ์ ์ํด์ ๋ง์ด์ฃ . ์ด๋ฐ ์ค๋ณต ์์ ์ด์ผ๋ง๋ก ๊ฐ๋ฐ์๋ค์ ๊ดด๋กญํ๋ ๋ถํ์ํ ๋ ธ๋์ด์์ต๋๋ค.
ํ์ ์ ์ฝ๋๋ก ๋ฐ๊ฟ์ฃผ๋ typia
์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด typia๋ ์ฌ๋ฏธ์๋ ์ ๊ทผ๋ฒ์ ์ฌ์ฉํ์ต๋๋ค. "ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ๊ฐ ํ์ ์ ๋ถ์ํด์, ๊ทธ์ ๋ง๋ ๊ฒ์ฆ ์ฝ๋๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ฉด ์ด๋จ๊น?"
์ด๊ฒ์ด ๋ฐ๋ก typia์ ํต์ฌ ์์ด๋์ด์ ๋๋ค. ํ์ ์คํฌ๋ฆฝํธ์ ์ ์ ํ์ ์ ๋ณด๋ฅผ ๋ถ์ํด ๋ฐํ์์์ ๋์ํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฒ์ฆ ์ฝ๋๋ก ๋ณํํด์ฃผ๋ ๊ฒ์ด์ฃ .
// ํ์
์ ์๋ง ํ๋ฉด
interface User {
id: string & tags.Format<"uuid">;
email: string & tags.Format<"email">;
age: number & tags.Type<"uint32"> & tags.Minimum<0>;
}
// ์๋์ผ๋ก ๋ฐํ์ ๊ฒ์ฆ ํจ์๊ฐ ์์ฑ๋ฉ๋๋ค
const isUser = typia.is<User>;
const isValid = isUser(userData); // true ๋๋ false
๋จ ํ ์ค์ ์ฝ๋๋ก ์๋ฒฝํ ํ์ ๊ฒ์ฆ์ด ๊ฐ๋ฅํด์ก์ต๋๋ค. ๋ ์ด์ ํ์ ๊ณผ ๊ฒ์ฆ ๋ก์ง์ ๋ฐ๋ก ๊ด๋ฆฌํ ํ์๊ฐ ์์ด์ง ๊ฒ์ด์ฃ .
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ TypeScript ์ฝ๋๊ฐ ์๋ค๊ณ ํด๋ด ์๋ค.
const isUser = typia.createIs<User>();
const valid = isUser(data);
์ด ์ฝ๋๋ ์ปดํ์ผ ํ ๋ค์๊ณผ ๊ฐ์ด ์ต์ ํ๋ JavaScript ์ฝ๋๋ก ๋ณํ๋ฉ๋๋ค.
// ์์ ์ฝ๋, ์ค์ ๋ ๋ณด๋ค ๋ ์ต์ ํ๋ ์ฝ๋๊ฐ ์์ฑ๋ฉ๋๋ค
const isUser = (() => {
return (input) => {
return typeof input === "object" && input !== null &&
typeof input.id === "string" &&
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(input.id) &&
typeof input.email === "string" &&
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/.test(input.email) &&
typeof input.age === "number" &&
input.age > 19 && input.age <= 100;
};
})();
์ฑ๋ฅ๊น์ง ์ฑ๊ธด typia
typia์ ์ง๊ฐ๋ ๋จ์ํ ์ฝ๋ ํธ์์ฑ์ ๋์ด ์ค์ ์ฑ๋ฅ์์๋ ๋๋ฌ๋ฉ๋๋ค. ๋ฏฟ๊ธฐ ํ๋ค ์ ๋์ ์ฑ๋ฅ ์ฐจ์ด๊ฐ ์ฌ๊ธฐ ์์ต๋๋ค.
- 20,000๋ฐฐ ๋ ๋น ๋ฅธ ๊ฒ์ฆ ์๋: ๊ธฐ์กด์ class-validator๋ณด๋ค ๋ฌด๋ ค 2๋ง ๋ฐฐ ๋น ๋ฅธ ์๋๋ก ํ์ ๊ฒ์ฆ์ ์ํํฉ๋๋ค. ๋ฐฑ์๋ ์๋ฒ์์๋ ์ด๋ฅผ ํตํด ์ฑ๋ฅ์ด ์ฝ 10๋ฐฐ ํฅ์๋ฉ๋๋ค.
- 200๋ฐฐ ๋น ๋ฅธ JSON ์ง๋ ฌํ: class-transformer๋ณด๋ค 200๋ฐฐ ๋น ๋ฅธ JSON ์ฒ๋ฆฌ ๋ฅ๋ ฅ์ ๋ณด์ฌ์ค๋๋ค. ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ์ต์ ํ๋์ด ์์ต๋๋ค.
- ๋ณต์กํ ์ ๋์จ ํ์ ์ง์: ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์ด๋ ค์ํ๋ ๋ณต์กํ ์ ๋์จ ํ์ (union type)๋ ์์ ์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
์ด๋ฌํ ์ฑ๋ฅ ํฅ์์ ๋น๋ฐ์ ์ด๋์ ์์๊น์? typia๋ ํ์ ๋ถ์์ ๋ฐํ์์ด ์๋ ์ปดํ์ผ ํ์์ ์ํํฉ๋๋ค. ๋ฐ๋ผ์ ๋ฐํ์์์๋ ๋ฏธ๋ฆฌ ์ต์ ํ๋ ์ฝ๋๋ง ์คํ๋์ด ๋๋ผ์ด ์๋ ํฅ์์ด ๊ฐ๋ฅํ ๊ฒ์ ๋๋ค. ๋ํ typia๋ ํ์ ์คํฌ๋ฆฝํธ์ ํ์ ์์คํ ์ ํ์ฅํ์ฌ ๋์ฑ ํ๋ถํ ํํ์ด ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ๋จ์ํ "์ด๊ฒ์ ๋ฌธ์์ด์ด๋ค"๋ฅผ ๋์ด, "์ด๊ฒ์ ์ด๋ฉ์ผ ํ์์ ๋ฌธ์์ด์ด๋ค"์ ๊ฐ์ ๊ตฌ์ฒด์ ์ธ ์ ์ฝ ์กฐ๊ฑด์ ํ์ ๋ ๋ฒจ์์ ์ ์ํ ์ ์๊ฒ ๋ ๊ฒ์ด์ฃ .
LLM ํจ์ ํธ์ถ๊น์ง ์๋ํํ๋ค
LLM์ ํจ์ ํธ์ถ(Function Calling)์ ์์ฆ AI ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์ ํ์์ ์ธ ๊ธฐ๋ฅ์ด ๋์์ต๋๋ค. ํ์ง๋ง ์ด๋ฅผ ์ํ ์คํค๋ง(schema) ์ ์๋ ์ฌ์ ํ ๊ณจ์น ์ํ ์์ ์ด์์ฃ . OpenAI๋ Anthropic์ ๋ง๋ ํ์์ผ๋ก ํจ์๋ฅผ ์ผ์ผ์ด ์ ์ํด์ผ ํ์ผ๋๊น์.
typia๋ ์ต๊ทผ์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ต๋๋ค. typia.llm.application()์ด๋ผ๋ ๊ธฐ๋ฅ์ ํตํด, ํ์ ์คํฌ๋ฆฝํธ ์ธํฐํ์ด์ค์์ ์ง์ LLM ํจ์ ํธ์ถ ์คํค๋ง๋ฅผ ์์ฑํ ์ ์๊ฒ ๋ง๋ ๊ฒ์ ๋๋ค.
// ์ธํฐํ์ด์ค ์ ์
interface WeatherService {
getWeather(props: {
city: string;
date: string;
}): Promise<{
temperature: number;
condition: string;
}>;
}
// LLM ํจ์ ํธ์ถ ์คํค๋ง ์๋ ์์ฑ
const schema = typia.llm.application<WeatherService, "chatgpt">();
์ด๋ ๊ฒ ์์ฑ๋ ์คํค๋ง๋ ์๋์ ๊ฐ์ด OpenAI API์ ๋ฐ๋ก ์ ๋ฌํ ์ ์๋ ํํ๋ก ๋ณํ๋ฉ๋๋ค.
{
"functions": [
{
"name": "getWeather",
"description": "getWeather ํจ์",
"parameters": {
"type": "object",
"properties": {
"props": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "๋์ ์ด๋ฆ"
},
"date": {
"type": "string",
"description": "๋ ์ง"
}
},
"required": ["city", "date"]
}
},
"required": ["props"]
}
}
]
}
์ด์ ํ์ ์คํฌ๋ฆฝํธ ๋ฉด์ ์ง๋ฌธ์ ๋ต์ ๋ฐ๋์ด์ผ ํฉ๋๋ค.
"ํ์ ์คํฌ๋ฆฝํธ์ ํ์ ์ฒดํฌ๋ typia๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐํ์์์๋ ๊ฐ๋ฅํฉ๋๋ค."
samchon์ด๋ผ๋ ๋๋ค์์ ๊ฐ์ง ํ๊ตญ ๊ฐ๋ฐ์๊ฐ ๋ง๋ ์ด ํ์ ์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ์ ์คํฌ๋ฆฝํธ ์ํ๊ณ์ ์๋ก์ด ํจ๋ฌ๋ค์์ ์ ์ํ์ต๋๋ค. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์๊ฒ ๋์๋ค๋ฉด ํ์ ์คํฌ๋ฆฝํธ๋ก ๋ฐํ์์ ํ์ ์ฒดํฌ๋ฅผ ํ ์ ์๋์ง ์ง๋ฌธ๋ฐ์์ ๋, ์์ ์๊ฒ "๊ฐ๋ฅํฉ๋๋ค."๋ผ๊ณ ๋ตํ ์ ์์ต๋๋ค.
SWC: ์ด๊ณ ์ ์น ์ปดํ์ผ๋ฌ
์ฝ๋๋ฅผ ์์ ํ๊ณ ์ ์ฅ ๋ฒํผ์ ๋๋ฅธ ํ, ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ก๊ณ ์นจ๋๊ธฐ๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๋ช ์ด์ ์๊ฐ. ๊ฐ๋ฐ์๋ผ๋ฉด ๋๊ตฌ๋ ๊ฒฝํํด ๋ณธ ์ง๋ฃจํ ์๊ฐ์ด ์์ต๋๋ค. ํนํ ๋๊ท๋ชจ ํ๋ก์ ํธ์์๋ ๋น๋ ์๊ฐ์ด ๋ช ๋ถ, ์ฌ์ง์ด ๋ช์ญ ๋ถ๊น์ง ๊ฑธ๋ฆฌ๊ธฐ๋ ํ์ฃ . ๊ฐ๋ฐ ์์ฐ์ฑ์ ํฌ๊ฒ ๋จ์ด๋จ๋ฆฌ๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ ํ๊ตญ ๊ฐ๋ฐ์๊ฐ ๋์ฐ์ต๋๋ค.

์น์ ๋ฌ์คํธ๋ฅผ ๋ผ์น๋ค
SWC (Speedy Web Compiler swc-project/swc
)๋ ํ๊ตญ ๊ฐ๋ฐ์ 'kdy1'์ด ๋ง๋ ์ด๊ณ ์ JavaScript/TypeScript ์ปดํ์ผ๋ฌ์
๋๋ค. SWC์ ๊ฐ์ฅ ํฐ ํน์ง์ ๋ฐ๋ก ์๋์
๋๋ค. ๊ธฐ์กด ์น ๊ฐ๋ฐ ๋๊ตฌ์ ํ์ค์ด์๋ Babel๋ณด๋ค ๋จ์ผ ์ค๋ ๋์์ 20๋ฐฐ, 4๊ฐ ์ฝ์ด์์๋ ๋ฌด๋ ค 70๋ฐฐ๋ ๋ ๋น ๋ฅธ ์๋๋ฅผ ์๋ํฉ๋๋ค.
์ด์ฒ๋ผ ๋๋ผ์ด ์ฑ๋ฅ ํฅ์์ด ๊ฐ๋ฅํ๋ ๋น๊ฒฐ์ ๋ฌด์์ผ๊น์? ๋ฐ๋ก Rust๋ผ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ์ ํํ ๊ฒ์ ์์ต๋๋ค. kdy1์ ๋๋ถ๋ถ์ ์น ๋๊ตฌ๊ฐ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์์ฑ๋๋ ํ๊ฒฝ์์ ๊ณผ๊ฐํ๊ฒ Rust๋ฅผ ์ ํํ์ต๋๋ค. Rust๋ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ์ ์ ๊ณตํ๋ฉด์๋ C/C++์ ํ์ ํ๋ ์๋๋ฅผ ์ ๊ณตํ๋ ํ๋์ ์ธ ์ธ์ด์ ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ก ์์ฑ๋ Babel์ Node.js ํ๊ฒฝ์์ ์คํ๋๊ธฐ ๋๋ฌธ์ ๊ทผ๋ณธ์ ์ธ ์ฑ๋ฅ ํ๊ณ๊ฐ ์์์ต๋๋ค. ๋ฐ๋ฉด SWC๋ Rust์ ์ฑ๋ฅ ์ด์ ์ ์ต๋ํ ํ์ฉํ์ฌ ์ปดํ์ผ๋ฌ์ ์๋ ํ๊ณ๋ฅผ ์์ ํ ์๋กญ๊ฒ ์ ์ํ์ต๋๋ค.
SWC๋ ๋จ์ํ ์ปดํ์ผ๋ฌ ์ด์์ ๊ฐ์น๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ํ์ฅ์ฑ์ ๊ณ ๋ คํ ํ๋ซํผ์ผ๋ก ์ค๊ณ๋์ด, ๋ค์ํ ๋๊ตฌ๋ค์ด ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถ๋ ์ ์์ต๋๋ค. ์ฝ๋ ๋ณํ, ๋ฒ๋ค๋ง, ์ต์ํ ๋ฑ ์ฌ๋ฌ ๊ธฐ๋ฅ์ ๋ชจ๋ํํ์ฌ, ํ์ํ ๋ถ๋ถ๋ง ์ ํ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ์ ์ฐ์ฑ์ ์ ๊ณตํฉ๋๋ค. ๋ํ Rust์ ์น์ด์ ๋ธ๋ฆฌ(WebAssembly, WASM) ์ง์์ ํตํด ๊ฑฐ์ ๋ชจ๋ ํ๋ซํผ์์ ๋์ํ ์ ์์ด, ์น ๊ฐ๋ฐ ํ๊ฒฝ์ ๋์ฑ ๋ค์ํํ๋ ๋ฐ ํฌ๊ฒ ๊ธฐ์ฌํฉ๋๋ค.
Next.js๋ SWC๋ฅผ ๋์ ํ์ต๋๋ค!
SWC์ ์ ์ฌ๋ ฅ์ ์์๋ณธ ๊ฒ์ ์น ๊ฐ๋ฐ ํ๋ ์์ํฌ ๋ถ์ผ์ ์ ๋์ฃผ์์ธ ๋ฒ์ ์ด์์ต๋๋ค. Next.js๋ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ์ง์ํ๋ ๋ฆฌ์กํธ ํ๋ ์์ํฌ์ ๋๋ค. ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ๊ตฌํํ ๋ Next.js๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํด๋ ๊ณผ์ธ์ด ์๋ ์ ๋๋ก ์ ๊ณ ํ์ค์ด ๋ ์ ๋ช ํ๋ ์์ํฌ์ฃ .
์ด๋ฌํ ์ ๋ช ํ๋ ์์ํฌ์ธ Next.js๊ฐ ๋ฒ์ 12๋ถํฐ SWC๋ฅผ ๊ธฐ๋ณธ ์ปดํ์ผ๋ฌ๋ก ๋์ ํ์ต๋๋ค. ๊ทธ ๊ฒฐ๊ณผ๋ ๋๋ผ์ ์ต๋๋ค.
- ๊ฐ๋ฐ ๋ชจ๋์์์ Fast Refresh ์๋๊ฐ 3๋ฐฐ ๋ ๋นจ๋ผ์ก์ต๋๋ค.
- ํ๋ก๋์ ๋น๋ ์๋๊ฐ 5๋ฐฐ ํฅ์๋์์ต๋๋ค.
- ์ฝ๋ ๋ณํ ๋ฐ ์ต์ํ(๋ฏธ๋ํ์ด)๊ฐ 17๋ฐฐ ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋ฉ๋๋ค.
Next.js์์์ SWC ๋์ ์ ๋จ์ํ ์ฑ๋ฅ ํฅ์ ์ด์์ ์๋ฏธ๋ฅผ ๊ฐ์ง๋๋ค. ์ด๋ฅผ ํตํด Next.js๋ ๋ค์ํ ๊ธฐ๋ฅ์ ๋์ฑ ํจ์จ์ ์ผ๋ก ์ ๊ณตํ ์ ์๊ฒ ๋์์ต๋๋ค. Styled Components ๊ฐ์ CSS-in-JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ๊ณ , Jest ํตํฉ์ ํตํด ํ ์คํธ ํ๊ฒฝ ์ค์ ์ ๊ฐ์ํํ๋ฉฐ, ๋ก์ปฌ ํจํค์ง๋ ๋ ธ๋ ๋ชจ๋(Node Modules)์ ์ฝ๋๋ฅผ ์๋์ผ๋ก ๋ณํํ๊ณ ๋ฒ๋ค๋งํ ์ ์๊ฒ ๋์์ต๋๋ค. ๋ํ ๋ถํ์ํ ์ฝ์ ์ถ๋ ฅ ์ ๊ฑฐ, ๋ฆฌ์กํธ ์์ฑ ์ ๊ฑฐ ๋ฑ ๋ค์ํ ์ต์ ํ ์ต์ ๋ ์ ๊ณตํฉ๋๋ค.
์ด ๊ธฐ๋ฅ๋ค์ ๊ณผ๊ฑฐ์ ์ฃผ๋ก Babel ํ๋ฌ๊ทธ์ธ์ผ๋ก ๊ตฌํ๋์๋ ๊ฒ๋ค์ ๋๋ค. ํ์ง๋ง ์ด์ ๋ SWC๋ฅผ ํตํด ํจ์ฌ ๋ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋ฉ๋๋ค. ๋๋ถ์ Next.js ๊ฐ๋ฐ์๋ค์ ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์ปค์ ธ๋ ๋น ๋ฅธ ๊ฐ๋ฐ ๊ฒฝํ์ ์ ์งํ ์ ์๊ฒ ๋์์ต๋๋ค.
์ด๋ฐ ๊ฑด ์ธ๊ตญ ๊ฐ๋ฐ์๋ค๋ง ํ๋ ์ค ์์๋๋ฐ...
SWC๋ ํ๊ตญ ๊ฐ๋ฐ์๋ค๋ ๊ธ๋ก๋ฒ ์ํํธ์จ์ด ์ฐ์ ์ ํฐ ์ํฅ์ ๋ฏธ์น ์ ์์์ ๋ณด์ฌ์ฃผ๋ ์ข์ ์ฌ๋ก์ ๋๋ค. SWC์ ๊ฐ๋ฐ์๋ ํ์ฌ ๋ฒ์ ์์ ์ผํ๊ณ ์์ผ๋ฉฐ, Next.js์ GitHub ์ ์ฅ์์์๋ ๊ทธ์ ๊ธฐ์ฌ๋ฅผ ์ฌ์ฌ์ฐฎ๊ฒ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๊ฐ๋ฐ ๋๊ตฌ๋ ์๋ฏธ๊ถ ๊ฐ๋ฐ์๋ค์ด ์ฃผ๋ํด ์์ต๋๋ค. ํ์ง๋ง SWC๋ ์ด๋ฐ ๊ณ ์ ๊ด๋ ์ ๊นจ๊ณ ํ๊ตญ์ ๊ธฐ์ ๋ ฅ์ ์ ์ธ๊ณ์ ์ฆ๋ช ํ์ต๋๋ค. ๋ฒ์ , ๋ฐ์ดํธ๋์ค(ByteDance), ํ ์ผํธ(Tencent), ์ผํผํ์ด(Shopify)์ ๊ฐ์ ๊ธ๋ก๋ฒ ๊ธฐ์ ๋ค์ด ์ด๋ฏธ ํ๋ก๋์ ํ๊ฒฝ์์ SWC๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ, Next.js, Parcel, Deno์ ๊ฐ์ ์ฃผ์ ์๋ฐ์คํฌ๋ฆฝํธ ๋๊ตฌ๋ค๋ ์ด๋ฏธ SWC๋ฅผ ์ฑํํ์ต๋๋ค.
์ค๋๋ ์๋ง์ ์น ๊ฐ๋ฐ์๋ค์ด ํ๊ตญ์์ ํ์ํ ์ด ๋๊ตฌ๋ฅผ ํตํด ๋ ๋น ๋ฅด๊ณ ํจ์จ์ ์ธ ๊ฐ๋ฐ์ ํ๊ณ ์๋ค๋ ์ฌ์ค์ ์ ๋ง ๋๋์ต๋๋ค. SWC์ ์ฑ๊ณต์ ๋จ์ํ ๊ธฐ์ ์ ํ์ ์ ๋์ด, ๊ธ๋ก๋ฒ ์คํ์์ค ์ํ๊ณ์์ ํ๊ตญ ๊ฐ๋ฐ์๋ค์ ์์์ ๋์ธ ์ค์ํ ์ด์ ํ๊ฐ ๋์์ต๋๋ค. ์์ผ๋ก ๋ ๋ง์ ํ๊ตญ ๊ฐ๋ฐ์๋ค์ด ์ธ๊ณ์ ์ธ ์คํ์์ค ํ๋ก์ ํธ๋ฅผ ์ด๋์ด๊ฐ ์ ์๋๋ก ์๊ฐ์ ์ ๊ณตํ๋ค๋ ์ ์์, SWC์ ๊ฐ์น๋ ๋จ์ง ์ฝ๋ ๊ทธ ์ด์์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค.
Flitter: ์ ์ธ์ ์ผ๋ก ์บ๋ฒ์ค์ SVG๋ฅผ ๋ค๋ฃจ๋ ๋ ๋๋ง ์์ง

์ ์ธ์ ํ๋ก๊ทธ๋๋ฐ? ์ด๊ฒ ๋ญ์ง?
์น ๊ฐ๋ฐ์ ํ์ จ๋ค๋ฉด jQuery์ ๋ฆฌ์กํธ์ ์ฐจ์ด๋ฅผ ๋๊ปด๋ณด์ จ์ ๊ฒ๋๋ค. jQuery์์๋ ์ด๋ฐ ์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ์ฃ .
// jQuery ๋ฐฉ์ - ๋ช
๋ น์ (imperative) ์ ๊ทผ๋ฒ
$("button").click(function() {
// ๋ฒํผ์ ์จ๊ธด๋ค
$(this).hide();
// ๋ฉ์์ง ์์๋ฅผ ์์ฑํ๋ค
$("<p>๋ฒํผ์ด ํด๋ฆญ๋์์ต๋๋ค!</p>").appendTo("container");
// ๋ฉ์์ง ์คํ์ผ์ ๋ณ๊ฒฝํ๋ค
$("container p").css("color", "red");
});
๋งค ๋จ๊ณ๋ง๋ค "์ด๊ฑธ ํด๋ผ, ์ ๊ฑธ ํด๋ผ"๋ผ๊ณ DOM์ ์ง์ ์กฐ์ํ๋ ๋ฐฉ์์ ๋๋ค. ๋ฐ๋ฉด ๋ฆฌ์กํธ๋ ์ด๋จ๊น์?
// ๋ฆฌ์กํธ ๋ฐฉ์ - ์ ์ธ์ (declarative) ์ ๊ทผ๋ฒ
function App() {
const [isButtonClicked, setButtonClicked] = useState(false);
return (
<div id="container">
{!isButtonClicked && (
<button onClick={() => setButtonClicked(true)}>
ํด๋ฆญํ์ธ์
</button>
)}
{isButtonClicked && (
<p style={{ color: 'red' }}>
๋ฒํผ์ด ํด๋ฆญ๋์์ต๋๋ค!
</p>
)}
</div>
);
}
๋ฆฌ์กํธ์์๋ "์ด๋ป๊ฒ" ๋ณด๋ค๋ "๋ฌด์์" ๋ณด์ฌ์ค์ง๋ฅผ ์ ์ธํฉ๋๋ค. ์ํ์ ๋ฐ๋ผ UI๊ฐ ์ด๋ป๊ฒ ๋ณด์ฌ์ผ ํ๋์ง๋ฅผ ์ค๋ช ํ๋ฉด, ์ค์ DOM ์ ๋ฐ์ดํธ๋ ๋ฆฌ์กํธ๊ฐ ์์์ ์ฒ๋ฆฌํด์ฃผ์ฃ .
์บ๋ฒ์ค: ๋๋ค์ ์ ์ฐจ์ ์ฝ๋ ์์ฑํ๊ธฐ
๊ทธ๋ฐ๋ฐ ์น ๊ทธ๋ํฝ์ ๋ค๋ฃฐ ๋, ํนํ Canvas๋ฅผ ์ฌ์ฉํ ๋๋ ์ด๋จ๊น์? ์ํ๊น๊ฒ๋ ๋ค์ ์ ์ฐจ์ ์ธ ์ฝ๋๋ก ๋์๊ฐ๊ฒ ๋ฉ๋๋ค.
// Canvas์ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ๋ฒ - ์ ์ฐจ์
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// ์ฌ๊ฐํ ๊ทธ๋ฆฌ๊ธฐ
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 100, 100);
// ํ
์คํธ ์ถ๊ฐ
ctx.fillStyle = 'white';
ctx.font = '16px Arial';
ctx.fillText('Hello Canvas', 20, 50);
// ์ด๋ฒคํธ ์ฒ๋ฆฌ๋ ๋ชจ๋ ์๋์ผ๋ก...
canvas.addEventListener('click', function(e) {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// hitTest๋ฅผ ์ง์ ๊ตฌํํด์ผ ํจ
if (x >= 10 && x <= 110 && y >= 10 && y <= 110) {
console.log('์ฌ๊ฐํ ํด๋ฆญ๋จ!');
}
});
์บ๋ฒ์ค(Canvas)๋ DOM๊ณผ ๋ฌ๋ฆฌ ์์๋ค์ ๊ฐ์ฒด๋ก ์ถ์ ํ์ง ์์ต๋๋ค. ๋ชจ๋ ๊ฒ์ด ๊ทธ์ ํฝ์ ์ผ ๋ฟ์ด์ฃ . ๊ทธ๋์ ์์์ ์์น ๊ณ์ฐ, ์ด๋ฒคํธ ๊ฐ์ง, ๋ ๋๋ง ์ต์ ํ ๋ฑ์ ๋ชจ๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ตฌํํด์ผ ํ์ต๋๋ค.
์ ์ธ์ ์ ๊ทผ๋ฐฉ์์ผ๋ก ์บ๋ฒ์ค์ SVG ๋ค๋ฃจ๊ธฐ
์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํ์ํ ๊ฒ์ด ๋ฐ๋ก Flitter์ ๋๋ค. Flitter๋ ๊ตฌ๊ธ(Google)์ Flutter ํ๋ ์์ํฌ์์ ์๊ฐ์ ๋ฐ์ ์น์์ ์บ๋ฒ์ค์ SVG๋ฅผ ์ ์ธ์ ์ผ๋ก ๋ค๋ฃฐ ์ ์๊ฒ ํด์ฃผ๋ ๊ฐ๋ ฅํ ๋ ๋๋ง ์์ง์ ๋๋ค.
// Flitter ์ฌ์ฉ ์์ - ์ ์ธ์ ์ ๊ทผ๋ฒ
import { Container, Text, TextStyle, GestureDetector, AppRunner } from '@meursyphus/flitter';
const app = new AppRunner({
view: document.getElementById('app'),
});
app.runApp(
Container({
width: 200,
height: 100,
color: 'blue',
child: GestureDetector({
onClick: (e) => {
console.log('Container clicked!');
},
child: Text('Hello, Flitter!', {
style: new TextStyle({ color: 'white', fontSize: 20 }),
}),
}),
})
);
์ด์ ์บ๋ฒ์ค๋ SVG๋ฅผ ์ฌ์ฉํ๋๋ผ๋ ๋ฆฌ์กํธ์ ๊ฐ์ ์ ์ธ์ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ์ ์งํ ์ ์๊ฒ ๋์์ต๋๋ค.
Flitter์ ํต์ฌ ํน์ง
๊ฐ๋ ฅํ ๋ ๋๋ง ์์ง
Flitter๋ ๊ฐ๋ ฅํ ๋ ๋๋ง ์์ง์ ๊ธฐ๋ฐ์ผ๋ก ๋ณต์กํ ๊ทธ๋ํฝ๊ณผ UI๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. ๋ ๋ ๊ฐ์ฒด ํธ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ฉด์ ํ์๋๋ ์์๋ค์ ๊ด๋ฆฌํ๊ณ , ํ์ํ ๋ถ๋ถ๋ง ์ ๋ฐ์ดํธํ๋ ์ต์ ํ๋ ๋ ๋๋ง ํ์ดํ๋ผ์ธ์ ์ ๊ณตํฉ๋๋ค.
์ ์ธ์ ํ๋ก๊ทธ๋๋ฐ ๋ชจ๋ธ
Flitter๋ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ํ๋ฉด์ด ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋๋ ์ ์ธ์ (declarative) ํจ๋ฌ๋ค์์ ๋ฐ๋ฆ ๋๋ค. ๊ฐ๋ฐ์๋ UI๊ฐ ์ด๋ป๊ฒ ๋ณด์ฌ์ผ ํ๋์ง๋ง ์ ์ํ๋ฉด ๋ฉ๋๋ค. ๋ณต์กํ DOM ์กฐ์์ด๋ ์บ๋ฒ์ค ๋ช ๋ น์ Flitter๊ฐ ์๋์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
๋์ผ ๋ ๋๋ฌ ์ง์ (SVG์ Canvas)
Flitter๋ SVG์ Canvas, ๋ ๊ฐ์ง ๋ ๋๋ฌ(renderer)๋ฅผ ๋ชจ๋ ์ง์ํฉ๋๋ค. ์ํฉ์ ๋ฐ๋ผ ๋ฒกํฐ ๊ทธ๋ํฝ(SVG)์ด๋ ๋นํธ๋งต ๊ทธ๋ํฝ(Canvas)์ ์ ํํ ์ ์์ผ๋ฉฐ, ๋ ๋ ๋๋ฌ ๊ฐ์ ์ ํ๋ ๊ฐํธํฉ๋๋ค.
// SVG ๋ ๋๋ฌ ์ฌ์ฉ
const app = new AppRunner({
view: document.getElementById('app'),
renderer: 'svg', // SVG ๋ ๋๋ฌ ์ ํ
});
// Canvas ๋ ๋๋ฌ ์ฌ์ฉ
const app = new AppRunner({
view: document.getElementById('app'),
renderer: 'canvas', // Canvas ๋ ๋๋ฌ ์ ํ
});
๋ด์ฅ๋ ์ ์ค์ฒ ๊ฐ์ง
Flitter๋ ๋ณต์กํ ์ฌ์ฉ์ ์ํธ์์ฉ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ ์ค์ฒ ๊ฐ์ง ๊ธฐ๋ฅ์ ๋ด์ฅํ๊ณ ์์ต๋๋ค. ๊ธฐ์กด์๋ ์บ๋ฒ์ค์์ ํด๋ฆญ ๊ฐ์ง๋ฅผ ์ํด hitTest ๋ก์ง์ ์ง์ ๊ตฌํํด์ผ ํ์ง๋ง, Flitter์์๋ ์ด ๋ชจ๋ ๊ฒ์ด ์๋์ผ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค.
GestureDetector({
onClick: (e) => console.log('ํด๋ฆญ๋จ!'),
onDoubleClick: (e) => console.log('๋๋ธ ํด๋ฆญ๋จ!'),
onDragStart: (e) => console.log('๋๋๊ทธ ์์!'),
onDragUpdate: (e) => console.log('๋๋๊ทธ ์ค...'),
onDragEnd: (e) => console.log('๋๋๊ทธ ์ข
๋ฃ!'),
child: /* ์์ ์์ ฏ */
})
์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ
Flitter๋ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ๋ฅผ ์ฑํํ์ฌ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์์ต๋๋ค. ์ํ๊ฐ ์๋ ์์ ฏ(StatefulWidget)๊ณผ ์ํ๊ฐ ์๋ ์์ ฏ(StatelessWidget)์ ํตํด ๋ค์ํ UI ์์๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค.
// ์ํ๊ฐ ์๋ ์์ ฏ ์์
class Counter extends StatefulWidget {
createState() {
return new CounterState();
}
}
class CounterState extends State<Counter> {
private count: number = 0;
incrementCounter() {
this.setState(() => {
this.count++;
});
}
build() {
return Container({
padding: EdgeInsets.all(16),
color: Colors.blue[100],
child: GestureDetector({
onTap: () => this.incrementCounter(),
child: Text(`Count: ${this.count}`, {
style: new TextStyle({ color: Colors.black, fontSize: 24 }),
}),
}),
});
}
}
Flitter๋ ์ด๋ป๊ฒ ์ธ ์ ์๋์?
Flitter๋ ๋ค์ํ ๊ทธ๋ํฝ ์ค์ฌ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ณต์กํ ๋ฐ์ดํฐ๋ฅผ ์๊ฐ์ ์ผ๋ก ํํํ๋ ์ฐจํธ์ ๊ทธ๋ํ๋ฅผ ๊ฐํธํ๊ฒ ๊ตฌํํ ์ ์์ผ๋ฉฐ, ์ํธ์์ฉ๊ณผ ์ ๋๋ฉ์ด์ ์ ์ถ๊ฐํด ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์ํ ์ ์์ต๋๋ค. ํนํ ERD(Entity-Relationship Diagram)๋ ๋ง์ธ๋๋งต๊ณผ ๊ฐ์ ๋ค์ด์ด๊ทธ๋จ ํธ์ง๊ธฐ๋ฅผ ๊ตฌํํ๋ ๋ฐ ์ด์์ ์ ๋๋ค. ์์ ๋๋๊ทธ(drag), ์ฐ๊ฒฐ์ ์์ฑ, ํ๋/์ถ์ ๋ฑ์ ๋ณต์กํ ๊ธฐ๋ฅ์ ์ ์ธ์ ์ผ๋ก ๊ตฌํํ ์ ์์ด, ์ฝ๋ ๊ด๋ฆฌ๊ฐ ํจ์ฌ ์์ํด์ง๋๋ค.
๋ํ ๊ฒ์, ๋๋ก์ ๋๊ตฌ, ์๋ฎฌ๋ ์ด์ ๋ฑ ์ฌ์ฉ์์์ ์ํธ์์ฉ์ด ๋ง์ ๊ทธ๋ํฝ ์ค์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ Flitter๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค. ๋ด์ฅ๋ ์ ์ค์ฒ(gesture) ๊ฐ์ง ๊ธฐ๋ฅ๊ณผ ๊ณ ์ฑ๋ฅ ๋ ๋๋ง ์์ง ๋๋ถ์ ๋ณต์กํ ์ธํฐ๋์ (interaction)๋ ์ฝ๊ฒ ๊ตฌํํ ์ ์์ฃ . ์ค์ ๋ก Flitter๋ฅผ ์ฌ์ฉํด ๊ตฌํ๋ ์ธํฐ๋ํฐ๋ธ ERD ๋๊ตฌ EasyRD๋ Flitter์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋ณด์ฌ์ฃผ๋ ์ข์ ์์ ๋๋ค.
Flitter๋ ์น ๊ทธ๋ํฝ ๊ฐ๋ฐ ๋ฐฉ์์ ํ์ ์ ๊ฐ์ ธ์ค๋ ๋ ๋๋ง ์์ง์ ๋๋ค. ์ ์ธ์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ์บ๋ฒ์ค์ SVG๋ฅผ ๋ค๋ฃจ๊ธฐ ๋๋ฌธ์, ๊ฐ๋ฐ์๋ค์ด ๋ณต์กํ ๊ทธ๋ํฝ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ ์ฝ๊ณ ํจ์จ์ ์ผ๋ก ๊ตฌํํ ์ ์๋๋ก ๋์์ค๋๋ค.
์ฌ์ค ์ด์ฏค์์ ์กฐ์ฉํ ๋ฐํ์ผ ํ ๊ฒ ๊ฐ์๋ฐ์. ์ด ๊ธ์์ ์๊ฐํ Flitter ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ๋ฐ์ Moon-DaeSeung์ ๋ฐ๋ก ์ ๋๋ค. ์๋ ๊ฐ์ธ์ ์ผ๋ก ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค์ด ์ฐ๋ ค๊ณ ํ๋๋ฐ, ์ฐจํธ ๋ง๋ค๊ธฐ๊ฐ ์๊ฐ๋ณด๋ค ๋๋ฌด ์ด๋ ค์์ ์ด ๋ ๋๋ง ์์ง๋ถํฐ ๊ฐ๋ฐํ๊ฒ ๋์์ต๋๋ค. ๊ทธ๋ฌ๋ค ๋ณด๋ ์ด๋ ๊ฒ ์คํ์์ค๋ก ๊ณต์ ํ๊ฒ ๋์๋ค์. ๊ด์ฌ ์์ผ์ ๋ถ๋ค์ ํ๋ฒ ์ฌ์ฉํด ๋ณด์๊ณ ํผ๋๋ฐฑ์ ์ฃผ์๋ฉด ์ ๋ง ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
TOAST UI: ํ๊ตญ ๊ธฐ์ ์ด ์ ๋ณด์ธ ์ธ๊ณ์ ์คํ์์ค ์ปดํฌ๋ํธ

๋ด๊ฐ ์ ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
NHN์ TOAST UI Chart๋ ์ ๊ฐ ์น ๊ฐ๋ฐ์ ํ๋ฉด์ ๊ฐ์ฅ ์ ์ฉํ๋ ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ํ๋์ ๋๋ค. ๋ค๋ฅธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก๋ ๊ตฌํํ๊ธฐ ์ด๋ ค์ ๋ ๋ณต์กํ ์ฐจํธ ์ปค์คํ (custom)๋ TOAST UI๋ก๋ ๋น๊ต์ ์ฝ๊ฒ ๊ตฌํํ ์ ์์์ต๋๋ค. ์ง์ ์ฝ๋๋ฅผ ๋ถ์ํด ๋ดค๋๋ฐ, ChartJS์ ๋นํด ์ฝ๋ ๊ตฌ์กฐ๊ฐ ํจ์ฌ ๊น๋ํ๋๋ผ๊ณ ์. ์ฌ์ค ์ด ๊ฒฝํ์ด ์ ๊ฐ ์คํ์์ค์ ๊ด์ฌ์ ๊ฐ๊ฒ ๋ ๊ณ๊ธฐ๊ฐ ๋๊ธฐ๋ ํ์ต๋๋ค. "๋๋ ์ด๋ ๊ฒ ์ข์ ์คํ์์ค๋ฅผ ๋ง๋ค์ด ๋ณด์."๋ผ๋ ์๊ฐ์ด ๋ค์์ผ๋๊น์.
์ง๊ธ์ด์ผ Toss์ overlay-kit์ด๋ WRTN์ agentica์ฒ๋ผ ํ๊ตญ ๊ธฐ์ ๋ค์ด ๋ค์ํ ์คํ์์ค๋ฅผ ์ ๋ณด์ด๋ ์๋๊ฐ ๋์์ง๋ง, TOAST UI๊ฐ ์ฒ์ ๊ณต๊ฐ๋์์ ๋น์์๋ ํ๊ตญ ๊ธฐ์ ์ด ์คํ์์ค๋ฅผ ์ฃผ๋ํ๋ค๋ ๊ฒ์ด ๋งค์ฐ ๋๋ฌธ ์ผ์ด์์ต๋๋ค. NHN์ ๋ค๋ฅธ ๊ธฐ์ ๋ค๊ณผ๋ ๋ค๋ฅธ ๊ธธ์ ์ ํํ๊ณ , TOAST UI๋ผ๋ ์ด๋ฆ์ผ๋ก ๊ณ ํ์ง์ ์น ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์คํ์์ค๋ก ๊ณต๊ฐํ์ต๋๋ค.
๋น์ ๊ตญ๋ด ๊ธฐ์ ์ด ์ด๋ ๊ฒ ๋ฐฉ๋ํ ๊ท๋ชจ์ ์คํ์์ค ํ๋ก์ ํธ๋ฅผ ๊ณต๊ฐํ๋ค๋ ๊ฒ์ ๋งค์ฐ ์ด๋ก์ ์ธ ์ผ์ด์์ต๋๋ค. ํนํ ๋จ์ํ ํ ์ด ํ๋ก์ ํธ(toy project)๊ฐ ์๋๋ผ ์ค์ ์ ํ์๋ ์ฌ์ฉํ ์ ์์ ๋งํผ ์์ฑ๋ ๋์ ์ปดํฌ๋ํธ๋ฅผ ๊ณต๊ฐํ๋ค๋ ์ ์ด ๋๋ผ์ ์ฃ .
๋ค์ฌ๋ค๋ฅํ TOAST UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ
TOAST UI๋ ๋ค์ํ ์น ๊ฐ๋ฐ ํ์๋ฅผ ์ถฉ์กฑ์ํค๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ์ ๊ณตํฉ๋๋ค. ๊ทธ์ค์์๋ ๊ฐ์ฅ ์ธ๊ธฐ ์๋ ์ปดํฌ๋ํธ๋ค์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
Chart: ๋ฐ์ดํฐ๋ฅผ ์๋๊ฐ ์๊ฒ ํํํ๋ ์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
TOAST UI Chart๋ ๋ผ์ธ, ๋ฐ, ํ์ด ์ฐจํธ ๋ฑ ๋ค์ํ ์ ํ์ ๋ฐ์ดํฐ ์๊ฐํ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋จ์ํ ์์ ์ฐจํธ๋ง ๊ทธ๋ฆฌ๋ ๊ฒ์ด ์๋๋ผ, ๋ณต์กํ ๋ฐ์ดํฐ๋ฅผ ์ง๊ด์ ์ผ๋ก ํํํ ์ ์๋ ๋ค์ํ ๊ธฐ๋ฅ์ ๊ฐ์ถ๊ณ ์์ต๋๋ค. ํนํ ์์ (Excel)๋ก ๋ฐ์ดํฐ ๋ด๋ณด๋ด๊ธฐ๋ ์ด๋ฏธ์ง๋ก ์ ์ฅํ๊ธฐ ๊ฐ์ ์ค์ฉ์ ์ธ ๊ธฐ๋ฅ๋ ํฌํจํ๊ณ ์์ด, ์ค๋ฌด์์ ๋งค์ฐ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค.
Editor: ๋งํฌ๋ค์ด๊ณผ WYSIWYG์ ๋ชจ๋ ์ง์ํ๋ ํ ์คํธ ์๋ํฐ
TOAST UI Editor๋ ๋งํฌ๋ค์ด ๋ฌธ์๋ฅผ ํ ์คํธ์ WYSIWYG(What You See Is What You Get) ๋ชจ๋๋ก ๋์์ ํธ์งํ ์ ์๊ฒ ํด์ค๋๋ค. ๊ตฌ๋ฌธ ๊ฐ์กฐ, ์คํฌ๋กค ๋๊ธฐํ, ์ค์๊ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ฑ์ ๊ธฐ๋ฅ์ ๊ฐ์ถ๊ณ ์์ด ๋ฌธ์ ์์ฑ ๊ฒฝํ์ ํ์ธต ํฅ์์ํต๋๋ค. ๋ํ ์ฐจํธ ์ฝ์ ๋ ์ง์ํ์ฌ ๋ฐ์ดํฐ ์๊ฐํ์ ๋ฌธ์ ์์ฑ์ ํ ๊ณณ์์ ํ ์ ์์ต๋๋ค.
Grid: ๊ฐ๋ ฅํ ๋ฐ์ดํฐ ๊ทธ๋ฆฌ๋ ์๋ฃจ์
TOAST UI Grid๋ ๋๋์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ํ์ํ๊ณ ๊ด๋ฆฌํ ์ ์๋ ๊ทธ๋ฆฌ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๋ฐ์ดํฐ ํธ์ง, ํํฐ๋ง, ์ ๋ ฌ, ํ์ด์ง๋ค์ด์ ๋ฑ์ ๊ธฐ๋ฅ์ ๋ฌผ๋ก , ๋ค์ํ cell editor์ renderer๋ฅผ ํตํด ์ํ๋ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํ์ํ๊ณ ํธ์งํ ์ ์์ต๋๋ค. ํนํ ๋ณต์กํ ํ ์ด๋ธ ํํ์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ง๊ฐ๋ฅผ ๋ฐํํฉ๋๋ค.
Calendar: ์ง๊ด์ ์ธ ์ผ์ ๊ด๋ฆฌ ๋๊ตฌ
TOAST UI Calendar๋ ์๊ฐ, ์ฃผ๊ฐ, ์ผ๊ฐ ๋ทฐ(view) ๋ฑ ๋ค์ํ ์บ๋ฆฐ๋ ๋ณด๊ธฐ ๋ฐฉ์์ ์ ๊ณตํฉ๋๋ค. ๊ธฐ๋ณธ ํ์ UI๋ฅผ ํตํด ์ผ์ ์ถ๊ฐ, ํธ์ง ๋ฐ ์ญ์ ๋ฅผ ์ฝ๊ฒ ํ ์ ์์ผ๋ฉฐ, ๋๋๊ทธ ์ค ๋๋กญ(drag and drop)์ผ๋ก ์ผ์ ์ ๊ฐํธํ๊ฒ ์ด๋ํ ์๋ ์์ต๋๋ค. ๋ณต์กํ ์ผ์ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ํ์๋ก ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด์์ ์ธ ์๋ฃจ์ ์ ๋๋ค.
Image-editor: ๋ค์ํ ๊ธฐ๋ฅ์ ๊ฐ์ถ ์ด๋ฏธ์ง ํธ์ง๊ธฐ
์ฌํํ๋ฉด์๋ ์๋ฆ๋ค์ด UI๋ฅผ ๊ฐ์ง TOAST UI Image-editor๋ ํธ์ง, ๊ทธ๋ฆฌ๊ธฐ, ํ ์คํธ ์ ๋ ฅ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๋ํ ๋ค์ํ ์ด๋ฏธ์ง ํํฐ๋ฅผ ์ ์ฉํ ์ ์์ด ์น์์ ๋ฐ๋ก ์ด๋ฏธ์ง๋ฅผ ํธ์งํ๊ณ ๊ฐ๊ณตํ ์ ์์ต๋๋ค.
๊ทธ ์ธ ๋ค์ํ ์ปดํฌ๋ํธ
TOAST UI๋ ์์ ์ฃผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ธ์๋ ๋ค์๊ณผ ๊ฐ์ ๋ค์ํ ์ปดํฌ๋ํธ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- App Loader:๋ชจ๋ฐ์ผ ๊ธฐ๊ธฐ์์ ํน์ ์ฑ์ ๋ก๋ํ๊ฑฐ๋ ์ค์น
- Auto Complete: ์ ๋ ฅ ํ ์คํธ์ ๋ฐ๋ฅธ ์๋ ์์ฑ ๊ธฐ๋ฅ
- Color Picker: ์ง๊ด์ ์ธ ์์ ์ ํ ๋๊ตฌ
- Context Menu: ์ฌ์ฉ์ ์ ์ ์ปจํ ์คํธ ๋ฉ๋ด
- Date Picker: ๋ ์ง ์ ํ ์ปดํฌ๋ํธ
- Pagination: ํ์ด์ง ์ด๋ ์ปดํฌ๋ํธ
- Rolling: ์บ๋ฌ์ ์ปดํฌ๋ํธ
- Select Box: ์ ํ ์์
- Time Picker: ์๊ฐ ์ ํ ์ปดํฌ๋ํธ
- Tree: ๊ณ์ธต ๊ตฌ์กฐ ๋ฐ์ดํฐ ํํ ์ปดํฌ๋ํธ
๊ณ ํ์ง์ ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
TOAST UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ค ํ๋๋ ๊น๋ํ ์ฝ๋ ๊ตฌ์กฐ์ ๋์ ํ์ฅ์ฑ์ ๋๋ค. ํนํ Chart ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ChartJS์ ๊ฐ์ ์ ์ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ณด๋ค ์ฝ๋๊ฐ ์ ์ ๋๋์ด ์์ด ์ปค์คํฐ๋ง์ด์ง(customizing)ํ๊ธฐ ์ฝ์ต๋๋ค.
TOAST UI์ ์ฑ๊ณต์ ํ๊ตญ ๊ธฐ์ ๋ค์ด ์คํ์์ค๋ฅผ ํตํด ๊ธ๋ก๋ฒ ๊ฐ๋ฐ ์ํ๊ณ์ ๊ธฐ์ฌํ ์ ์๋ค๋ ๊ฐ๋ฅ์ฑ์ ์ด์์ต๋๋ค. ์ด์ ๋ง์ ํ๊ตญ ๊ธฐ์ ๋ค์ด ์คํ์์ค๋ฅผ ํ๋ฐํ๊ฒ ๊ณต๊ฐํ๊ณ ์์ง๋ง, TOAST UI๊ฐ ๊ทธ ์ฒซ ๊ฑธ์์ ๋ด๋๋ ๋ค๋ ์ ์์ ๊ทธ ์๋ฏธ๋ ํน๋ณํฉ๋๋ค.
nn: ๋ฅ๋ฌ๋ ๊ฐ๋ฐ์ ์ํ ์คํ์ ์ธ์ด

<์ถ์ฒ: ์๊ฐ ์บก์ฒ>
์๋ก์ด ๋ถ์ผ์ ์คํ์์ค ๋์
์ต๊ทผ ์คํ์์ค ์ธ๊ณ๋ฅผ ๋ณด๋ฉด ๋ธ๋ก์ฒด์ธ ๋ถ์ผ์์ Solidity๋ Move ๊ฐ์ ํนํ ์ธ์ด๊ฐ ๋ฑ์ฅํ๊ณ ์์ต๋๋ค. ๋๋ถ๋ถ ๋ํ ํ์ด๋ ๊ธฐ์ ๋ค์ด ์ฃผ๋ํ๋ ํ๋ก์ ํธ๋ค์ด์ฃ . ๊ทธ๋ฐ๋ฐ ์ด์๋ ๋ค๋ฅธ ์์ญ์์ ํฅ๋ฏธ๋กญ๊ณ ์คํ์ ์ธ ์ธ์ด๊ฐ ์กฐ์ฉํ ๊ฐ๋ฐ๋๊ณ ์์ต๋๋ค. ๋ฐ๋ก ๊นํ๋ธ(GitHub) ID 'SieR-VR'๋ก ํ๋ํ๋ ๊ฐ๋ฐ์๊ฐ ๋ง๋ค๊ณ ์๋ 'nn'์ด๋ผ๋ ๋ฅ๋ฌ๋ ํนํ ์ธ์ด์ ๋๋ค.
์ฌ์ค ์๋ก์ด ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ๋ง๋๋ ์ผ์ ์ฌ์ด ๋์ ์ด ์๋๋๋ค. ๊ทธ๋ผ์๋ ์ด๋ฐ ์๋๊ฐ ๋์จ ๋ฐฐ๊ฒฝ์๋ ๋ฅ๋ฌ๋ ๊ฐ๋ฐ ๊ณผ์ ์์ ๊ฐ๋ฐ์๋ค์ด ์ค์ ๋ก ๊ฒช๋ ๋ถํธํจ์ด ์กด์ฌํฉ๋๋ค.
๋ฅ๋ฌ๋ ๊ฐ๋ฐ์์ ๊ณ ์ถฉ: "์ด ํ ์์ ๋ชจ์์ด ๋ญ์๋๋ผ?"
๋ฅ๋ฌ๋ ๋ชจ๋ธ์ ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ํญ์ ๋ถ๋ชํ๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ฐ๋ก ํ ์์ ๋ชจ์(shape)์ ์ถ์ ํ๋ ์ผ์ ๋๋ค.
x = torch.randn(64, 64, 3) ์ด๋ฏธ์ง ํ
์
x = x.permute(2, 0, 1).unsqueeze(0) ์ฐจ์ ์ฌ๋ฐฐ์ด
x = model(x) ๋ชจ๋ธ ํต๊ณผ
์ฌ๊ธฐ์ x์ ๋ชจ์์?
PyTorch๋ TensorFlow์์๋ ์ฝ๋๋ฅผ ์คํํด๋ณด๊ธฐ ์ ๊น์ง๋ ํ ์์ ์ต์ข ๋ชจ์์ ์ ํํ ์๊ธฐ ์ด๋ ต์ต๋๋ค. ํนํ ์ฌ๋ฌ ๋ ์ด์ด๋ฅผ ๊ฑฐ์น๋ฉด์ reshape, transpose ๋ฑ์ ์ฐ์ฐ์ด ์ถ๊ฐ๋๋ฉด ์ถ์ ์ด ๋์ฑ ์ด๋ ค์์ง๋๋ค.
nn ์ธ์ด: ์ปดํ์ผ ํ์์ ๋ชจ์ ์ฒดํฌ
SieR-VR์ด ๊ฐ๋ฐ ์ค์ธ nn ์ธ์ด๋ ์ด ๋ฌธ์ ๋ฅผ ์ ๋ฉด์ผ๋ก ํด๊ฒฐํฉ๋๋ค. ์ฝ๋๋ฅผ ์คํํ๊ธฐ๋ ์ ์, ์ปดํ์ผ ๋จ๊ณ์์ ๋ชจ๋ ํ ์์ ๋ชจ์์ ๊ณ์ฐํ๊ณ ๊ฒ์ฆํ ์ ์์ต๋๋ค.
// nn ์ธ์ด ์์
x: Tensor[64, 64, 3]; // ์ด๋ฏธ์ง ํ
์
// ํฉ์ฑ๊ณฑ ๋ ์ด์ด ์ ์ฉ (์ปค๋ 3x3, ํจ๋ฉ 1, ์คํธ๋ผ์ด๋ 1, ์ถ๋ ฅ ์ฑ๋ 16)
y = Conv2D[3, 1, 1, 16](x);
// ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก ๊ณ์ฐ: y์ ํ์
์ Tensor[64, 64, 16]
์ด ๊ฐ๋จํ ์์๋ง์ผ๋ก๋ nn ์ธ์ด์ ๊ฐ๋ ฅํจ์ด ๋๋ฌ๋ฉ๋๋ค. Conv2D ์ฐ์ฐ ํ ํ ์์ ๋ชจ์์ด ์ด๋ป๊ฒ ๋ณํ ์ง ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก ๊ณ์ฐํด์ฃผ๊ธฐ ๋๋ฌธ์, ๊ฐ๋ฐ์๋ ๋ ์ด์ ๋ณต์กํ ์์์ ๋จธ๋ฆฟ์์ผ๋ก ๊ณ์ฐํ ํ์๊ฐ ์์ต๋๋ค.
// ์ข ๋ ๋ณต์กํ ์์
x: Tensor[64, 64, 3];
conv = Conv2D[5, 0, 1, 32](x); // ํจ๋ฉ ์๋ 5x5 ์ปค๋
// ์ถ๋ ฅ ๋ชจ์: Tensor[60, 60, 32] - ์ปดํ์ผ๋ฌ๊ฐ ์๋ ๊ณ์ฐ
pool = MaxPool2D[2, 2](conv); // 2x2 ํ๋ง
// ์ถ๋ ฅ ๋ชจ์: Tensor[30, 30, 32] - ์ปดํ์ผ๋ฌ๊ฐ ์๋ ๊ณ์ฐ
์คํ ์ ์ ์ด๋ฌํ ๋ชจ์ ๊ฒ์ฆ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์, ์คํ ์๊ฐ์ ๋ฐ์ํ ์ ์๋ ๋ชจ์ ๋ถ์ผ์น ์ค๋ฅ๋ฅผ ์ฌ์ ์ ๋ฐฉ์งํ ์ ์๋ค๋ ์๋ฏธ์ ๋๋ค. ๋ฅ๋ฌ๋ ๊ฐ๋ฐ ๊ณผ์ ์์ ๊ฐ์ฅ ํํ๊ฒ ๋ฐ์ํ๋ ์ค๋ฅ ์ ํ์ ์์ฒ์ ์ผ๋ก ์ฐจ๋จํ๋ ์ ์ด์ฃ .
ํ๋กํ ํ์ ์์ ์ธ์ด๋ก
nn ์ธ์ด๋ ์ฒ์๋ถํฐ ์ธ์ด๋ก ์์๋ ๊ฒ์ด ์๋๋๋ค. SieR-VR์ ์ฒ์์ C++์ ํ ํ๋ฆฟ ์์คํ ์ ํ์ฉํด StaticNet์ด๋ผ๋ ํ๋กํ ํ์ ์ ๊ฐ๋ฐํ์ต๋๋ค. ์ด๋ฅผ ํตํด ์ปดํ์ผ ํ์์ ํ ์ ๋ชจ์์ ์ถ์ ํ๋ ์์ด๋์ด๋ฅผ ๊ฒ์ฆํ์ฃ . ํ์ง๋ง C++ ํ ํ๋ฆฟ์ ํ๊ณ๋ก ์ธํด, ํ์ ๊ณ์ฐ ์๋๊ฐ ๋๋ฆฌ๊ณ ์ถ๋ก ๊ธฐ๋ฅ์ด ์ ํ์ ์ด์์ต๋๋ค. ์ดํ TypeScript ์ปดํ์ผ๋ฌ ๊ด๋ จ ์์ ์ ํ๋ฉฐ ์ป์ ๊ฒฝํ์ ๋ฐํ์ผ๋ก, ์์ ์๋ก์ด ์ธ์ด๋ฅผ ๋ง๋ค๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
ํ๊ตญ ์คํ์์ค์ ์๋ก์ด ์งํ
ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ๊ฐ๋ฐํ๋ ๊ฒ์ ๊ฑฐ๋ ๊ธฐ์ ์ด๋ ์ฐ๊ตฌ ๊ธฐ๊ด, ํน์ ์์ญ ๋ช ์ ๊ฐ๋ฐ์๊ฐ ์ฐธ์ฌํ๋ ๋ํ ์คํ์์ค ํ๋ก์ ํธ์์๋ ์๋ํ๋ ์ผ๋ก ์ฌ๊ฒจ์ ธ ์์ต๋๋ค. ํ์ง๋ง nn ์ธ์ด๋ ํ๊ตญ์ ๊ฐ์ธ ๊ฐ๋ฐ์๊ฐ ์ค์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์์ํ ํ๋ก์ ํธ์ ๋๋ค.
nn ์ธ์ด๊ฐ ํฅ๋ฏธ๋ก์ด ์ ์ LSP(Language Server Protocol) ์ง์๋ ํจ๊ป ๊ฐ๋ฐ๋๊ณ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ Visual Studio Code์ ๊ฐ์ ์๋ํฐ์์ ์ฝ๋ ์๋ ์์ฑ์ด๋ ์ค๋ฅ ํ์ ๊ฐ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๊ธฐ์ ์ธ๋ฐ, ์ด ์ ๋ ๊ท๋ชจ์ ์ด๊ธฐ ํ๋ก์ ํธ์์ ๋ณผ ์ ์๋ ๊ฒ์ ์๊ฐ๋ณด๋ค ๋๋ฌธ ์ผ์ ๋๋ค.
์ฌ์ค SieR-VR์ ์ ๊ฐ ์ผํ๋ ํ์ฌ์ ํ์์ด๊ธฐ๋ ํฉ๋๋ค. ์์ง ๋ง์ด ์๋ ค์ง์ง ์์ ์ด๊ธฐ ๋จ๊ณ์ ํ๋ก์ ํธ์ง๋ง, ๊พธ์คํ ๊ฐ๋ฐ ์ค์ธ ๊ฒ์ผ๋ก ์๊ณ ์์ต๋๋ค. ๊ด์ฌ ์์ผ์ ๋ถ๋ค์ GitHub์์ ํ๋ก์ ํธ ์งํ ์ํฉ์ ํ์ธํด๋ณด์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
๋ค์ํด์ง๋ ํ๊ตญ ์คํ์์ค
nn ์ธ์ด๋ ํ๊ตญ ์คํ์์ค ์ํ๊ณ์ ๋ ํ๋์ ๋ค์์ฑ์ ๋ํด์ฃผ๊ณ ์์ต๋๋ค. ์ง๊ธ๊น์ง ์๊ฐํ ๋ค๋ฅธ ํ๋ก์ ํธ๋ค์ด ์ฃผ๋ก ์น ๊ฐ๋ฐ ์์ญ์ ์ง์ค๋์๋ค๋ฉด, nn์ ๋ฅ๋ฌ๋์ด๋ผ๋ ์กฐ๊ธ ๋ค๋ฅธ ๋ถ์ผ์์์ ์๋๋ผ๋ ์ ์์ ๋์ฑ ๋ฐ๊ฐ์ต๋๋ค. ๋ฌผ๋ก ์์ง์ ์ด๊ธฐ ๋จ๊ณ์ด๊ณ ๊ฐ ๊ธธ์ด ๋ฉ๊ฒ ์ง๋ง, ์ด๋ฐ ๋ค์ํ ์๋๋ค์ด ๋ชจ์ฌ ํ๊ตญ ์คํ์์ค ์ํ๊ณ๊ฐ ์ ์ ๋ ํ์ฑํด์ง๊ณ ์๋ค๋ ์๊ฐ์ด ๋ญ๋๋ค. ์์ผ๋ก์ ๋ฐ์ ๊ณผ์ ์ด ๊ธฐ๋๋๋ ํ๋ก์ ํธ์ ๋๋ค.
์ธ์์ ๋ฐ๊พธ๋ ์์ ์์, ์คํ์์ค
"๋ด๊ฐ ๋ง๋ ์ฝ๋๊ฐ ๊ณผ์ฐ ๋๊ตฐ๊ฐ์๊ฒ ๊ฐ์น๊ฐ ์์๊น?" ๋ง์ ๊ฐ๋ฐ์๋ค์ด ์คํ์์ค๋ฅผ ์์ํ๊ธฐ ์ ๊ฐ๋ ์๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ด ๊ธ์์ ์๊ฐํ ํ๋ก์ ํธ๋ค์ ์ด๋ฐ ์๋ฌธ์ ๋์ง ๊ฐ๋ฐ์๋ค์ด ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ์์ ์ ์ฝ๋๋ฅผ ์ธ์๊ณผ ๊ณต์ ํ์ ๋, ์ด๋ค ๋๋ผ์ด ์ผ์ด ์ผ์ด๋ ์ ์๋์ง ์ ๋ณด์ฌ์ค๋๋ค.
์คํ์์ค ํ๋ก์ ํธ๋ฅผ ์์ํ๋ฉด ์์์น ๋ชปํ ์ฌ๋ฌ ๊ฐ์ง ์ ๋ฌผ์ ๋ฐ๊ฒ ๋ฉ๋๋ค.
๊ธ๋ก๋ฒ ํผ๋๋ฐฑ์ ๋น์ ์ ์ฝ๋๋ฅผ ๋ ๊ฒฌ๊ณ ํ๊ฒ ๋ง๋ญ๋๋ค.
ํผ์์๋ ์์ํ ์ ์์๋ ๋ฒ๊ทธ์ ๊ฐ์ ์ ์ ์ ์ธ๊ณ ๊ฐ๋ฐ์๋ค์ด ์ฐพ์์ฃผ๊ณ , ๋๋ก๋ ์ง์ ์์ ๊น์ง ํด์ค๋๋ค. ์ด๋ณด๋ค ๋ ์ข์ ์ฝ๋ ๋ฆฌ๋ทฐ๊ฐ ์์๊น์?
๊ฐ๋ฐ์๋ก์์ ์ฑ์ฅ์ ์์ฐ์ค๋ฝ๊ฒ ๋ฐ๋ผ์ต๋๋ค.
๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ ์ง๋ฌธ์ ๋ตํ๊ณ , ์ด์๋ฅผ ํด๊ฒฐํ๊ณ , PR์ ๊ฒํ ํ๋ ๊ณผ์ ์์ ์์ ๋ ๋ชจ๋ฅด๊ฒ ์ ๋ฌธ์ฑ์ด ์์ ๋๋ค. ์คํ์์ค ํ๋ก์ ํธ๋ ์ต๊ณ ์ ํ์ต ํ๋ซํผ์ ๋๋ค.
์ปค๋ฆฌ์ด์ ๋์ฝ๋๊ฐ ๋ ์๋ ์์ต๋๋ค.
์ด ๊ธ์์ ์๊ฐํ ๋ง์ ๊ฐ๋ฐ์๋ค์ ์์ ์ ์คํ์์ค ํ๋ก์ ํธ๋ฅผ ํตํด ๊ธ๋ก๋ฒ ๊ธฐ์ ์ ์์ ์ ์์ ๋ฐ๊ฑฐ๋, ์ ๊ณ์์ ์ธ์ ๋ฐ๋ ์ ๋ฌธ๊ฐ๊ฐ ๋์์ต๋๋ค. ๋น์ ์ GitHub๋ ์ด๋ค ์ด๋ ฅ์๋ณด๋ค ๊ฐ๋ ฅํ ํฌํธํด๋ฆฌ์ค๊ฐ ๋ ์ ์์ต๋๋ค.
์์์ ์๊ฒ, ์ฑ์ฅ์ ํจ๊ป
์คํ์์ค๋ฅผ ์์ํ๋ ๋ฐ ๊ฑฐ์ฐฝํ ์์ด๋์ด๋ ์๋ฒฝํ ๊ตฌํ์ด ํ์ํ์ง ์์ต๋๋ค. ๋๋ก๋ ์์ ์ด ๋งค์ผ ๋ถ๋ช์น๋ ์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋๊ตฌ๊ฐ ๋ค๋ฅธ ๋ง์ ๊ฐ๋ฐ์๋ค์๊ฒ ํฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
Flitter์ ๊ฐ์ ํ๋ก์ ํธ๋ ์ฒ์์๋ ๊ฐ์ธ์ ์ธ ํ์์์ ์์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. "์ฐจํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค๋ ค๋ค๊ฐ ์๊ฐ๋ณด๋ค ์ด๋ ค์์ ๋ ๋๋ง ์์ง๋ถํฐ ๋ง๋ค๊ฒ ๋" ๊ฒ์ฒ๋ผ, ๋๋ก๋ ์์์น ๋ชปํ ๋ฐฉํฅ์ผ๋ก ๋ฐ์ ํ๊ธฐ๋ ํฉ๋๋ค. ์๋ฒฝ์ ์ถ๊ตฌํ๊ธฐ๋ณด๋ค๋ ์์ ๊ฒ๋ถํฐ ์์ํ๊ณ ์ปค๋ฎค๋ํฐ์ ํจ๊ป ์ฑ์ฅํด ๋๊ฐ๋ ๊ณผ์ ์ด ์คํ์์ค์ ๋งค๋ ฅ์ ๋๋ค.
์ธ์์ด ๋น์ ์ ์ฝ๋๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค
"๋ด ์ฝ๋๊ฐ ๊ณผ์ฐ ๊ฐ์น๊ฐ ์์๊น?"
์ด๋ฐ ์๋ฌธ์ ์ด์ ์ด๋ ๊ฒ ๋ฐ๊ฟ ์๊ฐํด ๋ณด๋ฉด ์ด๋จ๊น์?
"๋ด๊ฐ ํด๊ฒฐํ ๋ฌธ์ ๋ฅผ ๋ค๋ฅธ ๋๊ตฐ๊ฐ๋ ๊ฒช๊ณ ์์ง ์์๊น?"
๋น์ ์ด ์ง๋ฉดํ ๋ฌธ์ , ๋น์ ์ด ๋ฐ๊ฒฌํ ํด๊ฒฐ์ฑ , ๋น์ ๋ง์ ๋ ํนํ ๊ด์ ์ ๋๊ตฐ๊ฐ์๊ฒ ์๊ฐ์ด ๋๊ณ ๋์์ด ๋ ์ ์์ต๋๋ค. ๊ทธ๊ฒ์ด ์ ์ธ๊ณ ์์ฒ ๋ช ์ ๊ฐ๋ฐ์๋ค์ด ์ฌ์ฉํ๋ ๊ฑฐ๋ํ ํ๋ก์ ํธ๋ก ์ฑ์ฅํ ์๋ ์๊ณ , ๋จ ํ ๋ช ์ ๊ฐ๋ฐ์์๊ฒ "์ํ!" ์๊ฐ์ ์ ์ฌํ๋ ์์ ๋๊ตฌ์ ๊ทธ์น ์๋ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ ๊ฐ์น๋ ๊ฒฐ์ฝ ์์ง ์์ต๋๋ค.
์คํ์์ค๋ ๊ธฐ์ ์ ์๋ฃจ์ ์ ๋์ด '๊ณต์ '์ 'ํ๋ ฅ'์ ๋ฌธํ๋ฅผ ํ์ฑํฉ๋๋ค. ์ง์๊ณผ ๊ฒฝํ์ ๋๋๋ ์์ ํ๋๋ค์ด ๋ชจ์ฌ K-์คํ์์ค์ ๋ฏธ๋๋ฅผ ๋ง๋ค์ด๊ฐ๊ณ , ์ด์ฉ๋ฉด ์ ์ธ๊ณ ๊ฐ๋ฐ์ ์ํ๊ณ์๋ ์๋ฏธ ์๋ ๋ณํ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ง ์์๊น ๊ธฐ๋ํด ๋ด ๋๋ค. ์กฐ๊ธ์ด๋ผ๋ ๊ด์ฌ์ด ์๊ฒผ๋ค๋ฉด ์ฉ๊ธฐ๋ฅผ ๋ด์ด ์ฒซ ๊ฑธ์์ ๋ผ์ด๋ณด๋ ๊ฒ๋ ์ข๊ฒ ์ต๋๋ค. ๋๊ตฐ๊ฐ์๊ฒ ๋น์ ์ ์ฝ๋๊ฐ ํฐ ๋์์ด ๋ ์ง๋ ๋ชจ๋ฅด๋๊น์.