# Flutter๋ž€?

# What is Flutter?

Mobile World Congress 2018์—์„œ Flutter์˜ ์ตœ์ดˆ ๋ฒ ํƒ€ ๋ฆด๋ฆฌ์Šค๋ฅผ ๋ฐœํ‘œํ•˜์˜€๊ณ  Google์—์„œ ์ƒˆ๋กญ๊ฒŒ ์„ ๋ณด์ด๋Š” ๋ชจ๋ฐ”์ผ UI ํ”„๋ ˆ์ž„์›Œํฌ์ด๋ฉฐ, ๊ฐœ๋ฐœ์ž๊ฐ€ iOS์™€ Android ๋ชจ๋‘๋ฅผ ์œ„ํ•œ ๊ณ ํ’ˆ์งˆ ๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ์ž‘ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ ํ”„๋ ˆ์ž„์›Œํฌ ์ž…๋‹ˆ๋‹ค.

  • [x] IOS
  • [x] Android
  • [x] Any Web App

Dart ์–ธ์–ด๋กœ ๋ชจ๋‘ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

# Dart๋ž€?

Dart๋Š” ๊ตฌ๊ธ€์—์„œ ๋งŒ๋“  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋กœ Flutter๋ฅผ ์ž‘์„ฑํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋์Šต๋‹ˆ๋‹ค.
Dart๋Š” ๊ตฌ๊ธ€์ด server side๋ฐ front-end์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š”๋ฐ Javascript ๋ณด๋‹ค ๋” ๋‚˜์€ ์–ธ์–ด๋ฅผ ์›ํ–ˆ๊ธฐ์— ๋งŒ๋“ค์–ด ์กŒ์Šต๋‹ˆ๋‹ค.

์ œ๊ฐ€ ์•Œ๊ธฐ๋กœ๋Š”, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ๋Š” ์Šน์ธ์„ ์œ„ํ•œ ๊ฑฐ๋Œ€ ์œ„์›ํšŒ์™€ ์ด๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ ๋ธŒ๋ผ์šฐ์ € ๊ณต๊ธ‰์—…์ฒด์— ์˜์กดํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋Š๋ฆฌ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ตฌ๊ธ€์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ• ์ง€ ๋ง์ง€์— ๋Œ€ํ•œ ์ผ๋ จ์˜ ๊ฒฐ์ • ํ›„์— ์˜๋ฏธ์ ์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋งž๋Š” ์–ธ์–ด๋ฅผ ๋งŒ๋“ค๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•˜์ž๋ฉด Dart์—์„œ ์ž‘์„ฑ๋˜๋Š” ๋ชจ๋“  ๊ฒƒ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ปดํŒŒ์ผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ๊ตฌ๊ธ€์ด Java๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด ์–ธ์–ด๋ฅผ ๊ฐœ๋ฐœํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ข‹์€ ์†Œ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹คํŠธ๋Š” safe ์–ธ์–ด๋ฅผ ๋ฐฐ์šฐ๋Š” ๋ฐ ํƒ์›”ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ๊ธ€์€ Dart๋กœ ์–ด๋–ค ํ˜์‹ ์ ์ธ๊ฒƒ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์‹œ์ž‘ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๋‹จ์ˆœํ•˜๊ณ  ์ƒ์‚ฐ์ ์ด๋ฉฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ปดํŒŒ์ผ ๋  ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด๋ฅผ ๋งŒ๋“ค๊ณ ์ž ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ๋ฌธ์—๋Š” ํŠน๋ณ„ํžˆ ํฅ๋ฏธ๋กœ์šด๊ฒƒ๋„ ์—†์œผ๋ฉฐ ์—ฌ๋Ÿฌ๋ถ„์„ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ํ•  ํŠน๋ณ„ํ•œ ์—ฐ์‚ฐ์ž๋„ ์—†์Šต๋‹ˆ๋‹ค.
Dart(์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€๋Š” ๋‹ฌ๋ฆฌ)์—๋Š” true์™€ false๋ฅผ ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ๋งŒ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋‹ค์Œ์€ true๋กœ ์ธ์‹๋ฉ๋‹ˆ๋‹ค.

if (3) { ... }

๋‹คํŠธ์—์„  ์œ„ ์ฒ˜๋Ÿผ ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ์—‰๋ง์ด ๋ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‹คํŠธ์˜ ํ•ต์‹ฌ์€ ์ƒ์‚ฐ์ ์ด๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๋ฉฐ ๊ฐ„๋‹จํ•œ ์–ธ์–ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค, ์™œ๋ƒํ•˜๋ฉด ํ”Œ๋Ÿฌํ„ฐ์—์„œ ์•ฑ์„ ์ž‘์„ฑํ•˜๋Š”๊ฒƒ์€ ๋‹จ์ˆœํžˆ ๋‹คํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ”Œ๋Ÿฌํ„ฐ๋Š” ํ•˜๋ถ€์— ๋‹คํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํด๋ž˜์Šค๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

markup ์–ธ์–ด์™€ ๊ด€๋ จ๋๊ฑฐ๋‚˜ JSX์Šคํƒ€์ผ์˜ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์–ธ์–ด๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ”„๋ก ํŠธ ์—”๋“œ ์ฝ”๋“œ๋Š” ๋‹คํŠธ๋กœ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. No HTML, No CSS.

# Flutter๊ฐ€ Dart๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š”?

๋งŒ์•ฝ ์—ฌ๋Ÿฌ๋ถ„์ด ๋‹ค๋ฅธ ๊ธฐ์ˆ ๋ฐฐ๊ฒฝ์„ ์‚ฌ์šฉํ•ด๋ดค๋‹ค๋ฉด ์•„๋งˆ๋„ ํ”Œ๋Ÿฌํ„ฐ๊ฐ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ๋‹คํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์— ๋Œ€ํ•ด ๋ถˆํ‰ํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ์„ ํƒ์— ํšŒ์˜์ ์ธ ์ด์œ ๋Š” ์žˆ์Šต๋‹ˆ๋‹ค. Dart๊ฐ€ ์˜ค๋Š˜๋‚  ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” 25๊ฐœ ์–ธ์–ด์— ํฌํ•จ๋˜์ง€ ์•Š๋Š” ์ธ๊ธฐ ์—†๋Š” ์–ธ์–ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. โ€œ๋ญ๋ผ๊ตฌ์š”? ๊ตฌ๊ธ€์ด ์ž์‚ฌ ์–ธ์–ด๋ผ์„œ ์‚ฌ์šฉํ–ˆ๋‹ค๊ตฌ์š”?โ€ ์ €๋Š” ๊ทธ๊ฒƒ๋„ ๋งž๋Š” ์†Œ๋ฆฌ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์‹ค์šฉ์ ์ธ ์ด์œ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹คํŠธ๋Š” JIT(Just In Time)์ปดํŒŒ์ผ๊ณผ AOT(Ahead Of Time)์ปดํŒŒ์ผ์„ ๋ชจ๋‘ ์ง€์›ํ•œ๋‹ค.
    • AOT์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋‹คํŠธ์ฝ”๋“œ๋ฅผ ํšจ์œจ์ ์ธ native ์ฝ”๋“œ๋กœ ๋ฐ”๊พผ๋‹ค. ์ด๊ฒƒ์€ ํ”Œ๋Ÿฌํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋งŒ๋“ค์ง€๋งŒ, ๊ฑฐ์˜ ๋ชจ๋“  ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋‹คํŠธ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Œ์„ ์˜๋ฏธ ํ•œ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„ ์ฆ‰ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ชจ๋“  ๊ฒƒ์„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
    • ๋‹คํŠธ์˜ ์˜ต์…˜์ธ JIT์ปดํŒŒ์ผ์€ hot-reloading์„ ๊ฐ€๋Šฅ์ผ€ ํ•œ๋‹ค. ๋น ๋ฅธ ๊ฐœ๋ฐœ๊ณผ ๋ฐ˜๋ณต์€ ํ”Œ๋Ÿฌํ„ฐ ์‚ฌ์šฉ ์ฆ๊ฑฐ์›€์˜ ํ•ต์‹ฌ์ด๋‹ค. ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ์— ์ฝ”๋“œ๋ฅผ ์ €์žฅํ•˜๋ฉด ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์ƒ์˜ ์•ฑ์ด 1์ดˆ ์ด๋‚ด์— ์—…๋ฐ์ดํŠธ ๋œ๋‹ค.
  • ๋‹คํŠธ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ์ด๋‹ค. ์ด๊ฒƒ์€ ๋‹คํŠธ๋งŒ์œผ๋กœ ์‹œ๊ฐ์  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜(UX)์„ ์‰ฝ๊ฒŒ ์ž‘์„ฑ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, markup language๋Š” ํ•„์š”์น˜ ์•Š๋‹ค.
  • ๋‹คํŠธ๋Š” ์ƒ์‚ฐ์ ์ด๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ์–ธ์–ด์ด๋‹ค. ๋ฐฐ์šฐ๊ธฐ ์‰ฝ๊ณ  ์นœ์ˆ™ํ•˜๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์ด ๋™์ ์–ธ์–ด(dynamic language)๋ฅผ ์‚ฌ์šฉํ•ด ์™”๋“  ์ •์ ์–ธ์–ด(static language)๋ฅผ ์‚ฌ์šฉํ•ด ์™”๋“  ์‰ฝ๊ฒŒ ์‹œ์ž‘ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ๊ฐ™์€ ํšŒ์‚ฌ์—์„œ ๋งŒ๋“  ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ๋งค๋ ฅ์ ์ด๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค๊ธฐ๋„ ํ•œ๋‹ค. ์™œ๋ƒ๋ฉด ํ”Œ๋Ÿฌํ„ฐ ํŒ€์€ ๋‹คํŠธ ํŒ€๊ณผ ๊ธด๋ฐ€ํžˆ ํ˜‘๋ ฅํ•˜์—ฌ ํ•„์š”๋กœ ํ•˜๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

# Why Flutter?

Flutter๊ณต๋ถ€์— ์•ž์„œ ๊ถ๊ธˆํ•œ ์ ์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค.
Flutter๋Š” ์–ด๋–ค ์ƒˆ๋กญ๊ณ  ํฅ๋ฏธ๋กœ์šด ์ ์ด ์žˆ์„๊นŒ์š”?

๋จผ์ € ์ด์ „ ๋ชจ๋ฐ”์ผ ์•ฑ ๊ฐœ๋ฐœ์˜ ๊ฐ„๋žตํ•œ ์—ญ์‚ฌ๋ฅผ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

# ๋ชจ๋ฐ”์ผ ์•ฑ ๊ฐœ๋ฐœ์˜ ๊ฐ„๋žตํ•œ ์—ญ์‚ฌ

๋ชจ๋ฐ”์ผ ์•ฑ ๊ฐœ๋ฐœ ๋ถ„์•ผ๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ์ตœ์‹  ๋ถ„์•ผ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋“ค์ด ๋ชจ๋ฐ”์ผ ์•ฑ์„ ๊ฐœ๋ฐœํ•œ์ง€ ๋ฏธ์ฒ˜ 10๋…„์ด ๋˜์ง€ ์•Š์•˜๊ณ , ์ด๋ฅผ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๊ฐœ๋ฐœ ๋„๊ตฌ๋“ค์ด ์—ฌ์ „ํžˆ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ๊ทธ๋‹ค์ง€ ๋†€๋ผ์šด ์‚ฌ์‹ค์€ ์•„๋‹™๋‹ˆ๋‹ค.

# OEM SDKs

์• ํ”Œ์€ iOS SDK๋ฅผ 2008๋…„์— ๋ฆด๋ฆฌ์ฆˆํ–ˆ๊ณ , ๊ตฌ๊ธ€์€ Android SDK๋ฅผ 2009๋…„์— ๋ฆด๋ฆฌ์ฆˆ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋‘ SDK๋“ค์€ ๊ฐ๊ธฐ ๋‹ค๋ฅธ ์–ธ์–ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ณ  ์žˆ์ฃ : Objetive-C, JAVA

img

์—ฌ๊ธฐ์„œ ์•ฑ์€ ์œ„์ ฏ์„ ๋งŒ๋“ค๊ณ  ์นด๋ฉ”๋ผ์™€ ๊ฐ™์€ ์„œ๋น„์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ํ”Œ๋žซํผ๊ณผ ์ง์ ‘ ๋Œ€ํ™”๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ์œ„์ ฏ๋“ค์€ ์Šคํฌ๋ฆฐ ์บ”๋ฒ„์Šค์— ๋ Œ๋”๊ฐ€ ๋˜๊ณ , ํ™”๋ฉด์—์„œ ๋ฐœ์ƒ๋œ ์ด๋ฒคํŠธ๋“ค์€ ๋‹ค์‹œ ํ•ด๋‹น ์œ„์ ฏ์œผ๋กœ ๋ณด๋‚ด์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ๊ฐ„๋‹จํ•œ ๊ตฌ์กฐ์ด์ฃ . ํ•˜์ง€๋งŒ, ๊ฐ ํ”Œ๋žซํผ๋งˆ๋‹ค ์œ„์ ฏ์€ ๋‹ค๋ฅด๊ณ  ์–ธ์–ด ๋˜ํ•œ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, ์œ„์˜ ๊ตฌ์กฐ์—์„œ๋Š” ๊ฐ ํ”Œ๋žซํผ๋งˆ๋‹ค ๋…๋ฆฝ์ ์ธ ์•ฑ์„ ๋งŒ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

# WebViews

ํ•˜๋‚˜์˜ ์ฝ”๋“œ๋กœ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ํ•˜๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ–ฅํ•œ ์ฒซ๋ฒˆ์งธ ์‹œ๋„๋Š” JavaScript์™€ WebView๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. PhoneGap, Apache Cordova, Ionic ๋“ฑ๋“ฑ์ด ์—ฌ๊ธฐ์— ์†ํ•ฉ๋‹ˆ๋‹ค. iOS SDK๋ฅผ ๋ฆด๋ฆฌ์ฆˆํ•˜๊ธฐ ์ „, ์• ํ”Œ์ด ์•„์ดํฐ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ์›น์•ฑ์„ ๋งŒ๋“ค๋ผ๊ณ  ๊ถŒ์žฅํ•œ ์‚ฌ์‹ค์„ ์ƒ๊ฐํ•ด๋ณด๋ฉด, Web ๊ธฐ์ˆ ์„ ์ด์šฉํ•œ ํฌ๋กœ์Šค ํ”Œ๋žซํผ์˜ ๋“ฑ์žฅ์€ ์–ด์ฉŒ๋ฉด ๋‹น์—ฐํ•œ ์ ˆ์ฐจ์˜€๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

img

WebView ๊ธฐ๋ฐ˜์˜ ์•ฑ์€ HTML์„ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ํ”Œ๋žซํผ ๋‚ด๋ถ€์˜ WebView๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, JavaScript์™€ ๊ฐ™์€ ์–ธ์–ด๊ฐ€ ์ง์ ‘์ ์œผ๋กœ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ(์œ„์˜ ์„œ๋น„์Šค์™€ ๊ฐ™์€)์™€ ์†Œํ†ตํ•˜๋Š”๊ฒƒ์€ ๊ทธ๋ฆฌ ์‰ฌ์šด ์ผ์ด์•„๋‹™๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด JavaScript ์˜์—ญ๊ณผ Native ์˜์—ญ ์‚ฌ์ด์—์„œ ๋ฌธ๋งฅ ์ „ํ™˜์„ ํ•ด์ฃผ๋Š” ๋ธŒ๋ฆฟ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ”Œ๋žซํผ ๋‚ด๋ถ€์˜ ์„œ๋น„์Šค๋“ค์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ž์ฃผ ๋ถˆ๋ฆฌ์ง€๋Š” ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋Ÿฐ ๋ฐฉ์‹์˜ ๊ตฌํ˜„์ด ์—„์ฒญ๋‚œ ํผํฌ๋จผ์Šค ๋ฌธ์ œ๋กœ ์ด์–ด์ง€์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

# ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ทฐ

๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจํ„ด์„ ์ด์šฉํ•œ ReactJS์™€ ๊ฐ™์€ ๋ฆฌ์•กํ‹ฐ๋ธŒ ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ด์ „๋ณด๋‹ค ์›น๋ทฐ ์ƒ์„ฑ์„ ๋งค์šฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค๋Š” ์ ์—์„œ ํฐ ์ธ๊ธฐ๋ฅผ ์–ป๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. 2015๋…„์— ๊ณต๊ฐœ๋œ React Native๋Š” ๋ฆฌ์•กํ‹ฐ๋ธŒ ์Šคํƒ€์ผ์˜ ๋ทฐ๋“ค์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์žฅ์ ๋“ค์„ ๋ชจ๋ฐ”์ผ ์•ฑ์— ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.

img

React Native๋Š” ํ˜„์žฌ ์—„์ฒญ๋‚œ ์ธ๊ธฐ๋ฅผ ๋ˆ„๋ฆฌ๊ณ  ์žˆ์ง€๋งŒ, JavaScript ์˜์—ญ์˜ ์ฝ”๋“œ๊ฐ€ ๋„ค์ดํ‹ฐ๋ธŒ ์˜์—ญ์— ์žˆ๋Š” OEM ์œ„์ ฏ์— ์ ‘์†์„ ํ•˜๊ธฐ์œ„ํ•ด์„œ ๊ฒฐ๊ตญ ๋ธŒ๋ฆฟ์ง€๋ฅผ ๊ฑฐ์น˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ทฐ์—์„œ๋Š” OEM ์œ„์ ฏ์— ๊ต‰์žฅํžˆ ์ž์ฃผ ์ ‘๊ทผํ•˜๊ฒŒ ๋˜๊ณ  (์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ์Šค์™€์ดํ”„ ํ•œ๋ฒˆ์„ ํ–ˆ์„๋•Œ ์ตœ๋Œ€ ์ดˆ๋‹น 60๋ฒˆ๊นŒ์ง€๋„ ์ ‘๊ทผ), ์ด๋Š” ๊ฒฐ๊ตญ ํผํฌ๋จผ์Šค ์ด์Šˆ๋ฅผ ์•ผ๊ธฐํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. React Native์— ๋Œ€ํ•œ ์–ด๋–ค ๊ธ€ (opens new window)์—์„œ๋Š” ์ด์— ๋Œ€ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

React Native์˜ ์„ฑ๋Šฅ์„ ์ดํ•ดํ•˜๋Š” ์ฃผ๋œ ์—ด์‡ ๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ๋‹ค. ๊ฐ ์˜์—ญ ๊ทธ ์ž์ฒด๋Š” ์—„์ฒญ๋‚˜๊ฒŒ ๋น ๋ฅด๋‹ค. ์„ฑ๋Šฅ์˜ ๋ณ‘๋ชฉ์€ ์ฃผ๋กœ ํ•˜๋‚˜์˜ ์˜์—ญ์—์„œ ๋‹ค๋ฅธ ์˜์—ญ์œผ๋กœ ๋„˜์–ด๊ฐˆ๋•Œ ๋ฐœ์ƒํ•œ๋‹ค. ๊ณ ์„ฑ๋Šฅ์˜ React Native ์•ฑ์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ์ด ๋ธŒ๋ฆฟ์ง€๋ฅผ ๊ฑด๋„ˆ๋Š” ํšŸ์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•ด์•ผํ•œ๋‹ค.

# Flutter

Flutter๋Š” React Native์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฆฌ์•กํ‹ฐ๋ธŒ ์Šคํƒ€์ผ ๋ทฐ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, Flutter๋Š” Dart (opens new window)๋ผ๋Š” ์ปดํŒŒ์ผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ์ด์šฉํ•ด ์ด ๋ธŒ๋ฆฟ์ง€๋กœ ์ธํ•ด ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Dart๋Š” Ahead of time (AOT)์— ์—ฌ๋Ÿฌ ํ”Œ๋žซํผ์— ์ƒ์‘ํ•˜๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผ ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์‹œ๋งํ•ด, Flutter๋Š” ๋ฌธ๋งฅ ๊ตํ™˜์„ ํ•˜๋Š” JavaScript ๋ธŒ๋ฆฟ์ง€๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ํ”Œ๋žซํผ๊ณผ ์ง์ ‘์ ์œผ๋กœ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผ์ด ๋˜๋ฉด ์•ฑ์˜ ์Šคํƒ€ํŠธ์—… ์‹œ๊ฐ„ ๋˜ํ•œ ๋นจ๋ผ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. Flutter๊ฐ€ JavaScript ๋ธŒ๋ฆฟ์ง€๋ฅผ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š์œผ๋ฉด์„œ, ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ทฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” ์œ ์ผํ•œ ๋ชจ๋ฐ”์ผ SDK๋ผ๋Š” ์‚ฌ์‹ค๋งŒ์œผ๋กœ๋„ Flutter๋Š” ์ด๋ฏธ ์ถฉ๋ถ„ํžˆ ํฅ๋ฏธ๋กญ๊ณ  ์‹œ๋„ํ•ด๋ณผ๋งŒํ•œ ๊ฐ€์น˜๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ์—ฌ๊ธฐ์— ๊ทธ์น˜์ง€ ์•Š๊ณ  Flutter๋Š” ํ›จ์”ฌ ๋” ํ˜์‹ ์ ์ธ ๋ถ€๋ถ„๋“ค์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

# ์œ„์ ฏ

์œ„์ ฏ์€ ์•ฑ์˜ ๋ทฐ์™€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ปจํŠธ๋กคํ•˜๋Š” ์—˜๋ฆฌ๋จผํŠธ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์ ฏ์€ ๋ชจ๋ฐ”์ผ ์•ฑ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์š”์†Œ๋ผ๊ณ  ํ•ด๋„ ๊ณผ์–ธ์ด ์•„๋‹ ๊ฒ๋‹ˆ๋‹ค. ์‚ฌ์‹ค์ƒ, ์œ„์ ฏ๋งŒ์œผ๋กœ ์•ฑ์˜ ์„ฑํŒจ๊ฐ€ ๊ฐˆ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

img

  • ์œ„์ ฏ์—์„œ ๋ฃฉ์•คํ•„์€ ๋‹ค๋ฅธ ์–ด๋– ํ•œ ๊ฒƒ๋ณด๋‹ค๋„ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์œ„์ ฏ์€ ๋‹ค์–‘ํ•œ ์Šคํฌ๋ฆฐ ์‚ฌ์ด์ฆˆ์—์„œ ๋ณด๊ธฐ ์ข‹์•„์•ผํ•˜๊ณ  ๋˜ ์ž์—ฐ์Šค๋Ÿฌ์›Œ ๋ณด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์œ„์ ฏ์€ ๋ฐ˜๋“œ์‹œ ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค: ์œ„์ ฏ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค๋•Œ, ์œ„์ ฏ๋“ค์„ ์ธํ”Œ๋ ˆ์ดํŠธํ• ๋•Œ, ํ™”๋ฉด์— ๋ฐฐ์น˜์‹œํ‚ฌ๋•Œ, ๋ Œ๋”๋งํ• ๋•Œ, (ํŠนํžˆ) ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ์ค„๋•Œ ๋“ฑ์„ ํฌํ•จํ•ด์„œ ๋ง์ด์ฃ .
  • ์š”์ฆ˜ ์•ฑ์—์„œ ์œ„์ ฏ์€ ํ™•์žฅ๊ฐ€๋Šฅํ•ด์•ผํ•˜๋ฉฐ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ๊ฐ€๋Šฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋“ค์€ ๋งˆ์Œ์— ๋“œ๋Š” ์ƒˆ๋กœ์šด ์œ„์ ฏ๋“ค์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ผ๊ณ , ์•ฑ์˜ ๋ธŒ๋žœ๋“œ์™€ ๋งค์นญ๋˜๋„๋ก ์ด๋“ค์„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Flutter๋Š” ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ์š”๊ตฌ์‚ฌํ•ญ๋“ค ์ฆ‰, ์ข‹์€ ๋ฃฉ์•คํ•„, ๋น ๋ฅธ ์†๋„, ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ, ํ™•์žฅ๊ฐ€๋Šฅ์„ฑ์„ ์ง€์›ํ•˜๋Š” ์œ„์ ฏ์„ ์ œ๊ณตํ•˜๋Š” ์ƒˆ๋กœ์šด ์•„ํ‚คํ…์ณ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๋‹ค! ๋ฐ”๋กœ Flutter๊ฐ€ OEM ์œ„์ ฏ๋“ค (๋˜๋Š” DOM ์›น๋ทฐ)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ž์ฒด์ ์ธ ์œ„์ ฏ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

img

Flutter๋Š” ์œ„์ ฏ๋“ค๊ณผ ๋ Œ๋”๋Ÿฌ๋“ค์„ ํ”Œ๋žซํผ ์˜์—ญ์—์„œ ์•ฑ์˜ ์˜์—ญ์œผ๋กœ ์˜ฎ๊ฒจ์™”์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ด์ œ ์œ„์ ฏ๋“ค์ด ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ๊ฐ€๋Šฅํ•ด์กŒ๊ณ  ํ™•์žฅ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. Flutter๊ฐ€ ํ”Œ๋žซํผ์œผ๋กœ๋ถ€ํ„ฐ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์œ„์ ฏ์„ ๋ Œ๋”ํ•  ์ˆ˜ ์žˆ๋Š” ์บ”๋ฒ„์Šค๋ฟ ์ž…๋‹ˆ๋‹ค. ์ด ์บ”๋ฒ„์Šค๋ฅผ ํ†ตํ•ด ๋””๋ฐ”์ด์Šค ์Šคํฌ๋ฆฐ์— ์œ„์ ฏ์„ ๊ทธ๋ฆฌ๊ณ , ์ด๋ฒคํŠธ๋“ค(ํ„ฐ์น˜, ํƒ€์ด๋จธ ๋“ฑ)๊ณผ ์„œ๋น„์Šค๋“ค(์œ„์น˜, ์นด๋ฉ”๋ผ ๋“ฑ)์— ์ ‘๊ทผํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Dart ํ”„๋กœ๊ทธ๋žจ (์ดˆ๋ก์ƒ‰) ์˜์—ญ๊ณผ ๋„ค์ดํ‹ฐ๋ธŒ ํ”Œ๋žซํผ ์ฝ”๋“œ (ํŒŒ๋ž€์ƒ‰) ์‚ฌ์ด์—๋Š” ์ธ์ฝ”๋”ฉ๊ณผ ๋””์ฝ”๋”ฉ์„ ๋‹ด๋‹นํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์—ฌ์ „ํžˆ ์กด์žฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, JavaScript ๋ธŒ๋ฆฟ์ง€์™€ ๋น„๊ตํ–ˆ์„๋•Œ, ๋น„๊ตํ•  ์ˆ˜ ์—†์„ ์ •๋„๋กœ ๋น ๋ฅธ ์„ฑ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์ ฏ๋“ค๊ณผ ๋ Œ๋”๋Ÿฌ๋ฅผ ์•ฑ์œผ๋กœ ์˜ฎ๊ฒจ์˜จ๊ฒƒ์€ ์•ฑ ์‚ฌ์ด์ฆˆ์—๋„ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. Flutter ์•ฑ์˜ ์ตœ์†Œ ์‚ฌ์ด์ฆˆ๋Š” ์•ฝ 6.7MB์ด๋ฉฐ, ์ด๊ฒƒ์€ ๋น„์Šทํ•œ ๊ฐœ๋ฐœ ๋„๊ตฌ๋“ค์„ ์ด์šฉํ•ด์„œ ๋งŒ๋“  ์ตœ์†Œ ํฌ๊ธฐ์˜ ์•ฑ๋“ค๊ณผ ๋น„๊ตํ–ˆ์„ ๋•Œ ๋น„์Šทํ•œ ์‚ฌ์ด์ฆˆ์ž…๋‹ˆ๋‹ค. Flutter์˜ ์žฅ์ ๋“ค์ด ๋‹ค๋ฅธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ๋น„ํ•ด ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”์ง€ ์—†๋Š”์ง€ ํŒ๋‹จํ•˜๋Š” ๊ฒƒ์€ ์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ๋ชซ์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์˜ ๋‚จ์€ ๋ถ€๋ถ„์—์„œ๋Š” Flutter๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋” ๋งŽ์€ ์žฅ์ ๋“ค์— ๋Œ€ํ•ด์„œ ๋‹ค๋ค„๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

# ๋ ˆ์ด์•„์›ƒ

Flutter์—์„œ ๊ฐ€์žฅ ํฐ ๊ฐœ์„ ์  ์ค‘ ํ•˜๋‚˜๋Š” ๋ ˆ์ด์•„์›ƒ์„ ํ•˜๋Š” ๋ฐฉ์‹์— ์žˆ์Šต๋‹ˆ๋‹ค.

๋ ˆ์ด์•„์›ƒ์ด๋ž€ ์ •ํ•ด์ง„ ๊ทœ์น™(ํ˜น์€ ์ œํ•œ๋“ค)์— ๋”ฐ๋ผ์„œ ์œ„์ ฏ์˜ ํฌ๊ธฐ์™€ ์œ„์น˜๋ฅผ ์ •ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธ

์ „ํ†ต์ ์œผ๋กœ, ๋ ˆ์ด์•„์›ƒ์€ ์–ด๋– ํ•œ ์œ„์ ฏ์—๋„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ทœ์น™๋“ค์˜ ๊ฑฐ๋Œ€ํ•œ ์ง‘ํ•ฉ์„ ์‚ฌ์šฉํ•ด์™”์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ทœ์น™๋“ค์€ ๋‹ค์–‘ํ•œ ๋ ˆ์ด์•„์›ƒ ํ•จ์ˆ˜๋“ค์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ž˜ ์•Œ๋ ค์ ธ์žˆ๋Š” CSS ๋ ˆ์ด์•„์›ƒ์„ ์˜ˆ๋กœ ๋“ค์–ด ๋ด…์‹œ๋‹ค. CSS๋Š” ์†์„ฑ๋“ค(๊ทœ์น™๋“ค)์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ด ์†์„ฑ๋“ค์€ HTML ์—˜๋ฆฌ๋จผํŠธ๋“ค (์œ„์ ฏ๋“ค)์— ์ ์šฉ์ด ๋ฉ๋‹ˆ๋‹ค (CSS3๋Š” 375๊ฐœ์˜ ์†์„ฑ์„ ์ •์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค).

CSS๋Š” ๋ฐ•์Šค ๋ชจ๋ธ, ํ”Œ๋กœํŒ… ์—˜๋ฆฌ๋จผํŠธ, ํ…Œ์ด๋ธ”, ํ…์ŠคํŠธ ์ปฌ๋Ÿผ, ํŽ˜์ด์ง€ ๋ฏธ๋””์–ด ๋“ฑ๋“ฑ์„ ํฌํ•จํ•˜๋Š” ์ˆ˜ ๋งŽ์€ ๋ ˆ์ด์•„์›ƒ ๋ชจ๋ธ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๊ฐ„์ด ์ง€๋‚˜์„œ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ๋””์ž์ด๋„ˆ๋“ค์€ ๋ ˆ์ด์•„์›ƒ์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ๋ถ€๋ถ„์„ ์ปจํŠธ๋กค ํ•˜๊ณ  ์‹ถ์–ดํ–ˆ๊ณ , ์ด ํ•„์š”์— ๋”ฐ๋ผ์„œ Flex Box์™€ Grid Layout ๋ชจ๋ธ๋“ค์„ ์ถ”๊ฐ€ํ•ด์•ผ๋งŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ „ํ†ต์ ์ธ ๋ ˆ์ด์•„์›ƒ์—์„œ ์ƒˆ๋กœ์šด ๋ชจ๋ธ๋“ค์„ ์ถ”๊ฐ€ํ• ๋•Œ, ๊ฐœ๋ฐœ์ž๋“ค์ด ์ž์ฒด์ ์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์—, Flex Box์™€ Grid Layout์€ ์šฐ๋ฆฌ๊ฐ€ ์•Œ๊ณ  ์žˆ๋“ฏ์ด CSS ํ˜•ํƒœ๋กœ ์ถ”๊ฐ€๋˜์–ด์•ผ๋งŒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €๋“ค์€ ์ด์— ๋Œ€ํ•œ ๊ตฌํ˜„์„ ๋‹ค์‹œ ํ•ด์•ผ๋งŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ „ํ†ต์ ์ธ ๋ ˆ์ด์•„์›ƒ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋กœ๋Š” ๊ทœ์น™๋“ค์ด ์„œ๋กœ ์ƒํ˜ธ์ž‘์šฉ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ (ํ˜น์€ ์†์„ฑ๋“ค๊ฐ„์˜ Conflict๊ฐ€ ๋ฐœ์ƒ), ๋ณดํ†ต ํ•˜๋‚˜์˜ ์—˜๋ฆฌ๋จผํŠธ์— ์ˆ˜์‹ญ๊ฐœ์˜ ๊ทœ์น™๋“ค์ด ํ•œ๊บผ๋ฒˆ์— ์ ์šฉ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ™˜๊ฒฝ์€ ๋ ˆ์ด์•„์›ƒ์˜ ์‹œ๊ฐ„์„ ๋Š๋ฆฌ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ ˆ์ด์•„์›ƒ ์„ฑ๋Šฅ์€ ์ผ๋ฐ˜์ ์œผ๋กœ N ์ œ๊ณฑ์˜ ๋ณต์žก๋„๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด, ์—˜๋ฆฌ๋จผํŠธ์˜ ์ˆซ์ž๊ฐ€ ์ฆ๊ฐ€ํ•จ์—๋”ฐ๋ผ, ๋ ˆ์ด์•„์›ƒ ์†๋„๋Š” ํ›จ์”ฌ ๋” ๋น ๋ฅด๊ฒŒ ๋Š๋ ค์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด, ๊ตฌ๊ธ€ ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ € ํŒ€ ๋ฉค๋ฒ„๋“ค์€ ์ƒˆ๋กœ์šด ์‹คํ—˜์„ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๋งŒ์•ฝ ๊ทธ๋“ค์ด ์ „ํ†ต์ ์ธ ๋ ˆ์ด์•„์›ƒ ๋ชจ๋ธ์„ ๋จธ๋ฆฟ์†์— ์™„์ „ํžˆ ์ง€์›Œ๋ฒ„๋ฆฐ๋‹ค๋ฉด, ํ›จ์”ฌ ๋” ๋น ๋ฅธ ๋ Œ๋”๋Ÿฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ช‡์ฃผ๊ฐ€ ์ง€๋‚˜๊ณ  ๊ทธ๋“ค์€ ๋ˆˆ์— ๋„๋ˆˆ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋“ค์ด ๋ฐœ๊ฒฌํ•œ๊ฒƒ์€:

  • ๋Œ€๋ถ€๋ถ„์˜ ๋ ˆ์ด์•„์›ƒ์€ ์ƒ๋Œ€์ ์œผ๋กœ ๊ฐ„๋‹จํ•˜๋‹ค๋Š” ์ . ์Šคํฌ๋กค ํŽ˜์ด์ง€์— ์žˆ๋Š” ํ…์ŠคํŠธ, ๋””์Šคํ”Œ๋ ˆ์ด ์‚ฌ์ด์ฆˆ์— ๋”ฐ๋ผ ์œ„์น˜์™€ ํฌ๊ธฐ๊ฐ€ ๋ณ€ํ•˜๋Š” ์ง์‚ฌ๊ฐํ˜•, ๊ทธ๋ฆฌ๊ณ  ํ…Œ์ด๋ธ”๋“ค, ํ”Œ๋กœํŒ… ์—˜๋ฆฌ๋จผํŠธ๋“ค ์ •๋„๋งŒ ํ•„์š”ํ•˜๋‹ค๋Š” ์ .
  • ๋Œ€๋ถ€๋ถ„์˜ ๋ ˆ์ด์•„์›ƒ์€ ์œ„์ ฏ์˜ ์„œ๋ธŒํŠธ๋ฆฌ์— ์†ํ•ด์žˆ์œผ๋ฉฐ, ์ด ์„œ๋ธŒํŠธ๋ฆฌ๋Š” ๋ณดํ†ต ํ•˜๋‚˜์˜ ๋ ˆ์ด์•„์›ƒ ๋ชจ๋ธ๋งŒ์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ . ๋‹ค์‹œ ๋งํ•ด, ํ•˜๋‚˜์˜ ํŠน์ • ์œ„์ ฏ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์•„์ฃผ ์ ์€ ์ˆซ์ž์˜ ๊ทœ์น™๋“ค๋งŒ์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ .

๊ทธ๋“ค์€ ๊ด€์ ์„ ์™„์ „ํžˆ ๋ฐ”๊พธ๋ฉด ๋ ˆ์ด์•„์›ƒ์„ ํ›จ์”ฌ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

  • ์–ด๋– ํ•œ ์œ„์ ฏ์—๋„ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ์—„์ฒญ๋‚˜๊ฒŒ ํฐ ๊ทœ๋ชจ์˜ ๋ ˆ์ด์•„์›ƒ ๊ทœ์น™๋“ค ๋Œ€์‹ , ๊ฐ ์œ„์ ฏ์ด ๋ณธ์ธ๋งŒ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ณ ์œ ์˜ ๊ฐ„๋‹จํ•œ ๋ ˆ์ด์•„์›ƒ ๋ชจ๋ธ์„ ๊ฐ€์ง€๋ฉด ๋œ๋‹ค.
  • ์ด์ œ ๊ฐ ์œ„์ ฏ์€ ๊ณ ๋ คํ•ด์•ผํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ ๊ทœ์น™์ด ๊ต‰์žฅํžˆ ์ž‘์•„์ง€๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ ์œ„์ ฏ์„ ์œ„ํ•œ ์ตœ์ ํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
  • ๋ชจ๋“  ๊ฒƒ๋“ค์„ ์œ„์ ฏํ™” ์‹œํ‚ค๋ฉด, ๋”์šฑ ๊ฐ„๋‹จํ•œ ๋ ˆ์ด์•„์›ƒ์„ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ Flutter๋ฅผ ์ด์šฉํ•ด ๊ฐ„๋‹จํ•œ ์œ„์ ฏ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค

new Center(
  child: new Column(
    children: [
      new Text('Hello, World!')),
      new Icon(Icons.star, color: Colors.green)
    ]
  )
)

์ด ์ฝ”๋“œ์˜ ๊ตฌ๋ฌธ์— ์ด๋ฏธ ์–ด๋–ค ๊ฒฐ๊ณผ๋ฌผ์ด ๋งŒ๋“ค์–ด์งˆ์ง€ ์ถฉ๋ถ„ํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์–ป์–ด์ง€๋Š” ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

img

์ด ์ฝ”๋“œ์—์„œ ๋ ˆ์ด์•„์›ƒ์„ ํฌํ•จํ•œ ๋ชจ๋“  ๊ฒƒ์€ ์œ„์ ฏ์ž…๋‹ˆ๋‹ค.
Center ์œ„์ ฏ์€ ์œ„์ ฏ์˜ ๋ถ€๋ชจ(์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” ์Šคํฌ๋ฆฐ)์˜ ์ค‘์•™์— ์œ„์ ฏ์˜ ์ž์‹ ์œ„์ ฏ๋“ค์„ ์œ„์น˜์‹œํ‚ต๋‹ˆ๋‹ค.
Column ์œ„์ ฏ์€ ์ด ์œ„์ ฏ์˜ ์ž์‹ ์œ„์ ฏ๋“ค์„ ์ˆ˜์ง์œผ๋กœ ๋‚˜์—ด ์‹œํ‚ต๋‹ˆ๋‹ค.
์ด Column์€ Text ์œ„์ ฏ๊ณผ Icon ์œ„์ ฏ(์ƒ‰ ์†์„ฑ์„ ๊ฐ€์ง€๋Š”)์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Flutter์—์„œ ๊ฐ€์šด๋ฐ ์ •๋ ฌ์ด๋‚˜ ํŒจ๋”ฉ ์—ญ์‹œ๋„ ์œ„์ ฏ์ž…๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ํ…Œ๋งˆ๋“ค๊นŒ์ง€๋„ ์ž์‹ ์œ„์ ฏ๋“ค์—๊ฒŒ ์ ์šฉ๋˜๋Š” ๋˜๋‹ค๋ฅธ ์œ„์ ฏ์ด๋ฉฐ, ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋„ค๋น„๊ฒŒ์ด์…˜๊นŒ์ง€๋„ ์œ„์ ฏ์ž…๋‹ˆ๋‹ค.

Flutter๋Š” Column๋ฟ ์•„๋‹ˆ๋ผ Row, Grid, List ๋“ฑ ๊ฝค๋‚˜ ๋งŽ์€ ์œ„์ ฏ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€, Flutter๋Š” Silver Layout Model์ด๋ผ๊ณ  ์นญํ•˜๋Š” ์Šคํฌ๋กค๋ง์„ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๊ณ ์œ ํ•œ ๋ ˆ์ด์•„์›ƒ ๋ชจ๋ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค๋ง์€ ๋ฐ˜๋“œ์‹œ ์ฆ‰๊ฐ์ ์ด๋ฉด์„œ๋„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋ฐ˜์‘ํ•ด์•ผ๋งŒ ์‚ฌ์šฉ์ž๋“ค์ด ๋ฌผ๋ฆฌ์ ์ธ ํ™”๋ฉด์„ ๋“œ๋ž˜๊ทธํ–ˆ์„ ๋•Œ, ์†๋์— ์ด๋ฏธ์ง€๊ฐ€ ๋ถ™์–ด์žˆ๋Š” ๋“ฏํ•œ ๋Š๋‚Œ์„ ์ค๋‹ˆ๋‹ค. Flutter์˜ ๋ ˆ์ด์•„์›ƒ์€ ๊ต‰์žฅํžˆ ๋นจ๋ผ์„œ ๋ฐ”๋กœ ์ด๊ฒƒ์„ ํ•ด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํฌ๋กค๋ง์„ ์œ„ํ•ด ๋ ˆ์ด์•„์›ƒ์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ Flutter๋Š” ์•„๋ž˜ ์ด๋ฏธ์ง€์™€ ๊ฐ™์€ ๋ฐœ์ „๋œ ํ˜•ํƒœ์˜ ์Šคํฌ๋กค๋ง์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์ด๋ฏธ์ง€๊ฐ€ GIF ์ด๋ฏธ์ง€๋ผ๋Š” ์ ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”. Flutter๋Š” ์ด๋ณด๋‹ค ๋” ๋ถ€๋“œ๋Ÿฝ์Šต๋‹ˆ๋‹ค! ์ด ๊ธ€์˜ ๋งˆ์ง€๋ง‰์— ์žˆ๋Š” ๋ฆฌ์†Œ์Šค์—์„œ ํ•ด๋‹น ์•ฑ์˜ ์ฝ”๋“œ๋ฅผ ์ฐพ์•„ ๋Œ๋ ค๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ผญ ํ•œ๋ฒˆ ๋Œ๋ ค๋ณด์„ธ์š”!

img
img
img

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ Flutter๋Š” ํ•œ๋ฒˆ์˜ ํŒจ์Šค๋กœ ๋ ˆ์ด์•„์›ƒ์„ ๊ตฌ์ถ• ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค์‹œ ๋งํ•ด, ๋ฆฌ๋‹ˆ์–ด ํƒ€์ž„์•ˆ์— ๋๋‚ผ ์ˆ˜ ์žˆ๋Š”๊ฑฐ์ฃ . ์ด ๋•Œ๋ฌธ์— Flutter๋Š” ๋งŽ์€ ์ˆ˜์˜ ์œ„์ ฏ๋“ค์„ ํ•œ๊บผ๋ฒˆ์— ๋‹ค๋ฃจ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์ถ”๊ฐ€๋กœ Flutter๋Š” ๋งค๋ฒˆ ๋ ˆ์ด์•„์›ƒ ์ž‘์—…์„ ํ•˜์ง€ ์•Š๊ธฐ์œ„ํ•ด, ์บ์‰ฌ๋ฅผ ๋น„๋กฏํ•œ ๋‹ค์–‘ํ•œ ์ž‘์—…๋“ค์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

# ์ปค์Šคํ…€ ๋””์ž์ธ

Flutter๋Š” ์œ„์ ฏ์„ ์•ฑ์˜ ์ผ๋ถ€๋กœ ์˜ฎ๊ฒจ์™”๊ธฐ ๋•Œ๋ฌธ์—, ์ƒˆ๋กœ์šด ์œ„์ ฏ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ ํ˜น์€ ๊ธฐ์กด์˜ ์œ„์ ฏ๋“ค์— ๋‹ค๋ฅธ ๋ฃฉ์•คํ•„์„ ์ฃผ๊ฑฐ๋‚˜ ํšŒ์‚ฌ ๋ธŒ๋žœ๋“œ์— ๋งž๋„๋ก ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ˜„๋Œ€์˜ ๋ชจ๋ฐ”์ผ ๋””์ž์ธ ํŠธ๋ Œ๋“œ๋Š” ํŒ์— ๋ฐ•ํžŒ ์•ฑ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์—์„œ ์™„์ „ํžˆ ๋ฉ€์–ด์ ธ ์žˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ธฐ์จ์„ ์ฃผ๋Š” ์ปค์Šคํ…€ ๋””์ž์ธ์„ ํ–ฅํ•ด ์ ์  ๋” ๋ฐœ์ „ํ•ด ๋‚˜์•„๊ฐ€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Flutter๋Š” ํ’๋ถ€ํ•˜๊ณ , ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ ๊ฐ€๋Šฅํ•œ Android, iOS ๊ทธ๋ฆฌ๊ณ  Material ๋””์ž์ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค (์‚ฌ์‹ค, Flutter๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ์ˆ˜์ค€์˜ Material ๋””์ž์ธ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ๊ฐ€ ์ข…์ข… ๋“ค๋ฆฝ๋‹ˆ๋‹ค). Flutter๋Š” ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ ๋Šฅ๋ ฅ์„ ํ™œ์šฉํ•ด์„œ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ์— ์žˆ๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ์œ„์ ฏ๋“ค์˜ ๋ฃฉ์•คํ•„๊ณผ ๋งค์นญ๋˜๋Š” ์œ„์ ฏ๋“ค์„ ์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ ๊ฐœ๋ฐœ์ž๋“ค ์—ญ์‹œ ์ด ์ปค์Šคํ„ฐ๋งˆ์ด์ฆˆ ๋Šฅ๋ ฅ์„ ์‚ฌ์šฉํ•ด์„œ ์ž์‹ ๋“ค์˜ ์š”๊ตฌ์™€ ํ•„์š”์— ๋งž๋„๋ก Flutter์—์„œ ์ œ๊ณตํ•˜๋Š” ์œ„์ ฏ์„ ๋ณ€ํ˜•์‹œํ‚ค๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

# Hot reload

Flutter์—์„œ ๊ฐ€์žฅ ์œ ๋ช…ํ•œ ํŠน์ง•์€ ๋น ๋ฅด๊ณ , statefulํ•œ Hot reload ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์•ฑ์ด ๋™์ž‘ํ•˜๊ณ  ์žˆ๋Š” ๋™์•ˆ Flutter ์•ฑ์— ๋ณ€๊ฒฝ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Flutter๋Š” ๋ณดํ†ต ์ผ์ดˆ์•ˆ์— ์ด์ „ ์ฝ”๋“œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ๊ฐœ๋ฐœ์ž๋Š” ํ•ด๋‹น ์—๋Ÿฌ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  Flutter๋Š” ๋งˆ์น˜ ์—๋Ÿฌ๊ฐ€ ์—†์—ˆ๋˜๊ฒƒ์ฒ˜๋Ÿผ ๊ทธ ์ด์ „ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ์•ฑ ์ „์ฒด๋ฅผ ๋‹ค์‹œ ๋กœ๋”ฉํ•  ๋•Œ์กฐ์ฐจ๋„ ๊ต‰์žฅํžˆ ๋น ๋ฆ…๋‹ˆ๋‹ค.

img

# ๊ทธ๋ž˜์„œ, Flutter๋Š” ๋ฌด์—‡์ด ์ƒˆ๋กญ๊ณ  ํฅ๋ฏธ๋กœ์šด๊ฐ€?

์ด์ œ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ด๋Ÿฐ ์งˆ๋ฌธ์„ ์—ฌ๋Ÿฌ๋ถ„์—๊ฒŒ ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋Œ€๋‹ตํ•ด์•ผํ•˜๋Š”์ง€ ์•„์‹ค ๊ฒ๋‹ˆ๋‹ค.

  • JavaScript ๋ธŒ๋ฆฟ์ง€ ์—†๋Š” ๋ฆฌ์•กํ‹ฐ๋ธŒ ๋ทฐ์˜ ์žฅ์ ๋“ค
  • ๋น ๋ฅด๊ณ , ๋ถ€๋“œ๋Ÿฝ๊ณ , ์˜ˆ์ธก๊ฐ€๋Šฅํ•œ AOT ์—์„œ Native ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผ๋˜๋Š” ์–ธ์–ด
  • ์œ„์ ฏ๊ณผ ๋ ˆ์ด์•„์›ƒ์— ๋ชจ๋“  ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ ์ 
  • ์•„๋ฆ„๋‹ต๊ณ  ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ๊ฐ€๋Šฅํ•œ ์œ„์ ฏ๋“ค
  • Hot reload๋ฅผ ํฌํ•จํ•œ ์ตœ๊ณ ์˜ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ
  • ์„ฑ๋Šฅ์ด ์ข‹๊ณ , ํ˜ธํ™˜์„ฑ์ด ๋›ฐ์–ด๋‚˜๋ฉฐ, ์žฌ๋ฏธ์žˆ์Œ!
  • ํ•˜๋‚˜์˜ ์ฝ”๋“œ๋กœ ๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ์—์„œ ๋™์ž‘ํ•˜๋Š” ์•ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค!

# Reference

Last Updated: 6/18/2023, 2:13:15 PM