Flutter: React Native๋กœ JSX์™€ ๊ฐ™์€ ๊ฒƒ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

์— ๋งŒ๋“  2018๋…„ 03์›” 25์ผ  ยท  203์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: flutter/flutter

UI๋ฅผ ๋นŒ๋“œํ•˜๋Š” ์ฝ”๋“œ๋Š” ์ฝ์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Dart๋Š” Java์˜ ๊ฐ„๋‹จํ•œ ๋ฒ„์ „๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ UI๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ด ์ฝ์„ ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๋กœ ๋งˆ์Œ์— ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๋Š” ๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ Flutter๋Š” React์—์„œ ์˜๊ฐ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. Flutter์— JSX๊ฐ€ ์—†๋Š”๋ฐ ์–ด๋–ป๊ฒŒ ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์ฝ์„ ์ˆ˜ ์—†๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” Flutter๊ฐ€ AnglurJs์˜ ์ดˆ์ฐฝ๊ธฐ์ฒ˜๋Ÿผ ๊ณง ์ฃฝ๊ฒŒ ๋ ๊นŒ๋ด ๋งค์šฐ ๋‘๋ ต์Šต๋‹ˆ๋‹ค.

Google์—์„œ ์ผํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ๋˜‘๋˜‘ํ•˜๋‹ค๋Š” ๊ฒƒ์€ ์ดํ•ดํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ๋˜‘๋˜‘ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ๋“ค๋„ Dart ๋Œ€์‹  React๋ฅผ ์„ ํƒํ•˜๊ณ  ์ด๊ฒƒ์ด ๊ณผ๊ฑฐ Dart๊ฐ€ ์ฃฝ์€ ์ด์œ  ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

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

์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ jsx๋ฅผ ์ข‹์•„ํ•˜๊ณ  ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. UI๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? jsx์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋งˆ์นจ๋‚ด ๊ธฐ๋ณธ ๊ตฌ๋ฌธ์„ ํ”Œ๋Ÿฌํ„ฐ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

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

์ด๊ฒƒ์€ ์˜ค๋žซ๋™์•ˆ ์š”์ฒญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
https://github.com/flutter/flutter/issues/11609
๊ฐœ๋ฐœ๋œ ๊ธฐ๋Šฅ์  ํ”„๋กœํ† ํƒ€์ž…:
https://spark-heroku-dsx.herokuapp.com/index.html
๊ทธ๊ฒƒ์€ ๋Œ€์•ˆ๊ณผ ๋ช‡ ๊ฐ€์ง€ ์ด์ ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค ...


DSX์˜ ํ˜„์žฌ ๋ฌธ์ œ๋Š” .dsx ํŒŒ์ผ์—์„œ ์ž‘์—…ํ•˜๋Š” ๋””๋ฒ„๊ฑฐ, ์ž๋™ ์™„์„ฑ ๋“ฑ์˜ ํ›Œ๋ฅญํ•œ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด Flutter ๋„๊ตฌ์™€์˜ ์ ์ ˆํ•œ ํ†ตํ•ฉ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž์—๊ฒŒ DSX๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋””๋ฒ„๊ฑฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฑฐ๋‚˜ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์€ ์ €์—๊ฒŒ๋Š” ์‹œ์ž‘ํ•˜๊ธฐ ์–ด๋ ค์šด ์ผ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ๋„์™€์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด ๋‚ด๊ฐ€ ํ•„์š”ํ•œ ๊ฒƒ์€ Dart ๋„๊ตฌ ๋ฐ VS Code Dart ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์ „์ฒด ์ „์ฒ˜๋ฆฌ ์ง€์›(์†Œ์Šค ๋งต ํฌํ•จ)์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋„๊ตฌ๊ฐ€ DSX ๋˜๋Š” ๋‹ค๋ฅธ ํŠธ๋žœ์ŠคํŒŒ์ผ๋ง ์–ธ์–ด( Dart์˜ ์ƒ์œ„ ์ง‘ํ•ฉ์ด์ง€๋งŒ ๋ชจ๋“  ๊ฒƒ์„ Dart๊นŒ์ง€ ์ปดํŒŒ์ผํ•จ)์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋‹น์‹ ์ด ๋„์šธ ์ˆ˜ ์žˆ๊ณ  ๋•๊ณ  ์‹ถ๋‹ค๋ฉด ์ €์—๊ฒŒ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

๋™์˜ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํŠนํžˆ Dart Code์™€ ๊ฐ™์€ IDE๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ๊ฐ€์ƒ ๋‹ซ๊ธฐ ํƒœ๊ทธ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. new ๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋Š” Dart2๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๋‚˜์•„์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์œ„์ ฏ ํด๋ž˜์Šค๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ๋” ์ž‘๊ฒŒ ๋ถ„ํ•ดํ•˜์ง€ ์•Š๊ณ  ๋„ˆ๋ฌด ํฐ ์œ„์ ฏ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ์ŠคํŠœ๋””์˜ค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์ƒ ๋‹ซ๋Š” ํƒœ๊ทธ์กฐ์ฐจ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ€์ƒ์˜ ๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ์žˆ์ง€๋งŒ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์‹ซ์–ดํ•˜๋Š” HTML๋ณด๋‹ค ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. Dart๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. Google์˜ ์‚ฌ๋žŒ๋“ค์€ ๋‹จ์ˆœํ™”์˜ ์ค‘์š”์„ฑ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

close

JSX์™€ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ๋„ ์›ํ•˜์ง€ ์•Š์ง€๋งŒ ์˜ˆ, IntelliJ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  UI ์ฝ”๋“œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„๊ตฌ๋กœ ๋ญ”๊ฐ€๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์œ„์ ฏ ํด๋ž˜์Šค๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ๋” ์ž‘๊ฒŒ ๋ถ„ํ•ดํ•˜์ง€ ์•Š๊ณ  ๋„ˆ๋ฌด ํฐ ์œ„์ ฏ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด JSX์™€ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅธ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค... ํŠธ๋ฆฌ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์ž‘์€ ํ•˜์œ„ ํŠธ๋ฆฌ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JSX์™€ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ๋„ ์›ํ•˜์ง€ ์•Š์ง€๋งŒ ์˜ˆ, IntelliJ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  UI ์ฝ”๋“œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„๊ตฌ๋กœ ๋ญ”๊ฐ€๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Intellij๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ์ฝ๊ธฐ ์‰ฌ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๊ฒ€ํ† ํ•  ๋•Œ Bitbucket์—์„œ ์ฝ๊ธฐ ์‰ฌ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŽธ์ง‘๊ธฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋„ ์œ ํšจํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด '์ฃผ์„ ์ฃผ์„'์œผ๋กœ 'vi'๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์ด ๊ฑฐ๊ธฐ์— ๋‹ค๋ฅธ ์ฃผ์„์„ ์ž…๋ ฅํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ ์ž ๊ธด #11609์˜ ๋ณต์ œ์ž…๋‹ˆ๋‹ค.
@sethladd ?

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. IntelliJ ๋ฐ Android Studio์—์„œ "๊ฐ€์ƒ ๋‹ซ๊ธฐ ํƒœ๊ทธ"๊ฐ€ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

cc @devoncarew ๋Š” ์–ด๋–ค ๋ฒ„์ „์ด ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์ผฐ๋Š”์ง€ ํ™•์ธํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž๊ฐ€ ์˜ตํŠธ์ธํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ?

JSX์™€ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์˜๊ฒฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์–ธ์–ด, ๋„๊ตฌ ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ „๋ฐ˜์— ๊ฑธ์ณ UI ์ฝ”๋“œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๊ฐ€ ์žˆ๋‹ค๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์†์ž„์ˆ˜ #11609๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ @devoncarew ๋˜๋Š” @mit-mit์—์„œ "๊ฐ€์ƒ ๋‹ซ๊ธฐ ํƒœ๊ทธ"๋ฅผ ์ผœ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”!

@JonathanSum , ๋‹ซ๊ธฐ ๋ ˆ์ด๋ธ”์€ ๋ถˆํ–‰ํžˆ๋„ Android Studio 3.0์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. IntelliJ 2017.3 ๋˜๋Š” Android Studio 3.1 ์ด์ƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Android Studio 3.1์€ ํ˜„์žฌ ์ถœ์‹œ ํ›„๋ณด ๋‹จ๊ณ„์— ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ์ง€์›ํ•˜๋Š” Flutter ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋‚ด์ผ ์ถœ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

JSX์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์— ๋Œ€ํ•œ ๋Œ€ํ™”์™€ ์ƒ๊ด€์—†์ด IntelliJ/Android Studio ๋ฐ VS Code ๋ชจ๋‘์—์„œ Dart์—์„œ UI ์ฝ”๋“œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋…ธ๋ ฅํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ๋‹ซ๋Š” ๋ ˆ์ด๋ธ” ์ž‘์—…์ด์ง€๋งŒ ์ตœ๊ทผ Flutter ๊ฐœ์š” ๋ณด๊ธฐ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐœ์š” ๋ณด๊ธฐ์—์„œ build() ๋ฉ”์„œ๋“œ์˜ ๊ตฌ์กฐ๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์œ„์ ฏ์„ ํƒ์ƒ‰ํ•˜๊ณ  ์ƒ์œ„/ํ•˜์œ„ ๊ด€๊ณ„๋ฅผ ๋ณด๋‹ค ์‰ฝ๊ฒŒ โ€‹โ€‹๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ IntelliJ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. VS Code์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค.

@zoechi - ์ด๊ฒƒ์€ ์†์ž„์ˆ˜์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค๋ฅธ ์‹ค์€ ๊ฐ€์—ด๋˜์–ด ์ž ๊ฒผ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ทธ๋“ค์€ ๊ทธ ๋Œ€ํ™”์— ๊ธฐ์—ฌํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ๊ธฐ๋Šฅ์„ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•ด์„œ ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ค‘๋ณต์œผ๋กœ ๋‹ซ์•„์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ JSX ์ง€์›(๋˜๋Š” ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ)์„ ์š”์ฒญํ•˜๋Š” ์ƒˆ๋กœ์šด ์‚ฌ๋žŒ๋“ค์— ๋Œ€ํ•œ ์‘๋‹ต์„ ์œ„ํ•œ ์ƒˆ ์Šค๋ ˆ๋“œ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.


@sethladd - ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ž ๊ทธ์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋Œ€์•ˆ ๋ ˆ์ด์•„์›ƒ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ฐฌ๋ฐ˜ ์–‘๋ก ์„ ํ† ๋ก ํ•˜๋Š” ๊ฒƒ์ด ์œ ์šฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ž ๊ฒจ ์žˆ์ง€ ์•Š์•˜๋‹ค๋ฉด #11609์— ์ฐธ์—ฌํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.


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

NativeScript์—๋Š” ์‹ค์ œ๋กœ ๋‹ค์Œ ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • screen.js / screen.ts (.ts๋Š” typescript๋ฅผ ์„ ํ˜ธํ•˜๋Š” ๊ฒฝ์šฐ .js๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค). ์ด๊ฒƒ์€ ํ˜„์žฌ ํ‘œ์‹œํ•˜๊ณ  ์žˆ๋Š” ํ™”๋ฉด์˜ ์ฃผ์š” ๋…ผ๋ฆฌ์ž…๋‹ˆ๋‹ค.
  • screen.css (๋˜๋Š” screen.android.css ๋ฐ/๋˜๋Š” screen.ios.css ) CSS์˜ ํ›จ์”ฌ ๋” ์ œํ•œ๋œ ๋ฒ„์ „์ด์ง€๋งŒ ๋†’์ด, ๋„ˆ๋น„, ์ƒ‰์ƒ, ๋ฐฐ๊ฒฝ ๋“ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋‹จ์ผ CSS ํŒŒ์ผ๋งŒ ํ•„์š”ํ•˜์ง€๋งŒ ๊ฐ€๋” ์ด์ƒํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ CSS๋ฅผ Android ๋ฐ iOS์šฉ์œผ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค, ์š”์†Œ ๋ฐ ID๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•˜๋ฏ€๋กœ TextArea.Login #Password ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‹ค์ œ๋กœ๋Š” ํŠน์ • ์š”์†Œ ์ฒด์ธ์œผ๋กœ๋งŒ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.
  • screen.xml (๋‹ค์‹œ ๋˜๋Š” screen.android.xml ๋ฐ/๋˜๋Š” screen.ios.xml ) - ํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ์ž…๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ JS์—์„œ ๋ ˆ์ด์•„์›ƒ์„ ์ฝ”๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๊ธฐ๋ณธ์ ์œผ๋กœ ํ”Œ๋Ÿฌํ„ฐ์™€ ์œ ์‚ฌ). ๊ทธ๋Ÿฌ๋‚˜ XML์€ ํ›จ์”ฌ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ:
<Page onLoad="loadme">
    <ActionBar title="Blah"><NavigationButton click="back" title="Back"/></ActionBar>
    <StackLayout>
      <Label text="Hi" id="Hi" style="color: red"/>
     <Label text="{{name}}" class="name"></Label>
     <Button text="Click Me" tap="clicker"/>
    </StackLayout></Page>

ํฅ๋ฏธ๋กœ์šด ์ ์€ ActionBar๊ฐ€ ํŠน์ • ํŽ˜์ด์ง€ ์ „์šฉ ๊ตฌ์„ฑ ์š”์†Œ๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(์ฆ‰, Page์—๋งŒ ํ•ด๋‹น). ๋”ฐ๋ผ์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ XML ํŒŒ์„œ See์˜ ํŽ˜์ด์ง€๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ ํŽ˜์ด์ง€ ์š”์†Œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ActionBar ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“  ๋‹ค์Œ Page ๊ตฌ์„ฑ ์š”์†Œ์—์„œ builderChild ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๊ธฐ๋ณธ builderChild๋ฅผ ์žฌ์ •์˜ํ•˜๊ณ  ์ž์‹์ด ActionBar์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด; ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‚ด๋ถ€์ ์œผ๋กœ ์ ์ ˆํ•œ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‚˜๋จธ์ง€๋Š” ์ƒ์œ„/์ƒ์œ„๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋œ ๋‹ค์Œ ์ž๋™์œผ๋กœ "์ž์‹" ๋˜๋Š” "์ž์‹" ๊ตฌ์„ฑ ์š”์†Œ์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ ์‹œ์Šคํ…œ์€ ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋ถ€๋ชจ์˜ builderchild ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ด๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ <Label>Hi</Label> ์ง€์›๊ณผ ๊ฐ™์€ ์ถ”๊ฐ€ ํ•ญ๋ชฉ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ด๋ฅผ Text ๊ฐ’์— ์ž๋™์œผ๋กœ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ๋งค์šฐ ๋‹ค์žฌ๋‹ค๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฝ”๋“œ ์—†์ด๋„ ๋ ˆ์ด์•„์›ƒ์„ ๋งค์šฐ ์‰ฝ๊ฒŒ ์‹œ์ž‘ํ•˜๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ํŽธ์ง‘๊ธฐ๋Š” ์šฐ์ˆ˜ํ•œ XML ํŽธ์ง‘ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์œผ๋กœ ์ƒ‰์ƒ์ด ์ง€์ •๋˜๊ณ  ์ ์ ˆํ•œ xsd ์ •์˜ intellij(& vscode)๊ฐ€ ์ž๋™ ๊ฒ€์‚ฌ ๋ฐ ์ œํ•œ๋œ ์ปจํ…์ŠคํŠธ ์ง€์›์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

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

์ด๊ฒƒ์— ๋Œ€ํ•œ ์ข‹์€ ์ ; ์›น ๊ฐœ๋ฐœ์ž๊ฐ€ ์žฌ๊ต์œก์„ ๊ฑฐ์˜ ๋ฐ›์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ์‹ค๋กœ; ์œ ์—ฐํ•œ ๋ Œ๋”๋Ÿฌ์™€ JS ๊ธฐ๋ฐ˜์ด๊ธฐ ๋•Œ๋ฌธ์— NativeScript๋Š” ์‹ค์ œ๋กœ Angular์™€ Vue๋ฅผ ์ง€์›ํ•˜๋ฏ€๋กœ Angular ๋˜๋Š” Vue๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์›น๊ณผ ๋ชจ๋ฐ”์ผ ์•ฑ ๊ฐ„์— ์ฝ”๋“œ ๊ธฐ๋ฐ˜์˜ ๊ฑฐ์˜ 95%๋ฅผ ์‹ค์ œ๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. react native์™€ ๊ฐ™์€ ๊ธฐ๋ณธ OS ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— (cordova์™€ ๊ฐ™์€ webview๊ฐ€ ์•„๋‹˜); ๊ทธ๊ฒƒ์€ ์ •๋ง๋กœ ๊ดœ์ฐฎ์€ ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค(์ฆ‰, React Native๋ณด๋‹ค ํ›จ์”ฌ ๋‚ซ์Šต๋‹ˆ๋‹ค). ๊ทธ๋Ÿฌ๋‚˜ Flutter๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ฐ•์ ์ด ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ชจ๋ฐ”์ผ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ์ข‹์€ ๋ณด์™„ ๋„๊ตฌ๊ฐ€ ๋˜๋Š” ์ด์œ ๋Š” ์ผ๋ถ€ ์•ฑ์ด NativeScript๊ฐ€ ๋” ๋‚˜์ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ์•ฑ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋‚ด ์‘๋‹ต์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ›จ์”ฌ ๋” ๋‚ซ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Ian์˜ ๋ฌธ์ œ; ์ด๋Ÿฌํ•œ ์˜์—ญ์—์„œ ํ›จ์”ฌ ๋” ๋‚˜์€ ๋„๊ตฌ๋กœ ๋‚จ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ž ๊ธด ์Šค๋ ˆ๋“œ๋ฅผ ์—ด๊ณ  ์ด ๋Œ“๊ธ€์„ ๋ณต์‚ฌํ•˜์—ฌ ์ „์ฒด ํ† ๋ก  ๊ธฐ๋ก์„ ํ™•๋ณดํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@JonathanSum ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๊ทธ ๊ธฐ๋Šฅ์„ ์›ํ•˜๋Š”์ง€ ์›ํ•˜์ง€ ์•Š๋Š”์ง€์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.
์—ฌ๊ธฐ๊ฐ€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์—ด๋ค ํ† ๋ก ์„ ํ•  ์žฅ์†Œ์ธ์ง€ ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค. reddit์ด๋‚˜ ๋น„์Šทํ•œ ๊ณณ์ด ๋” ๋‚˜์€ ๊ฒƒ ๊ฐ™์•„์š”.

@cbazza - ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฏธ๋ž˜์— ์‚ฌ๋žŒ๋“ค์— ๋Œ€ํ•ด ์•”์‹œํ•˜์ง€ ์•Š๋„๋ก ๋งค์šฐ ์กฐ์‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‹น์‹ ์ด ๊ทธ๋“ค์ด ์–ผ๋งˆ๋‚˜ ๋ฐ”๋ณด ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋”๋ผ๋„ ํ† ๋ก ์— ๋ถˆ์„ ๋ถ™์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

@zoechi - ์‚ฌ์‹ค ์ €๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋ชจ๋“  ๋…ผ์˜๊ฐ€ ์—ฌ๊ธฐ์— ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. John Doe๊ฐ€ ์ง€๊ธˆ์œผ๋กœ๋ถ€ํ„ฐ ํ•œ ๋‹ฌ ํ›„์— ์™€์„œ XYZ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๊ฒ€์ƒ‰ํ•  ๋•Œ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋ก์„ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. +1: ๊ธฐ์กด ๊ธฐ๋Šฅ ๋ฐ/๋˜๋Š” ์ด์— ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ ๋Œ“๊ธ€ ๋•Œ๋ฌธ์— ๊ทธ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ด๋ ‡๊ฒŒ ์˜ค๋žซ๋™์•ˆ ์ž ๊ฒจ ์žˆ์ง€๋Š” ์•Š์€ ๊ฒƒ ๊ฐ™์•„์š”. ๋‚ด๊ฐ€ ๋งํ•œ ๊ฒƒ์ด ๊ทธ๋ ‡๊ฒŒ ๋‚˜์˜๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ์˜ˆ๋ฅผ ๋“ค์–ด ์ด ์Šค๋ ˆ๋“œ์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ชจ๋“  ๊ฒƒ์— ๋Œ€ํ•ด ๋…ผํ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

Flutter ํŒ€์€ ์ด ์ž‘์—…์— ๊ด€์‹ฌ์ด ์—†๊ณ  ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์Šค๋ ˆ๋“œ๊ฐ€ ์ž ๊ฒจ ์žˆ์Šต๋‹ˆ๋‹ค.

JSX์™€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์™€ ์˜ˆ์— ์ดˆ์ ์„ ๋งž์ถ˜ ์ด๋ฒˆ ํ˜ธ์˜ ๋…ผ์˜๋ฅผ ๊ณ„์† ์ง„ํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ NativeScript๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์ข‹์€ ๊ฒฝ์šฐ Flutter NativeScript๋ฅผ ์ข‹์•„ํ•˜๊ฒŒ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๋Š” ๋Œ€์‹  Flutter๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
์ €๋Š” XML ๊ธฐ๋ฐ˜ ํ”Œ๋žซํผ(Xamarin Forms)์—์„œ ์™”์œผ๋ฉฐ ์ฒ˜์Œ์—๋Š” ์ฝ”๋“œ๋กœ ๋””์ž์ธํ•˜๋Š” ๊ฒƒ์ด ๋” ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋ฐ˜๋Œ€๋กœ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ๋ณ„๋„์˜ ํด๋ž˜์Šค๋กœ ๋””์ž์ธ์„ ๋ถ„๋ฅ˜ํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

JSX๋Š” ์ฝ”๋“œ๋กœ ๋””์ž์ธํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค!!!

@sethladd

JSX์™€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์™€ ์˜ˆ์— ์ดˆ์ ์„ ๋งž์ถ˜ ์ด๋ฒˆ ํ˜ธ์˜ ๋…ผ์˜๋ฅผ ๊ณ„์† ์ง„ํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ž, ์—ฌ๊ธฐ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋‚ด DSX ๋””์ž์ธ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
https://spark-heroku-dsx.herokuapp.com/index.html

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

๊ฒฝํ—˜์ƒ ๋Š๋‚Œํ‘œ ํ•˜๋‚˜๋กœ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐ๋˜๋ฉด ํ‚ค๋ณด๋“œ์—์„œ ํ•œ ๋ฐœ์ง ๋–จ์–ด์ ธ ํœด์‹์„ ์ทจํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” Android์™€ Java์— ๋Œ€ํ•œ ์•ฝ๊ฐ„์˜ ๊ฒฝํ—˜๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” Flutter์˜ ์ดˆ๋ณด์ž์ด๋ฉฐ ์—ฌ๊ธฐ์—์„œ ์ œ์•ˆ๋œ ๊ฒƒ๋ณด๋‹ค Flutter๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ๋‚ซ๋‹ค๊ณ  ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” XML์ด ์ถ”ํ•˜๊ณ  ๋‹ค๋ฃจ๊ธฐ ํž˜๋“ค๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค. ๋ฐ”๋‹ค์˜ ๋ฐ”๋‹ค๋ณด๋‹ค ํ•˜๋‚˜์˜ ๋‹ซ๋Š” ๋ฌธ์ž๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ์•„๋ฆ„๋‹ต์Šต๋‹ˆ๋‹ค.๊ทธ๊ฒƒ์€ ๋‚ด ์ฝ”๋“œ๋ฅผ 5๋ฐฐ ๋” ๊ธธ๊ฒŒ ๋งŒ๋“ค๊ณ , Android XML์„ ํŽธ์ง‘ํ•  ๋•Œ ์‹ซ์–ดํ•˜๋ฉฐ, ์‚ฌ๋žŒ๋“ค์ด ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋‹ค์ˆ˜์˜ IDE๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ฐ€์ƒ ๋‹ซ๊ธฐ ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋” ๊ธด ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‚ด ์ƒ๊ฐ์— ํŠนํžˆ 'child:/children:'์ด ๊ฑฐ์˜ ๊ฐ™์€ ์—ญํ• ์„ ํ•  ๋•Œ XML์ด ์ œ๊ณตํ•˜๋Š” ๊น”๋”ํ•œ ์ค‘์ฒฉ์€ ๋‚˜๋จธ์ง€ ๋‹จ์ ์„ ๋Šฅ๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Dart๋Š” ๋ฏฟ์„ ์ˆ˜ ์—†์„๋งŒํผ ๊นจ๋—ํ•˜๊ณ  ๋‚ด๊ฐ€ ๊ทธ๊ฒƒ์„ ๋งค์šฐ ์ข‹์•„ํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋งํ•œ๋‹ค๋ฉด ๋‚˜๋Š” ์—„์ฒญ๋‚˜๊ฒŒ ์‹ค๋ง ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

React๊ฐ€ ์ด๋Ÿฐ ์‹์œผ๋กœ ํ•˜๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ๋งˆ์ง€๋ง‰์œผ๋กœ ํ™•์ธํ–ˆ์„ ๋•Œ ์ด ๊ณณ์€ Flutter์ž…๋‹ˆ๋‹ค. React๊ฐ€ ์ˆ˜ํ–‰ํ•œ๋‹ค๊ณ  ํ•ด์„œ ์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‹น์‹ ๋งŒ์ด ์—ฌ๊ธฐ๋กœ ๋›ฐ์–ด๋“œ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค! @escamoteur ์˜ ๋ชจ๋“  ์š”์ ์— ๋งค์šฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. Flutter๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์‚ฌ๋žŒ๋“ค์ด ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ์–ธ์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— Dart๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์Šคํ„ฐํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ๋งŽ์€ ์ž‘์—…์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค! ์ผ๊ด€์„ฑ๊ณผ ๋‹จ์ˆœ์„ฑ์„ ํ‰๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

DSX์™€ ์ƒ์„ฑ๋œ Dart ์Šค๋‹ˆํŽซ์˜ ์ผ๋ถ€ ์„ค๋ช…:

  1. ์ฃผ๊ด€์ : ๊ฐ€๋…์„ฑ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์žฅํ™ฉํ•จ์€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค - ์กฐ๊ธˆ ๋” ๊ธธ์ง€๋Š” ์•Š๋”๋ผ๋„. Dart IDE ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์„ ์–ธ์  ๋งˆํฌ์—… ๋‹ซ๊ธฐ ํƒœ๊ทธ๋ฅผ ๋ฏธ๋Ÿฌ๋งํ•˜๋Š” ์ž๋™ ๋‹ซ๊ธฐ ํƒœ๊ทธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. JSX๊ฐ€ ์ฝ”๋“œ๋กœ ๋””์ž์ธ๋œ ๊ฒฝ์šฐ Dart์˜ ์œ„์ ฏ์ด ์–ด๋–ป๊ฒŒ ๊ทธ๋ ‡์ง€ ์•Š์€์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  2. <vars> ์˜ ์—ฌ๋Ÿฌ ์†์„ฑ

@<vars>
var textStyle = {
    "textDirection": "TextDirection.ltr",
    "textAlign": "TextAlign.center",
    "overflow": "TextOverflow.ellipsis",
    "style": "new TextStyle(fontWeight: FontWeight.bold)"
};
</vars>@

์—ฌ๋Ÿฌ ์†์„ฑ์„ ํ˜ผํ•ฉํ•˜์—ฌ ์ „์—ญ ์Šคํƒ€์ผ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ์ข‹์€ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๋‚ด ๊ฒธ์†ํ•œ ํ”Œ๋Ÿฌํ„ฐ ๊ฒฝํ—˜์„ ๋Œ์ด์ผœ ๋ณผ ๋•Œ ๋‚˜๋Š” ์ด๊ฒƒ์„ ์–ด๋””์— ์‚ฌ์šฉํ• ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

Text ์˜ ๊ฒฝ์šฐ ์žฌ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์ด ์—ฌ๋Ÿฌ ์†์„ฑ์„ ํ˜ผํ•ฉํ•˜๋Š” ๋Œ€์‹  TextStyle ์— ์ •์˜๋˜์–ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ Text ์ด์™ธ์˜ ๋‹ค๋ฅธ ์˜ˆ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

TextStyle ๋ฅผ ๋ณด๋ฉด ํ˜„์žฌ immutable + copy() ๊ฐ€ Dart์—์„œ ์žฌ์‚ฌ์šฉ ๋ฐ ์ž‘์„ฑ์— ์ ํ•ฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

class Style {
  static const TextStyle avenirNextMedium =
      const TextStyle(
         fontFamily: 'Avenir Next', 
         fontWeight: FontWeight.w500,
      );

  static TextStyle title =
      avenirNextMedium.copyWith(
        color: ColorKit.blue, 
        fontSize: 45.0,
      );
}

new Text(
  'Hello',
  style: Style.title,
),

new Text(
  'Hello2',
  style: Style.title.copyWith(
    color: ColorKit.red,
  ),
),

๋™์ผํ•œ ์Šคํƒ€์ผ์„ ๊ณต์œ ํ•˜๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ Container ์˜ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž ์ •์˜ ์ƒํƒœ ๋น„์ €์žฅ ์œ„์ ฏ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์™ธ๋ถ€ ์ •์˜ <vars> ๋ณด๋‹ค ๋” ์ž˜ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ํŒจ๋”ฉ, ์ž‰ํฌ, ์ œ์Šค์ฒ˜ ์ˆ˜์‹ ๊ธฐ ๋˜๋Š” ๊ทธ๋ฆผ์ž๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ Container ๋ฅผ ๋‹ค๋ฅธ ์œ„์ ฏ์œผ๋กœ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Material , Padding , Center ๋“ฑ ์–ด์จŒ๋“  ์‚ฌ์šฉ์ž ์ •์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ "์ปจํ…Œ์ด๋„ˆ" ์œ„์ ฏ์„ ์‚ฌ์šฉํ•˜๋”๋ผ๋„, ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์œ„์ ฏ ๊ณ„์ธต ๊ตฌ์กฐ์—์„œ ๋‹จ์ผ ์œ„์ ฏ์˜ ์†์„ฑ์„ ์ •์˜ํ•˜๋Š” ์™ธ๋ถ€ <vars> ์Šคํƒ€์ผ์„ ๊ฐ–๋Š” ๊ฒƒ์—๋Š” ๋งŽ์€ ์ด์ ์ด ์—†์Šต๋‹ˆ๋‹ค.

Flutter์˜ "๋ชจ๋“  ๊ฒƒ์ด ์œ„์ ฏ์ž…๋‹ˆ๋‹ค"๊ฐ€ "์—ฌ๋Ÿฌ ์†์„ฑ" ์Šคํƒ€์ผ๊ณผ ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ํ˜„์žฌ DSX ์˜ˆ์ œ์—์„œ ๊ฐ•์กฐ ํ‘œ์‹œ๋˜์ง€ ์•Š์Œ: ๋™์  ์œ„์ ฏ์œผ๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ฝ”๋”ฉํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์˜๋ฏธ: ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ผ๋ถ€ ์œ„์ ฏ์„ ํ‘œ์‹œํ•˜๊ฑฐ๋‚˜ ํ‘œ์‹œํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•.

Dart์—์„œ ๋””์ž์ธ์„ ํ•  ๋•Œ children ์— ํŠน์ • ์œ„์ ฏ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์‰ฝ๊ณ  ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
์œ„์ ฏ์„ ๋‹ค๋ฅธ ์œ„์ ฏ์œผ๋กœ ๋™์ ์œผ๋กœ ๋ž˜ํ•‘ํ•˜๋Š” ๊ฒƒ๋„ ๋งค์šฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. build() ํ•จ์ˆ˜๋ฅผ ์œ ์ฐฝํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

    var children = <Widget>[];
    if(a) {
      children.add(wa);
    }

    var wb = Text();
    if(b) {
      wb = Padding(child: wb);
    }

    children.add(wb);

@SirComputer1 DSX ์ œ์•ˆ์€ ์ถ”๊ฐ€ ์‚ฌํ•ญ์ด๋ฉฐ ํ˜„์žฌ ๋ฐฉ์‹์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์œผ๋ฉด ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ณ  ์ง€๊ธˆ์ฒ˜๋Ÿผ ๊ณ„์†ํ•˜์‹ญ์‹œ์˜ค.

<var> ๋Š” ์ „์ฒด Dart๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ๋ชจ์šฉ์œผ๋กœ๋งŒ ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ข… ์†”๋ฃจ์…˜์€ <var> ๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์ง€๋งŒ ๋ชจ๋“  dart ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ '@'๋Š” ๊ตฌ๋ฌธ ๋ถ„์„์„ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ๋ชจ์šฉ์œผ๋กœ๋งŒ ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ข… ์†”๋ฃจ์…˜์—๋Š” ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŒŒ์ผ์˜ ๋‹ค๋ฅธ ๋ชจ๋“  ํ•ญ๋ชฉ์€ ์ผ๋ฐ˜ Dart ์ฝ”๋“œ์ด๋ฏ€๋กœ ๋‹ค๋ฅธ ๋ชจ๋“  ํ•ญ๋ชฉ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ์žŠ์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

    var children = <Widget>[];
    if(a) {
      children.add(wa);
    }

    // You can mix and match both
    var wb = <Text/>;
    if(b) {
      wb = Padding(child: wb);
    }

    // or
    var wb = Text();
    if(b) {
      wb = <Padding> {wb} </Padding>;
    }

    children.add(wb);

    children.add(
      <Center>
          {sayHello == true ?
             <Text ['Hello, world!']/>
          :
             <Text ['Good bye']/>
          }
      </Center>
    );

DSX๋ฅผ ํ˜„์žฌ ๋ฐฉ์‹๊ณผ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋งŒํ•ฉ์‹œ๋‹ค. ํ•˜๋‚˜๋Š” ๋‹ค๋ฅธ ํ•˜๋‚˜์™€ ๊ฒฝ์Ÿํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ JSX๋ฅผ ์„ ํ˜ธํ•  ๊ฒƒ์ด๊ณ  ์ด ์Šค๋ ˆ๋“œ๋Š” ๊ทธ๋“ค์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์•Œ๊ณ  ์‹ถ์€ ๊ฒƒ์€ DSX๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก DSX๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

@escamoteur - ์ €๋Š” ๋ง์น˜๋ฅผ ๋“œ๋ผ์ด๋ฒ„๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ ์„ ํ‰๊ฐ€ํ•˜๊ณ  ์ ์ ˆํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ ์ ˆํ•œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ด์„œ ๊ฐ ํ”Œ๋žซํผ์—์„œ ๋” ๋‚˜์€ ๋ฐฉํ–ฅ์œผ๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. :์›ƒ์Œ์ด ๋„˜์น˜๋Š”:

์˜ˆ๋ฅผ ๋“ค์–ด; ํƒ€์‚ฌ ํ”Œ๋Ÿฌ๊ทธ์ธ ํ†ตํ•ฉ. NativeScript๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ํฌ๋กœ์Šค ํ”Œ๋žซํผ์˜ ์ง„์ •ํ•œ ์™•์ž…๋‹ˆ๋‹ค. ์›๊ฒฉ์œผ๋กœ NativeScript์— ๊ทผ์ ‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค. ๋ฐ ํƒ€์‚ฌ ํ†ตํ•ฉ. https://github.com/vipulasri/Timeline-View ์‚ฌ์šฉ์— ๋Œ€ํ•ด ๋ฌป๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Flutter๋Š” ์‚ฌ์‹ค์ƒ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. NativeScript๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ช‡ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜๋ฉฐ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์ด ์™„์ „ํžˆ ์ž‘๋™ํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ NS ์ปจํŠธ๋กค์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— ํ”Œ๋Ÿฌํ„ฐ๋Š” NS ํ”Œ๋ž˜๊ทธ๊ฐ€ ...

์ž‘์—…์— ์ ํ•ฉํ•œ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. :์›ƒ์Œ์ด ๋„˜์น˜๋Š”:


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

์ €๋Š” ์‹ค์ œ๋กœ XML ๊ธฐ๋ฐ˜ ๋ Œ๋”๋Ÿฌ๋ฅผ Flutter์— POC๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์œ ๊ฐ€ ์—†์—ˆ์–ด์š”. ์ €๋Š” ๋‹จ์ง€ ๋Œ€ํ™”์— ๊ธฐ์—ฌํ•˜๊ณ  ์‹ถ์—ˆ๊ณ  ์ด๋Ÿฌํ•œ ์›€์ง์ž„์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ ํ•ต์‹ฌ ํŒ€์ด ์ž‘์—…ํ•  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค . NS XML ํ˜•์‹์€ ๊ด€์‹ฌ ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค(์˜ˆ: ์•„๋งˆ ๋‚˜:์›ƒ๋Š” ์ค‘:)์ด ๊ธฐ๊บผ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€์žฅ ํฐ ๊ด€์‹ฌ์‚ฌ๋Š” @sethladd ์ž…๋‹ˆ๋‹ค. ํŒจ์น˜์— ๋งŽ์€ ์‹œ๊ฐ„์„ ํ• ์• ํ•˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ํ•ต์‹ฌ ํŒ€์˜ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ด ๋Šฅ๋ ฅ์„ ์ ˆ๋Œ€์ ์œผ๋กœ ๋ฐ˜๋Œ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์ด๊ฒƒ์— ์‹œ๊ฐ„์„ ๋ณด๋‚ด๊ธฐ ์ „์— ๋จผ์ € ์ •ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค ...

@NathanaelA ํ™˜์ƒ์ ์ธ ๊ด€์  !!!!!! ๋Š๋‚Œํ‘œ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค ;-) ๋ง ๊ทธ๋Œ€๋กœ ๋จธ๋ฆฌ์— ๋ชป์„ ๋ฐ•์•˜์Šต๋‹ˆ๋‹ค.

์˜ˆ, ์ €๋Š” DSX๋ฅผ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ˜„์žฌ Flutter ๋นŒ๋“œ ์‹œ์Šคํ…œ์— ํ†ตํ•ฉํ•  ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ๊ณ„์† ์ง„ํ–‰ํ•˜๊ธฐ ์ „์— ํ˜„์žฌ Flutter ํŒ€์˜ ์•ฝ์†์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. IDE ํ†ตํ•ฉ์€ VS Code์—์„œ ์‚ฌ์‹ค์ƒ ์‚ฌ์†Œํ•˜์ง€๋งŒ Intellij์—์„œ๋Š” ๊ทธ๋‹ค์ง€ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(Google์ด Intellij JSX ์ง€์›์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ).

@zoech , ์•„๋‹ˆ์š”! ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ์ž๋ฐ”์™€ XML๋กœ ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์„ ๊ฐœ๋ฐœํ–ˆ๋˜ ๊ธฐ์–ต์ด ๋‚œ๋‹ค. ์šฐ๋ฆฌ๋Š” ์—ฌ์ „ํžˆ UI ์–ธ์–ด ๋ถ€๋ถ„์— XML์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋…ผ๋ฆฌ์™€ UI์— Dart๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ด์ƒํ•˜๊ณ  ์ด ๋ฌธ์ œ๋Š” ๋ถ„๋ช…ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ Google์ด Flutter์— React์˜ UI ์•„์ด๋””์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. React์˜ UI ๋ถ€๋ถ„์€ ๋งค์šฐ ๊ฐ•๋ ฅํ•˜๊ณ  ๊ฐ„๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

@JonathanSum ์ด์— ๋Œ€ํ•œ ๋งŽ์€ ์˜๊ฒฌ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
๋‚˜์—๊ฒŒ๋Š” ์—ฌ์ „ํžˆ ์‚ฌ๋žŒ๋“ค์ด ์Šต๊ด€์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์„ ๊บผ๋ คํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ํ”Œ๋žซํผ์— ๋„์›€์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด ์•„๋‹™๋‹ˆ๋‹ค.

์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ jsx๋ฅผ ์ข‹์•„ํ•˜๊ณ  ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. UI๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? jsx์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋งˆ์นจ๋‚ด ๊ธฐ๋ณธ ๊ตฌ๋ฌธ์„ ํ”Œ๋Ÿฌํ„ฐ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@zoechi

์‚ฌ๋žŒ๋“ค์ด ์Šต๊ด€์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ์„ ๊บผ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ ์‚ฌ๋žŒ๋“ค์ด ์›ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๊ณต์ •ํ•œ ๊ด€์ฐฐ์ด์ง€๋งŒ Flutter๊ฐ€ ์กฐ๋ ฅ์ž๊ฐ€ ๋˜์–ด (Google ์™ธ๋ถ€) ์‚ฌ๋žŒ๋“ค์ด Flutter๋ฅผ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ€๋Šฅํ•œ ํ•œ ๋งŽ์€ ๋งˆ์ฐฐ์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์ง€ ์•Š์„๊นŒ์š”? ์ด ๊ฒŒ์ดํŠธ ํ‚คํ•‘ ๋™์ž‘์€ ๊ฐœ๋ฐœ์ž์˜ ๋งˆ์Œ์„ ์‚ฌ๋กœ์žก๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

@yuu2lee4

์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ jsx๋ฅผ ์ข‹์•„ํ•˜๊ณ  ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. UI๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? jsx์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋งˆ์นจ๋‚ด ๊ธฐ๋ณธ ๊ตฌ๋ฌธ์„ ํ”Œ๋Ÿฌํ„ฐ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

ํ›Œ๋ฅญํ•œ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. JSX์™€ ๊ฐ™์€ DSX์—์„œ ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๊ณ  @Hixie ๊ฐ€ ๊ฐœ์ธ์ ์œผ๋กœ ์ง„ํ–‰ ์ƒํ™ฉ์— ๋Œ€ํ•ด ํฅ๋ถ„๋œ ์ด๋ฉ”์ผ์„ ๋ณด๋ƒˆ์Œ์„ ๊ฐ์•ˆํ•  ๋•Œ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. '๋ฌด์—‡์„ ๋„์™€๋“œ๋ฆด๊นŒ์š”? ๋‹น์‹ ์ด ์ด๊ฒƒ์„ ํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ๊ฒƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?'

์†”์งํžˆ, ์ด ์ œ๋ชฉ์„ ์ด์ „ ์ œ๋ชฉ๊ณผ ๋น„์Šทํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ์ƒ๊ฐํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„์›€์ด ๋˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค...

@cbazza

@Hixie๊ฐ€ ๊ฐœ์ธ์ ์œผ๋กœ ์ง„ํ–‰ ์ƒํ™ฉ์— ๋Œ€ํ•ด ํฅ๋ถ„ํ•œ ์ด๋ฉ”์ผ์„ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค..

๊ณ„์†ํ•ด์„œ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ์ฐธ์—ฌํ•˜๊ณ  ๋„์™€์•ผ ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๊นŒ? ์šฐ๋ฆฌ๊ฐ€ ์ด๊ฒƒ์ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์ฒ˜๋Ÿผ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋„๋ก ํ•˜๋ ค๋ฉด... ๋ธ”๋ก์ด ๋ฌด์—‡์ธ์ง€, ๋ธ”๋ก์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋Š”์ง€, ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๊ณ  ๊ฑฐ๊ธฐ์— ๋ฐฐ์น˜ํ•˜๋Š”์ง€ ๋…ผ์˜ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค... ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ๋˜ํ•œ flutter์™€ dart ํŒ€์ด UI ์ž‘์„ฑ์˜ ์žฅํ™ฉํ•œ ํŠน์„ฑ์„ ์ค„์ด๋Š” ์ž‘์—…์„ ์–ด๋–ค ์‹์œผ๋กœ๋“  ์‹œ์ž‘ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค...
์ง€๊ธˆ์€ ํŒ€์ด ํ•ฉ๋ฅ˜ํ•  ์ˆ˜ ์—†์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ํ•ฉ๋‹นํ•œ ์ด์œ ๋ผ๋ฉด ์–ด๋–ค ์ ‘๊ทผ ๋ฐฉ์‹์ด๋“  ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค...๊ทธ๋“ค์€ ์–ด๋Š ์‹œ์ ์—์„œ ๋”ฐ๋ผ์žก์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค...๊ทธ๋ž˜์„œ @cbazza ๋Š” ๊ณ„์†ํ•ด์„œ ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋‹น์‹ ์€ ํ•˜๊ณ  ์žˆ๊ณ  ๊ทธ๊ฒƒ์„ ๊บผ๋‚ด์‹ญ์‹œ์˜ค ...์ด ์‚ฌ๋žŒ์ด ์ดˆ๊ธฐ์— http://mutisya.com/ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ƒํƒœ๋ฅผ ์•Œ์ง€ ๋ชปํ•˜์ง€๋งŒ ... ๋˜ํ•œ @NathanaelA ๊ฐ€ ๊ธฐ์—ฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์••๋‹ˆ๋‹ค. Nativescript๋ฅผ ์œ„ํ•œ ์ •๋ง ๋†€๋ผ์šด ๋ฌผ๊ฑด๊ณผ ๋„๊ตฌ...๋” ๋งŽ์€ ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋” ๋งŽ์€ ์˜ต์…˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ...

@MichaelSowah
์ด๊ฒƒ์— ๋” ๋งŽ์€ ์‹œ๊ฐ„์„ ํˆฌ์žํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” @NathanaelA ๊ฐ€ ๋งํ•œ ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€์žฅ ํฐ ๊ด€์‹ฌ์‚ฌ๋Š” @sethladd ์ž…๋‹ˆ๋‹ค. ํŒจ์น˜์— ๋งŽ์€ ์‹œ๊ฐ„์„ ํ• ์• ํ•˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ํ•ต์‹ฌ ํŒ€์˜ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ด ๋Šฅ๋ ฅ์„ ์ ˆ๋Œ€์ ์œผ๋กœ ๋ฐ˜๋Œ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์ด๊ฒƒ์— ์‹œ๊ฐ„์„ ๋ณด๋‚ด๊ธฐ ์ „์— ๋จผ์ € ์ •ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค ...

์ข‹์•„, ์—ฌ๊ธฐ ๋‚ด๊ฐ€ ๊ฐ€์ง„ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
(a) *.dsx ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๊ณ  *.dart ํŒŒ์ผ์„ ์ถœ๋ ฅํ•˜๋Š” ์ „์ฒ˜๋ฆฌ๊ธฐ.

ํ•„์š”ํ•œ ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
(1) 'VS์ฝ”๋“œ' ํ†ตํ•ฉ์„ ๋‹ด๋‹นํ•  ์‚ฌ๋žŒ. ๋‚ด ์กฐ์‚ฌ์— ๋”ฐ๋ฅด๋ฉด ๊ฐ„๋‹จํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.
(2) ๋””๋ฒ„๊น…์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋„๋ก ์ „์ฒ˜๋ฆฌ๊ธฐ ๊ธฐ๋Šฅ์„ Flutter ๋นŒ๋“œ ์‹œ์Šคํ…œ์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋‚ผ ์‚ฌ๋žŒ. ๋‚ด ๋ง์€ ์ฝ”๋“œ ์Šคํ…Œํ•‘์ด ์†Œ์Šค๋งต ๋“ฑ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ํ†ตํ•ด *.dsx ํŒŒ์ผ์— ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

์œ„์˜ 2๊ฐ€์ง€ ํ•ญ๋ชฉ์ด ์™„๋ฃŒ๋˜๋ฉด ๋ณผ์„ ๊ตด๋ฆฌ๊ธฐ ์œ„ํ•œ ์ดˆ๊ธฐ ์—”๋“œ ํˆฌ ์—”๋“œ ์‹œ์Šคํ…œ์„ ๊ฐ–๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ…Œ์ด์ปค?

๋”ฐ๋ผ์„œ ์œ„์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด (1) ๋ฐ (2)๋Š” Flutter ํŒ€์ด ๊ฑฐ๋ถ€ํ•  ์ˆ˜ ์žˆ๋Š” Flutter ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ์ง€์›/์•ฝ์† ์—†์ด ์ด ๊ธฐ๋Šฅ์ด ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค.

@cbazza ํ›Œ๋ฅญํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ํ”Œ๋Ÿฌํ„ฐ ํŒ€ ๊ตฌ์„ฑ์› ์ค‘ ํ•œ ๋ช…์„ ๋ถˆ๋Ÿฌ์„œ 1๊ณผ 2๋ฅผ ๋ฐ›์•„๋“ค์ผ ์˜ํ–ฅ์ด ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๋„๋ก ํ•ฉ์‹œ๋‹ค...๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๊ฐ€ ์ง„ํ–‰ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์€ ๋ˆ„๊ตฌ์ธ๊ฐ€์š”...?

(2) ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์•„๋งˆ๋„ [email protected] ๋˜๋Š” ๋ฌธ์ œ ์ถ”์ ๊ธฐ๋ฅผ ํ†ตํ•ด Dart ํŒ€์— ์—ฐ๋ฝํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Dart 2์˜ ๋ชฉํ‘œ ์ค‘ ํ•˜๋‚˜๋Š” ์–ธ์–ด์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์‹คํ—˜์„ ์œ„ํ•œ ์ธํ”„๋ผ๋ฅผ ๋งŒ๋“ค๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ DSX์™€ ๊ฐ™์€ ์‹คํ—˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. @anders-sandholm @mit-mit ๋˜๋Š” @mraleph ๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉํ–ฅ์„ ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@sethladd ๋น ๋ฅธ ์‘๋‹ต์— ๊ฐ์‚ฌ๋“œ๋ฆฌ๋ฉฐ ๋ฆฌ์†Œ์Šค ๋‹ด๋‹น์ž ๋ฐ ๊ฐ€๋Šฅํ•˜๋ฉด ๋ณต์‚ฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹คํŠธ ํŒ€๋„ ์ด ์Šค๋ ˆ๋“œ์—
@cbazza ๋‚˜์—ด๋œ ๋ฆฌ์†Œ์Šค ๋‹ด๋‹น์ž์™€ ํ•จ๊ป˜ ์ด ๋‹ด๋ก ์„ ์ง„ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋›ฐ์–ด๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
'VS Code' ํ†ตํ•ฉ๊ณผ ๊ด€๋ จํ•˜์—ฌ 2๊ฐœ๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด @DanTup ์ด ๋„์›€์„ ์ฃผ๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ƒฅ ๋ช‡ ๊ฐ€์ง€ ์ƒ๊ฐ

์ข‹์•„, ์—ฌ๊ธฐ ๋‚ด๊ฐ€ ๊ฐ€์ง„ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
(a) *.dsx ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๊ณ  *.dart ํŒŒ์ผ์„ ์ถœ๋ ฅํ•˜๋Š” ์ „์ฒ˜๋ฆฌ๊ธฐ.

์ด๊ฒƒ์€ ์•„๋งˆ๋„ ์‹œ์ž‘ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ „๋ถ€์ด๋ฉฐ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ๋‹ค์‹œ ๋นŒ๋“œํ•˜๊ธฐ ์œ„ํ•œ ํŒŒ์ผ ๊ฐ์‹œ์ž์ž…๋‹ˆ๋‹ค. FileSystemEntity ์ฐธ์กฐ. ๋ฌธ์ œ๋Š” ์ด .dx ๋ฌธ๋ฒ•์ด dartlang์˜ ์ƒ์œ„ ์ง‘ํ•ฉ์ด๋ฏ€๋กœ Dart๋„ ๋ชจ๋‘ ๊ตฌ๋ฌธ ๋ถ„์„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. JavaScript์™€ ๋‹ฌ๋ฆฌ < ๋ฐ > ๊ฐ€ ๋” ๋งŽ์€ ๊ณณ์—์„œ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ๊นŒ๋‹ค๋กœ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Dart ํŒŒ์„œ๋Š” ์ด๋ฏธ Dart์™€ sdk repo ๋‚ด๋ถ€ ์–ด๋”˜๊ฐ€์— ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์–ด๋””์— ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. vscode ๋ฐ Intellij ํ†ตํ•ฉ์˜ ๊ฒฝ์šฐ ํ”Œ๋Ÿฌํ„ฐ ๋นŒ๋“œ ์‹œ์Šคํ…œ์ด ์•„๋‹ˆ๋ผ ์›ํ•˜๋Š” ๋‹คํŠธ ๋ถ„์„๊ธฐ ์ž…๋‹ˆ๋‹ค. dx๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  dart๋กœ ๋ณ€ํ™˜ํ•œ ๋‹ค์Œ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์›๋ณธ ํŒŒ์ผ์— ๋งคํ•‘ํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ฐ๋„ ๋ถ„์„๊ธฐ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ด html ํŒŒ์ผ์— ์ž๋™ ์™„์„ฑ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

  2. ๋นŒ๋“œ ๋Ÿฌ๋„ˆ ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ a ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ›จ์”ฌ ๋” ์ •๊ตํ•œ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค.

@MichaelSowah
ํ›Œ๋ฅญํ•ฉ๋‹ˆ๋‹ค. (1)๊ณผ (2)๋ฅผ ๋งก์•„์„œ ์ œ๊ฐ€ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

@jonahwilliams
๋‚˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋ฆด๋ฆฌ์Šค(https://spark-heroku-dsx.herokuapp.com/index.html)์— ๋‚ด ๋งˆ์ปค๋ฅผ ํ•ญ์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ „์ฒด ๋‹คํŠธ ๊ตฌ๋ฌธ ๋ถ„์„์ด ๋ณต์žกํ•˜๊ณ  ์ง€๊ธˆ ๋‹น์žฅ์€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์••๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ํ•œ ๊ฐ€์ง€ ํ™•์‹คํ•œ ๊ฒƒ์€ IDE์™€ ๋””๋ฒ„๊ฑฐ๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์‚ฌ๋žŒ๋“ค์€ ์ ˆ์ถฉ์•ˆ์ด ๋„ˆ๋ฌด ์ปค์„œ DSX๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด ๋ง์€ 'DSX๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ฌ๋ณผ๋ฆญ ๋””๋ฒ„๊น…์€ ์žŠ์–ด๋ผ'๋Š” ๊ฒƒ์ด์ง€ ๊ทธ๋‹ค์ง€ ๋งค๋ ฅ์ ์ธ ์ œ์•ˆ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์ตœ์†Œํ•œ ํ•˜๋‚˜์˜ IDE๋ฅผ ์ง€์›ํ•˜๊ณ  VS Code๊ฐ€ ํŒŒ์ด๋งŒํผ ๊ฐ„๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค(์ด๋ฏธ Typescript ๋ฐ Javascript ๊ตฌ๋ฌธ ์ •์˜ json ํŒŒ์ผ์—์„œ JSX๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์—)

re: IDE ๋ฐ ๋””๋ฒ„๊ฑฐ, ์•„๋งˆ๋„ Dart 2 ์ธํ”„๋ผ ๋ฐ "๊ณตํ†ต ํ”„๋ก ํŠธ ์—”๋“œ" ๋‚ด๋ถ€์—์„œ ์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•จ์œผ๋กœ์จ ๋” ๋†’์€ ์ˆ˜์ค€์˜ ์Šคํƒ์ด DSX๋ฅผ ์ธ์‹ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Dart ํŒ€๊ณผ ํ˜‘๋ ฅํ•˜์—ฌ Common Front End ๋ฐ ํ•ด๋‹น API์˜ ๋‹ค์–‘ํ•œ ๋ถ€๋ถ„์„ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@MichaelSowah https://github.com/flutter/flutter/issues/15922#issuecomment -376960770์—์„œ Dart์˜ ์‚ฌ๋žŒ๋“ค์„ ์ฐธ์กฐํ–ˆ์Šต๋‹ˆ๋‹ค.

@NathanaelA ํŒ€์˜ ์ง€์›์ด ๋ถ„๋ช…ํžˆ ์žˆ์œผ๋ฏ€๋กœ (1) & (2)์— ์ฐธ์—ฌํ•˜๋Š” ๋ฐ ๊ด€์‹ฌ์ด ์žˆ์œผ์‹ญ๋‹ˆ๊นŒ?

ํ™•์‹คํ•˜์ง€ ์•Š๋‹ค; ์ด ์ˆœ๊ฐ„ -- ์ €๋Š” ์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ ํ”„๋กœ์ ํŠธ์— ํœฉ์‹ธ์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปดํŒŒ์ผ ํŒŒ์ดํ”„๋ผ์ธ์— ์—ฐ๊ฒฐํ•˜๊ณ  ์ž ์žฌ์ ์œผ๋กœ ์†Œ์Šค ๋งต์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ธฐ๊บผ์ด ์กฐ์‚ฌํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. (ie 2) ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ธฐ๊นŒ์ง€ ๋ช‡ ์ฃผ๊ฐ€ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@NathanaelA ์„œ๋‘๋ฅด๊ฑฐ๋‚˜ ํ•˜์ง€ ์•Š์œผ๋‹ˆ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค :-)

DSX ๊ฐ€ ๋‹จ์ˆœํžˆ Dart + Virtual closing tag ์ด๋ฉด ์‹ค์งˆ์ ์ธ ์ด์ ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‹คํŠธ์˜ ํ•œ ๊ฐ€์ง€ ์ด์ ์€ ํ•จ์ˆ˜์™€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ„์ ฏ์˜ ์ผ๋ถ€๋ฅผ ๋งŒ๋“ค๊ณ  ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ DSX์™€ ์ „์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด 1์ดˆ ๋ฏธ๋งŒ์˜ ํ•ซ ๋ฆฌ๋กœ๋“œ ๊ธฐ๋Šฅ์„ ์žƒ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. @cbazza ?

์•„๋‹ˆ์š”, DSX๋Š” JSX์™€ ๊ฐ™์œผ๋ฉฐ ํ˜„์žฌ Dart ์ „์šฉ ์œ„์ ฏ ํŠธ๋ฆฌ์™€ IDE๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” 'Dart + ๊ฐ€์ƒ ๋‹ซ๊ธฐ ํƒœ๊ทธ'์™€๋Š” ์™„์ „ํžˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

DSX๋Š” ์—ฌ๊ธฐ์— ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
https://spark-heroku-dsx.herokuapp.com/index.html

DSX๋Š” Dart์ด๋ฏ€๋กœ ์„ค๋ช…ํ•˜๋Š” Dart์˜ ๋ชจ๋“  ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. JSX์— ์ต์ˆ™ํ•œ ์‚ฌ๋žŒ๋“ค์€ ์ฆ‰์‹œ ๊ทธ๊ฒƒ์„ ์–ป๊ณ  ๊ทธ๊ฒƒ์„ ์ข‹์•„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„๋‹ˆ์š”, ๋‹น์‹ ์€ ์•„๋ฌด๊ฒƒ๋„ ์žƒ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค, ๋‹น์‹ ์ด ๋งŒ๋“œ๋Š” ์ผ๋ฐ˜ *.dart ํŒŒ์ผ์— ๋Œ€ํ•ด ์•„๋ฌด ๊ฒƒ๋„ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹1์ดˆ ๋ฏธ๋งŒ์˜ ํ•ซ ๋ฆฌ๋กœ๋”ฉ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ *.dsx ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด ๋จผ์ € *.dart๋กœ ๋ณ€ํ™˜๋˜๋ฉฐ ๊ทธ ํ”„๋กœ์„ธ์Šค๋Š” ๋‚ด๊ฐ€ ๊นœ๋ฐ•ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋ณด๋‹ค ๋น ๋ฆ…๋‹ˆ๋‹ค!!! ๋”ฐ๋ผ์„œ DSX ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ๋ˆˆ์— ๋„์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

@JonathanSum ๋‹ซ๋Š” ๋ ˆ์ด๋ธ”์ด ์žˆ๋Š” Android Studio(3.1)์˜ ๋งˆ์ง€๋ง‰ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ?

@14n ๋„ค, ๊ฐ€์ƒ์˜ ๋‹ซ๋Š” ํƒœ๊ทธ์™€ ๋Œ“๊ธ€์ด ๋ณด์ž…๋‹ˆ๋‹ค.

ํฐ XML๊ณผ ๊ฐ™์€ ์œ„์ ฏ ํŠธ๋ฆฌ๋Š” Dart, JSON, YAML ๋˜๋Š” JSX์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ํฐ ๊ฒƒ๋งŒํผ ์ฝ๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. JSX ์ž์ฒด๊ฐ€ ๊ฐ€๋…์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๊ตฌ๋ฌธ์œผ๋กœ ์ •์ƒ์ ์ธ ํฌ๊ธฐ์˜ ์œ„์ ฏ ํŠธ๋ฆฌ๋ฅผ ์ฝ๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. Plus Flutter๋Š” ๊ตฌ์„ฑ์„ ์ด‰์ง„ํ•˜๋ฏ€๋กœ ํŠน์ • ์œ„์ ฏ์ด ๋„ˆ๋ฌด ์ปค์ง€๋ฉด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ ์œ„์ ฏ์œผ๋กœ ๋ถ„ํ• ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

์ œ์•ˆ๋œ DSX ํ˜•์‹์— ๋Œ€ํ•œ ์ฃผ๊ด€์ ์ธ ์˜๊ฒฌ:

  1. ์‹œ๊ฐ์ ์œผ๋กœ ์‹ค์งˆ์ ์ธ ์ด์ ์ด ์—†๊ณ  ๋‹ค์‹œ - ํฐ XML ํŠธ๋ฆฌ๋ฅผ ์ฝ๋Š” ๊ฒƒ์€ ๊ณ ํ†ต์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํด๋ฆฐ ์ฝ”๋“œ ๊ด€ํ–‰์„ ์žฅ๋ คํ•˜๋ฉด ์‹ค์ œ๋กœ ๊ฐ€๋…์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Ÿฌํ•œ ๊ด€ํ–‰์€ (๊ฑฐ์˜) ๋ชจ๋“  ๊ตฌ๋ฌธ์— ์ ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ๋‹ค๋ฅธ DSL/๊ตฌ๋ฌธ์„ ๋ฐฐ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ ˆ์ด์•„์›ƒ, ์Šคํƒ€์ผ, ์• ๋‹ˆ๋ฉ”์ด์…˜, ๋…ผ๋ฆฌ ๋“ฑ ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ํ•˜๋‚˜์˜ ๊ตฌ๋ฌธ(Dart)๋งŒ ์•Œ๋ฉด ๋œ๋‹ค๋Š” ๊ฒƒ์ด ์ •๋ง ์ •๋ง ์ •๋ง ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค. html/js/jsx/ts/coffee/css/sass/scss๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น์— ๋ฐœ์ƒํ•œ ๊ฒƒ๊ณผ ๋น„๊ตํ•˜์—ฌ ์‹ ๊ทœ ์‚ฌ์šฉ์ž์™€ ์ˆ™๋ จ๋œ ๊ฐœ๋ฐœ์ž ๋ชจ๋‘์—๊ฒŒ ํ›จ์”ฌ ๋” ์นœ์ˆ™ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ์ €๋Š” ์ด๊ฒƒ์ด ๋‹ค๋ฅธ ํ”Œ๋žซํผ์— ๋น„ํ•ด Flutter์˜ ์ฃผ์š” ์ด์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, UI๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ๋•Œ Dart๊ฐ€ ๋” ๋งŽ์€ ํ‘œํ˜„๋ ฅ์„ ๋ฐœํœ˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด DSL ๋Œ€์‹  ๊ธฐ์กด Dart ๊ตฌ๋ฌธ์— ๋Œ€ํ•œ ํ™•์žฅ ๊ธฐ๋Šฅ์„ ๋” ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

Flutter๋ฅผ "๋œจ๊ฑฐ์šด ์ƒˆ ๊ฒƒ"์ฒ˜๋Ÿผ ๋งŒ๋“ค๋ ค๋Š” ์‹œ๋„๋ฅผ ์ค‘๋‹จํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๊ฒƒ์€ ๊ทธ ์ž์ฒด๋กœ ๋œจ๊ฑฐ์šด ์ƒˆ๋กœ์šด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํŒจ๋Ÿฌ๋‹ค์ž„์„ ํƒ๊ตฌํ•˜๊ฒŒ ํ•˜์‹ญ์‹œ์˜ค.

@naiveaiguy ๋”์šด ๊ฒƒ ๊ฐ™์•„์š”. ๋งค์šฐ ์ƒ์‚ฐ์ ์ด๋ฉฐ ๋ธŒ๋ผ์šฐ์ € ๋ฐ ์„œ๋ฒ„ ์•ฑ๊ณผ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ํ•œ ์—ฌ๋ฆ„ ๋™์•ˆ ๊ณผ๋Œ€ ๊ด‘๊ณ ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‚ด ์ผ์„ ์™„์ˆ˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌด์–ธ๊ฐ€๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ Flutter์™€ Dart๊ฐ€ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

์ด ๊ฑฐ์šธ์— ๋Œ€ํ•œ ๋‚ด ์ƒ๊ฐ์€ @pulyaevskiy๊ฐ€ https://github.com/flutter/flutter/issues/15922#issuecomment -377666972 ์—์„œ ๋งํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฝ์„ ์ˆ˜ ์—†๋Š” ๋ชจ๋“  ์˜ˆ์ œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ์กด ์ฝ”๋“œ์—์„œ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ Dart์— ์ถ”๊ฐ€๋กœ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์†Œํ•œ ๋ณ€๊ฒฝ(new/const๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌ)์ด ๋” ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. . ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ตฌ๋ฌธ๊ณผ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ๋„๊ตฌ ์ฝ”๋“œ ์„ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์™„์ „ํžˆ ๋‹ค๋ฅธ ํŒŒ์ผ ์„ธํŠธ๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์ƒ๋Œ€์ ์œผ๋กœ ์ ์€ ์ด๋“(FWIW, ์ €๋Š” JSX ์—†๋Š” React๋„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค)์— ๋Œ€ํ•œ ๋†’์€ ๋น„์šฉ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์ œ์•ˆ๋œ dsx๊ฐ€ ์ผ๋ฐ˜ Dart ์ฝ”๋“œ๋„ ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์— ์™„์ „ํžˆ ์ ์šฉ ๊ฐ€๋Šฅํ•œ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ƒˆ๋กœ์šด ๊ตฌ๋ฌธ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๋Š” ๊ฒƒ์„ ๋“ค์„ ๋•Œ๋งˆ๋‹ค Gilad A DOMain of Shadows ์˜ ์ด ํ›Œ๋ฅญํ•œ ๊ฒŒ์‹œ๋ฌผ์ด ์ƒ๊ฐ๋‚ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒƒ๋“ค์€ ์‚ฌ๋žŒ๋“ค์ด ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ•ญ์ƒ ๋” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ์‹ค์‹œ๊ฐ„ ์˜ค๋ฅ˜, ์ฝ”๋“œ ์™„์„ฑ, ๋ฆฌํŒฉํ„ฐ๋ง, ํˆดํŒ ๋“ฑ์„ ๊ธฐ๋Œ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ํŠธ๋žœ์ŠคํŒŒ์ผํ•˜๋Š” ๊ฒƒ๋งŒํผ ๊ฐ„๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํฐ ์ž‘์—…์ž…๋‹ˆ๋‹ค.

์ž‘๋™ํ•˜๋Š” ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๋ณด๋‹ค ์ฝ๊ธฐ ์–ด๋ ค์šด ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜๋Š” ์ผ๋ถ€ ์ฝ”๋“œ, ์ด ์ œ์•ˆ๋œ ๊ตฌ๋ฌธ์—์„œ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€, ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ๋Œ€๊ด„ํ˜ธ๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š๊ณ  ๊ธฐ์กด Dart ๊ตฌ๋ฌธ. ์˜ˆ๋ฅผ ๋“ค์–ด React์—์„œ ๋‚ด๊ฐ€ ์ข‹์•„ํ•˜๋Š” ๊ฒƒ์€ ์ž์‹์ด ๋งˆ์ง€๋ง‰ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ varargs๋กœ ์ „๋‹ฌ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. child ๋ฐ children ๊ฐ€ Flutter์— ๋งŽ์€ ๋…ธ์ด์ฆˆ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. . ์„œ์‹์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์œ„์ ฏ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๊ฐ•์กฐ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•œ ํ† ๋ก ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Extract Widget ๋ฆฌํŒฉํ„ฐ๋ง์ด ๋Œ€๊ทœ๋ชจ ๋นŒ๋“œ ๋ฉ”์„œ๋“œ๋ฅผ ์‰ฝ๊ฒŒ ๋ถ„ํ•ดํ•˜๋Š” ๊ณผ์ •์— ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฌผ๋ก  IntelliJ์—๋Š” ํŠธ๋ฆฌ์˜ ์ฝ”๋“œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š” Flutter Outline ๋ณด๊ธฐ๊ฐ€ ์žˆ๊ณ  ์„ ํƒ ํ•ญ๋ชฉ์ด ํŽธ์ง‘๊ธฐ์˜ ์ปค์„œ ์œ„์น˜์™€ ๋™๊ธฐํ™” ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ์ผ๋ถ€ VS Code ๊ธฐ๋Šฅ์œผ๋กœ ๐Ÿ‘ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•˜์„ธ์š”!).

@pulyaevskiy
๋‚˜๋Š” ๋‹น์‹ ์ด ๋งํ•˜๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜์ง€๋งŒ ์‹คํ—˜์€ ์ข‹์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์ง„ํ™”์˜ ๊ธธ์ž…๋‹ˆ๋‹ค. DSX์— ๋Œ€ํ•œ ๋‚˜์˜ ์‹คํ—˜์ด ์‹คํŒจํ•˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๋‹ค๋ฅธ ๋งŽ์€ ๊ฒƒ์„ ์‹คํ—˜ํ•˜๊ณ  ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๋ฅผ ๋ชจ์•„ ๋†€๋ผ์šด ๊ธฐ์ˆ ์„ ๋งŒ๋“ค๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@sethladd
๋ฆฌ๋“œ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
@anders-sandholm @mit-mit ๋˜๋Š” @mraleph ์˜ ๋‹ต๋ณ€์„ ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
Dart 2 ์ธํ”„๋ผ ๋ฐ '๊ณตํ†ต ํ”„๋ก ํŠธ ์—”๋“œ'๋กœ ์ž‘์—…ํ•˜๋Š” ๋ฐฉ๋ฒ•.
@NathanaelA์™€ ํ•จ๊ป˜ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@DanTup

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

๊ทธ๋ž˜ ์ •ํ™• ํ•ด. ๋‚ด '์‚ฌ์†Œํ•˜๊ณ  ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„' ์ฃผ์„์€ โ€‹โ€‹ํŽธ์ง‘๊ธฐ๊ฐ€ .dsx ๊ตฌ๋ฌธ์„ ์ธ์‹ํ•˜๋„๋ก ํ•˜๋Š” ๋ฐ๋งŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Intellij๋ฅผ ์กฐ์‚ฌํ•œ ๊ฒฐ๊ณผ ์ด๋ฅผ ์œ„ํ•œ ์™„์ „ํ•œ ์–ธ์–ด ํŒŒ์„œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(๋ณต์žกํ•จ). ๋ฐ˜๋ฉด VS Code๋Š” ๊ตฌ๋ฌธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฌ์› ๊ณ  Typescript/Javascript ๊ตฌ๋ฌธ ํŒŒ์ผ์—๋Š” ์ด๋ฏธ JSX์— ๋Œ€ํ•œ ์ง€์›์ด ์žˆ์—ˆ๊ณ  DSX๋Š” JSX์—์„œ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝ๋จ).

์šฐ๋ฆฌ๋Š” ์‹คํ—˜์„ ์ง„ํ–‰ํ•˜๋Š” ๋ฐ ๋„์›€/์ง€์‹œ๋ฅผ ์œ„ํ•ด ๋‹น์‹ ์„ ๊ดด๋กญํž ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์š”์•ฝํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
(a) *.dsx ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๊ณ  *.dart ํŒŒ์ผ์„ ์ถœ๋ ฅํ•˜๋Š” ์ „์ฒ˜๋ฆฌ๊ธฐ.
https://spark-heroku-dsx.herokuapp.com/index.html

๋„์›€์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค:
(1) 'VS์ฝ”๋“œ' ํ†ตํ•ฉ์„ ๋‹ด๋‹นํ•  ์‚ฌ๋žŒ.
(2) ๋””๋ฒ„๊น…์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋„๋ก ์ „์ฒ˜๋ฆฌ๊ธฐ ๊ธฐ๋Šฅ์„ Flutter ๋นŒ๋“œ ์‹œ์Šคํ…œ์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋‚ผ ์‚ฌ๋žŒ. ๋‚ด ๋ง์€ ์ฝ”๋“œ ์Šคํ…Œํ•‘์ด ์†Œ์Šค๋งต ๋“ฑ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ํ†ตํ•ด *.dsx ํŒŒ์ผ์— ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

@NathanaelA ๊ฐ€ (2)๋ฅผ ๋„์™€๋“œ๋ฆฝ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ €๋Š” ์—ฌ์ „ํžˆ ๋„์›€์„ ์ค„ ์‚ฌ๋žŒ๋“ค์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค (1)
ํ…Œ์ด์ปค? @birkir @yuriy-manifold @tehfailsafe @alexkrolick @sanketsahusoft

@DanTup - ์ €๋Š” JSX์˜ ์ „๋ฌธ๊ฐ€๋Š” ์•„๋‹ˆ์ง€๋งŒ NativeScript XML ํ˜•์‹์— ๋Œ€ํ•ด ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ•  ์ˆ˜์žˆ๋Š”:

StackLayout ํด๋ž˜์Šค๊ฐ€ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ์†์„ฑ์€ XML์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๋Œ€์ผ ๊ด€๊ณ„์ž…๋‹ˆ๋‹ค. ์—„์ฒญ๋‚˜๊ฒŒ ๋งŽ์€ ๋ถˆํ•„์š”ํ•œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. Flutter ๋ฐ๋ชจ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/gallery/home.dart#L39 -L63

<AnimationBuilder animation="{{animation}}">
   <Stack>
      <BackgroundLayer top="{{-layer.parallaxTween.evaluate(animation)}}" left=0.0 right=0.0 bottom=0.0>
          <Image src="{{layer.assetName}}" package="{{layer.assetPackage}} fit="cover" height="{{maxHeight}"}/>
      </BackgroundLayer>
   </Stack>
</AnimationBuilder>

์ด๊ฒƒ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ณ€ํ™˜ํ•˜๋ฉด ๋” ์ฝ๊ธฐ ์‰ฝ๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. :์›ƒ์Œ์ด ๋„˜์น˜๋Š”:

@NathanaelA map ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ๋ณด๋‹ค ๋™์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ? ๋‹ค์Œ์€ ๋™์ผํ•œ ํŒŒ์ผ์˜ ์ผ๋ถ€ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

  Widget build(BuildContext context) {
    return new AnimatedBuilder(
      animation: animation,
      builder: (BuildContext context, Widget child) {
        return new Stack(
          children: _kBackgroundLayers.map((_BackgroundLayer layer) {
            return new Positioned(
              top: -layer.parallaxTween.evaluate(animation),
              left: 0.0,
              right: 0.0,
              bottom: 0.0,
              child: new Image.asset(
                layer.assetName,
                package: layer.assetPackage,
                fit: BoxFit.cover,
                height: _kFlexibleSpaceMaxHeight
              )
            );
          }).toList()
        );
      }
    );
  }

์ด ๊ตฌ๋ฌธ์—์„œ children: _kBackgroundLayers.map(...) ๋Š” ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์Šต๋‹ˆ๊นŒ?

JSX/DSX๋Š” ํƒœ๊ทธ ๋ณ€ํ™˜๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ž…๋ ฅ:
<A property="a"/>
๋ฐ–:
new A(property: a)

์ž…๋ ฅ:

<A property="a">
  <B/>
  <C/>
</A>

๋ฐ–:

new A(property: a, 
children: <Widget>[
   new B(), 
   new C()
])

{}๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€์ˆ˜ ํ‰๊ฐ€ ๋ฐ ์ต๋ช… ํ•จ์ˆ˜ ๋“ฑ๊ณผ ๊ฐ™์€ ์œ ํšจํ•œ Dart ์ฝ”๋“œ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. {}๋Š” 3๊ณณ์— ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ๋Š” 2๊ณณ(ํƒœ๊ทธ ์†์„ฑ ๋ฐ ์ž์‹)์—์„œ ์‚ฌ์šฉ๋œ {}๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์„ธ ๋ฒˆ์งธ๋Š” ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  Widget build(BuildContext context) {
    return <AnimatedBuilder
      animation={animation}
      builder={(BuildContext context, Widget child) {
        return <Stack> {
          _kBackgroundLayers.map((_BackgroundLayer layer) {
            return <Positioned
              top={-layer.parallaxTween.evaluate(animation)}
              left={0.0}
              right={0.0}
              bottom={0.0}>
              <Image.asset [layer.assetName]
                package={layer.assetPackage}
                fit={BoxFit.cover}
                height={_kFlexibleSpaceMaxHeight}
              />
            </Positioned>;
          }).toList()
        } </Stack>;
      }}
    />;
  }

์œ„์˜ ์ฝ”๋“œ๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์— ๋„ฃ๊ณ  VS Code/Intellij๋กœ ํ™•์ธํ•˜์„ธ์š”. XML ๋…ธ๋“œ๋ฅผ ์—ด๊ณ  ์ถ•์†Œํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ๋” ์ž‘๊ฒŒ/๋” ํฌ๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” +/-(์ค„ ์™ผ์ชฝ)์— ์ฃผ๋ชฉํ•˜์‹ญ์‹œ์˜ค.

์™œ ์šฐ๋ฆฌ๋Š” ๋ฌธ์ œ๋ฅผ ์ธ์ •ํ•˜๊ณ  React Native ๋ฐฉ์‹์„ ์ฑ„ํƒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ? ์šฐ๋ฆฌ๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•  ๊ฒƒ์ธ๊ฐ€, ๋ง ๊ฒƒ์ธ๊ฐ€?

@JonathanSum ์—ฌ๊ธฐ๋กœ ์•ˆ๋‚ด๋˜์–ด ์ฃ„์†กํ•˜์ง€๋งŒ ๋‹น์‹ ์€ ๋ˆ„๊ตฌ๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? ๋‹น์‹ ์ด ์ข‹์•„ํ•˜์ง€ ์•Š๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ๋Š” ์—†์Šต๋‹ˆ๋‹ค.
Flutter๋กœ ๋‹จ์ผ ์•ฑ์„ ์ž‘์„ฑํ•ด ๋ณด์…จ๋‚˜์š”?
Dart์™€ XML์„ ํ˜ผํ•ฉํ•œ ์œ„์˜ ์˜ˆ๋Š” Dart๋ณด๋‹ค ํ›จ์”ฌ ๋‚˜๋น  ๋ณด์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.
์ €๋Š” xaml์„ ์‚ฌ์šฉํ•˜๋Š” Xamarin Forms์—์„œ ์™”์œผ๋ฉฐ ์ •๋ง ์ข‹์•„ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Flutter๊ฐ€ Xaml์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์œ ์— ๋Œ€ํ•ด ๋ถˆํ‰ํ•˜๋Š” ๋Œ€์‹  ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์ ์‘ํ•˜๊ณ  ๋ฐฐ์šฐ๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.
React์—์„œ์ฒ˜๋Ÿผ ์ผํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์—ฌ๊ธฐ ์žˆ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์„ ์งœ์ฆ๋‚˜๊ฒŒ ํ•˜๋Š” ๋Œ€์‹  Reactive๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

๋‹ค์Œ์€ ์œ„์™€ ๋™์ผํ•œ ์ฝ”๋“œ ๋ธ”๋ก์ด์ง€๋งŒ ์ˆœ์ˆ˜ํ•œ Dart์—์„œ ๊นŠ์€ ์ค‘์ฒฉ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌํŒฉํ† ๋ง๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
์•„๋ž˜ ์Šค๋‹ˆํŽซ์˜ ์–ด๋–ค ๋ถ€๋ถ„์ด ์ฝ๊ธฐ ๋ฐ/๋˜๋Š” ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šด์ง€ ๊ถ๊ธˆํ•˜์‹ญ๋‹ˆ๊นŒ?

Widget build(BuildContext context) =>
    AnimatedBuilder(animation: animation, builder: _buildChild);

_buildChild(BuildContext context, Widget child) {
  return Stack(
    children: _kBackgroundLayers.map((_BackgroundLayer layer) {
      final image = Image.asset(layer.assetName,
          package: layer.assetPackage,
          fit: BoxFit.cover,
          height: _kFlexibleSpaceMaxHeight);
      return Positioned(
          top: -layer.parallaxTween.evaluate(animation),
          left: 0.0,
          right: 0.0,
          bottom: 0.0,
          child: image);
    }).toList(),
  );
}

์‚ฌ์‹ค, ๊ฐœ์ธ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ด๊ฒŒ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

Widget build(BuildContext context) => AnimatedBuilder(
      animation: animation,
      builder: _buildChild,
    );

_buildChild(BuildContext context, Widget child) {
  return Stack(
    children: _kBackgroundLayers.map(_imageForLayer).toList(),
  );
}

_imageForLayer(_BackgroundLayer layer) {
  final top = -layer.parallaxTween.evaluate(animation);
  final image = Image.asset(
    layer.assetName,
    package: layer.assetPackage,
    fit: BoxFit.cover,
    height: _kFlexibleSpaceMaxHeight,
  );
  return PositionedImage(top: top, image: image);
}

class PositionedImage extends StatelessWidget {
  PositionedImage({this.top, this.image});
  final double top;
  final Image image;

  <strong i="10">@override</strong>
  Widget build(BuildContext context) =>
      Positioned(top: top, left: 0.0, right: 0.0, bottom: 0.0, child: image);
}

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์— ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ํ˜ผํ•ฉ๋˜์–ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. Dart ๊ตฌ๋ฌธ์„ ์‹ซ์–ดํ•˜๊ณ  XML/JSX์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์ด ํ•„์š”ํ•จ
  2. Flutter ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ.

JSX๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๊ฐ€๋…์„ฑ์ด ํ•ด๊ฒฐ๋  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ฝ”๋“œ์— ๊นŠ๊ฒŒ ์ค‘์ฒฉ๋œ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๊ฐ€๋Šฅํ•˜๋ฉฐ ๊ฐœ๋ฐœ์ž๋Š” ๋‚ด๊ฐ€ ๋ฐฉ๊ธˆ Dart ๋ฒ„์ „์—์„œ ์ˆ˜ํ–‰ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ์•ผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ํ™•์‹คํžˆ ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์€ ์†Œ์Šค ๋งต๊ณผ ๊ณต๋™์œผ๋กœ ์ถ”๊ฐ€ ๋นŒ๋“œ/ํŠธ๋žœ์ŠคํŒŒ์ผ ๋‹จ๊ณ„์™€ IDE ๋ฐ Dart SDK(๋ถ„์„๊ธฐ, ๋””๋ฒ„๊ฑฐ ๋“ฑ)์—์„œ ์ด ์ธํ”„๋ผ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•œ ๋งŽ์€ ์ž‘์—…์ž…๋‹ˆ๋‹ค.

@JonathanSum @escamoteur ์šฐ๋ฆฌ๋Š” ์ด ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ๊ณต๊ฒฉ์ ์œผ๋กœ ๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜‘๋ ฅ ๊ด€๊ณ„๋ฅผ ์œ ์ง€ํ•˜์‹ญ์‹œ์˜ค. ๊ฐ์‚ฌ ํ•ด์š”. ์ตœ๊ทผ ํ† ๋ก ์€ ์นœ์ ˆํ•˜๊ณ  ์ƒ์‚ฐ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํ† ๋ก ์— ์ฐธ์—ฌํ•ด์ฃผ์‹  ๋ชจ๋“  ๋ถ„๋“ค๊ป˜ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

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

@Hixie ํ™”๋ฅผ ๋‚ด์„œ ๋ฏธ์•ˆํ•˜์ง€๋งŒ Flutter๋Š” ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ์ข‹์€ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€๊ณ  ์žˆ๊ณ  Flutter ๊ฐœ๋ฐœ์ž๋Š” ์ด๋Ÿฐ ์š”๊ตฌ ์—†์ด๋„ ์ถฉ๋ถ„ํžˆ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@escmoteur - ๊ทธ๊ฒƒ์ด ๋‚ด๊ฐ€ "์ปค๋ฎค๋‹ˆํ‹ฐ" ๋…ธ๋ ฅ์„ ๊ตฌ์ฒด์ ์œผ๋กœ ๋งํ•œ ์ด์œ ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ๊ธฐ๊บผ์ด ํŒจ์น˜๋ฅผ ์ˆ˜๋ฝํ•˜๋Š” ๊ฒƒ ์ด์ƒ์œผ๋กœ ํ”Œ๋Ÿฌํ„ฐ ์ฝ”์–ด ํŒ€์„ ํฌํ•จํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค... ์–ด๋Š Seth๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ๊ณ„์†ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋งํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์— ๊ด€์‹ฌ์ด ์—†๋‹ค๋ฉด; ๊ทธ๋Ÿฐ ๋‹ค์Œ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”... :์›ƒ์œผ๋ฉด์„œ:

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

๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์ฝ๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฝ๊ณ  ์ง€์˜ฅ์ฒ˜๋Ÿผ ๋ณต์žกํ•˜์ง€ ์•Š์•„์•ผํ•˜๋Š” ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ React-Native ๋นŒ๋“œ ๋ฐฉ์‹์ด ์ธ๊ฐ„์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ์‹์„ ๋”ฐ๋ฅธ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— flutter๋Š” stateful ์œ„์ ฏ์„ stateless์— ์—ฐ๊ฒฐํ•ด์•ผ ํ•˜๊ณ ... ๊ฒŒ๋‹ค๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์š”์ฆ˜ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ UI ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ด React ๋ฐฉ์‹์„ ํ‘œ์ค€์œผ๋กœ ํ•˜๊ณ  ์žˆ๊ณ , flutter๋Š” ์ด๊ฒƒ์— ๋” ์ง‘์ค‘ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ•ซ ๋ฆฌ๋กœ๋“œ ๋Œ€์‹ (์ƒˆ ํด๋ž˜์Šค๋ฅผ ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์ฝ˜์†”์€ ํ•ซ ๋ฆฌ๋กœ๋“œ ๋Œ€์‹  ๋ชจ๋“  ๊ฒƒ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ผ๊ณ  ์•Œ๋ ค์ค๋‹ˆ๋‹ค). ๋‚˜๋Š” ์ด๊ฒƒ์ด ์˜๊ฒฌ์ด๋‚˜ ์š”๊ตฌ๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๋‚˜์ด๋ฒ ๊ฐ€์ด๊ฐ€ ๋งํ–ˆ๋‹ค.

Flutter๋ฅผ "๋œจ๊ฑฐ์šด ์ƒˆ ๊ฒƒ"์ฒ˜๋Ÿผ ๋งŒ๋“ค๋ ค๋Š” ์‹œ๋„๋ฅผ ์ค‘๋‹จํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๊ฒƒ์€ ๊ทธ ์ž์ฒด๋กœ ๋œจ๊ฑฐ์šด ์ƒˆ๋กœ์šด ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ํŒจ๋Ÿฌ๋‹ค์ž„์„ ํƒ๊ตฌํ•˜๊ฒŒ ํ•˜์‹ญ์‹œ์˜ค.

๋‹น์‹ ์€ ๊ทธ๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://facebook.github.io/react-native/
React์—์„œ ์ƒ๊ฐํ•˜๊ธฐ:
https://reactjs.org/docs/design-principles.html
์‹ค๋ฃฉ ๊ฑฐ๋ฆฌ๋‹ค:
https://flutter.io/tutorials/animation/

React-Native๋ฅผ ๋ณด๋ฉด ์œ„์˜ ์ƒํƒœ ๊ด€๋ฆฌ์™€ ์•„๋ž˜์˜ UI ๋ถ€๋ถ„๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์˜ˆ์ˆ ์ด๋ฉฐ ์ธ๊ฐ„์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด ํ–‰๋™์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ํ•™์Šต ๊ณก์„ ๊ณผ ๊ด€๋ฆฌ ์‹œ๊ฐ„์ด ์งง์€ ์ด์œ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ XML์ด๋‚˜ Xamarin์„ React Native์™€ ๋น„๊ตํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๊ฒŒ๋‹ค๊ฐ€ ํผํ„ฐ๋Š” ํ˜ผ๋ˆ๊ณผ ๋ฌด์งˆ์„œ์™€๋„ ๊ฐ™๋‹ค. stateless๋Š” stateful์— ์—ฐ๊ฒฐํ•˜๊ณ  create-state๋Š” stateless์˜ ๋ชจ๋“  ๊ฒƒ์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. React-Native๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฐํ•„๋กœ ์•„๋ฆ„๋‹ค์šด ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŽ„๋Ÿญ์ด๋Š” ๊ฒƒ์€ ์ข…์ด์— ๋ฌผ์„ ๋–จ์–ด๋œจ๋ฆฌ๊ณ  ๋ฌผ์„ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ์•„์ง ํ”Œ๋Ÿฌํ„ฐ์˜ ์ดˆ๊ธฐ ๋‹จ๊ณ„์— ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. React-Native๋Š” ๋‚˜๋ฆ„์˜ ์ฒ ํ•™๊ณผ ๋ชฉํ‘œ๊ฐ€ ์žˆ๊ณ , flutter๋Š” ๊ทธ๋ƒฅ ์ง„์ง€ํ•œ ํ”„๋กœ์ ํŠธ์ด๊ฑฐ๋‚˜, ์•„๋‹ˆ๋ฉด ๋ชจ๋‘๊ฐ€ ์ €์—๊ฒŒ ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@JonathanSum

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

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

๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์ฝ๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฝ๊ณ  ์ง€์˜ฅ์ฒ˜๋Ÿผ ๋ณต์žกํ•˜์ง€ ์•Š์•„์•ผํ•˜๋Š” ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋™์–ด๋ฐ˜๋ณต์ž…๋‹ˆ๋‹ค. ๋ถ„๋ช…ํžˆ ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์ด๊ฒƒ์„ ์›ํ•˜์ง€๋งŒ ์‚ฌ๋žŒ๋“ค์€ ๋ฌธ์ œ์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. Flutter์˜ ํŒจ๋Ÿฌ๋‹ค์ž„์ด ๊ทธ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ React-Native ๋นŒ๋“œ ๋ฐฉ์‹์ด ์ธ๊ฐ„์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋นŒ๋“œํ•˜๋Š” ๋ฐฉ์‹์„ ๋”ฐ๋ฅธ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

UI ๊ตฌ์ถ•์„ ์œ„ํ•œ ๊ตฌ๋ฌธ๋งŒํผ ์‚ฌ์†Œํ•œ ๊ฒƒ์ด ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ „๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ์ •๋„์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์—, Flutter๋Š” Stateful ์œ„์ ฏ์„ Stateless์— ์—ฐ๊ฒฐํ•ด์•ผ ํ•˜๊ณ ...

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

๊ฒŒ๋‹ค๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์š”์ฆ˜ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ UI ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ด React ๋ฐฉ์‹์„ ํ‘œ์ค€์œผ๋กœ ์‚ผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋…ผ์Ÿ ๊ด‘๊ณ  ๋Œ€์ค‘.

๊ทธ๋ฆฌ๊ณ  flutter๋Š” hot reload๋ณด๋‹ค ์ด๊ฒƒ์— ๋” ์ง‘์ค‘ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(์ƒˆ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์ฝ˜์†”์€ hot reload ๋Œ€์‹  ๋ชจ๋“  ๊ฒƒ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ผ๊ณ  ์•Œ๋ ค์ค๋‹ˆ๋‹ค)

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

๊ทธ๋Ÿฌ๋‚˜ ํผํ„ฐ๋Š” ํ˜ผ๋ˆ๊ณผ ๋ฌด์งˆ์„œ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ•™์Šต ๊ณก์„ ๊ณผ ๊ด€๋ฆฌ ์‹œ๊ฐ„์ด ์งง์Šต๋‹ˆ๋‹ค. XML์ด๋‚˜ Xamarin์„ React Native์™€ ๋น„๊ตํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

์ถฉ๋ถ„ํžˆ ๊ณต์ •ํ•ฉ๋‹ˆ๋‹ค - ๊ทธ๋Ÿฐ ๋‹ค์Œ React Native๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๊ณณ์˜ ๊ฐœ๋ฐœ์ž๋“ค์€ ์ž์‹ ์˜ ํŒจ๋Ÿฌ๋‹ค์ž„์œผ๋กœ ํ›Œ๋ฅญํ•œ ์ผ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

stateless๋Š” stateless์— ์—ฐ๊ฒฐํ•˜๊ณ  stateless์—์„œ ์ƒํƒœ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋ญ๋ผ๊ณ  ์š”? ์•„๋‹ˆ์š”. ์ด๊ฒƒ์€ ๋ช…๋ฐฑํžˆ ์ž˜๋ชป๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋‹น์‹ ์˜ ์š”์ ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

React-Native๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฐํ•„๋กœ ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŽ„๋Ÿญ์ด๋Š” ๊ฒƒ์€ ์ข…์ด์— ๋ฌผ๋ฐฉ์šธ์ด ๋–จ์–ด์ ธ ๋ฌผ์„ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์†”์งํžˆ ๋งํ•ด์„œ, ์ด ๋น„์œ ๋Š” ๋‚˜์—๊ฒŒ ๊ฑฐ์˜ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ฐ˜๋Œ€ ์˜๊ฒฌ์„ ์‰ฝ๊ฒŒ ๋งํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์—์„œ ์‹œ์ž‘ํ•œ ๊ณณ์œผ๋กœ ๋ฐ”๋กœ ๋Œ์•„๊ฐˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์ด ์ด๋ ‡๊ฒŒ ํ–‰๋™ํ•˜๋Š” ๊ฒƒ์€ ์ž๋ช…ํ•œ ์ผ์ด๋ฉฐ("์ง๋ฉดํ•ด ๋ด…์‹œ๋‹ค") Flutter ํŒ€์ด ์ด ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์šฐ๋ฆฌ๋Š” ํ—ˆ์„ธ๋ฅผ ๋ถ€๋ฆฌ๊ฑฐ๋‚˜ ์ฐธ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๋‹น์‹ ์„ ์ง„์ง€ํ•˜๊ฒŒ ๋ฐ›์•„๋“ค์ด๊ธฐ๋ฅผ ๋ฐ”๋ž€๋‹ค๋ฉด ์ด๊ฒƒ์€ ์ข‹์€ ํƒœ๋„๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

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

@naiveaiguy
์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ์˜ณ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์—ฌ๊ธฐ ์žˆ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ๊ณผ React๋ฅผ ์ข‹์•„ํ•˜๋Š” ์‚ฌ๋žŒ์„ ๋น„๊ตํ•˜๋Š” ์ž„์˜์˜ ์‚ฌ๋žŒ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. Flutter์—๋Š” ๊ณ ์œ ํ•œ ๋ฐฉ์‹์ด ์žˆ๊ณ  React์—๋„ ๊ณ ์œ ํ•œ ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ํƒœ๋„์— ๋Œ€ํ•ด ๋ฏธ์•ˆํ•˜๊ณ , ๋‚˜๋Š” ์ฐฉํ•˜์ง€ ์•Š์•˜๋‹ค.

@JonathanSum Flutter ์•ฑ์ด ์–ด๋–ป๊ฒŒ ๊ตฌ์ถ•๋˜์—ˆ๋Š”์ง€ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๋ ค๋ฉด ์‹œ๊ฐ„์ด ๋” ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ณต์ •ํ•˜๊ฒŒ ๋งํ•˜๋ฉด ์•„ํ‚คํ…์ฒ˜, ์ƒ์†๋œ ์œ„์ ฏ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ๋ฐ ๋ทฐ ๋ชจ๋ธ์„ ์œ„์ ฏ์— ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋ฌธ์„œ๊ฐ€ ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์•Œ๊ณ  ์‹ถ์€ ๊ฒƒ์€ ์™œ Flutter์— ์ „ํ˜€ ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๊นŒ? ๋‚˜์—๊ฒŒ React๋Š” JS ๋•Œ๋ฌธ์— ๊ฐˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋Œ“๊ธ€์„ ๋„ˆ๋ฌด ๋งŽ์ด, ๋„ˆ๋ฌด ์ ์€ ์‹œ๊ฐ„, ์•„๋งˆ๋„ ์ง‘์ค‘ํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค...

@escamoteur ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ?

๋‚˜์—๊ฒŒ React๋Š” JS ๋•Œ๋ฌธ์— ๊ฐˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ES6/7 ๋˜๋Š” Typescript๋Š” Dart/Kotlin/Swift์— ๋งค์šฐ ๊ฐ€๊น๊ธฐ ๋•Œ๋ฌธ์— ์ด ์—ฌ์„ฑ๋“ค๊ณผ ํ•จ๊ป˜ ์ฆ๊ฒ๊ฒŒ ์ถค์„ ์ถœ ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

Flutter์— ๋งค๋ฃŒ๋œ ๊ฒƒ์€ ๊ทธ๋ž˜ํ”ฝ ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ง€์›์ž…๋‹ˆ๋‹ค. 60fps์˜ ์ดˆ๊ณ ์† UX๋ฅผ ์œ„ํ•ด OpenGL ์œ„์— ๊ตฌ์ถ•๋œ Direct Skia Vector ๊ทธ๋ž˜ํ”ฝ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://uimovement.com/
์ €๋Š” ๋งž์ถคํ˜• UX์— ๋น ์ ธ ์žˆ๊ณ  Flutter๊ฐ€ ์ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ˆ˜์‹ญ ๋…„ ๋™์•ˆ UX๋ฅผ ๊ตฌํ˜„ํ•ด ์™”์œผ๋ฉฐ ์„ ์–ธ์ /๋ฐ˜์‘์  ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์ •๋ง ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. Flutter๋Š” ์ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

@pulyaevskiy

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์— ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ํ˜ผํ•ฉ๋˜์–ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Dart ๊ตฌ๋ฌธ์„ ์‹ซ์–ดํ•˜๊ณ  XML/JSX์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์ด ํ•„์š”ํ•จ
  • Flutter ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ.

๋งž์Šต๋‹ˆ๋‹ค. ์ด ํ‹ฐ์ผ“(๊ทธ๋ฆฌ๊ณ  ์ด์ „ ํ‹ฐ์ผ“)์€ JSX์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์›ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ UI ๋นŒ๋“œ ์ฝ”๋“œ์˜ ์žฅํ™ฉํ•จ์„ ์ค„์ด๊ธฐ ์œ„ํ•œ Dart ์–ธ์–ด ๊ฐœ์„ ์„ ์œ„ํ•œ ๋‹ค๋ฅธ ํ‹ฐ์ผ“์ด ์žˆ์Šต๋‹ˆ๋‹ค.

JSX๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๊ฐ€๋…์„ฑ์ด ํ•ด๊ฒฐ๋  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ๋Š” ์‚ฌ๋žŒ๋“ค์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๊ทธ๋“ค์—๊ฒŒ๋Š” ๊ฐ์ž์˜ ๊ฒƒ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๊ทธ๋Ÿฌ๋‚˜ ํ™•์‹คํžˆ ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์€ ์†Œ์Šค ๋งต๊ณผ ๊ณต๋™์œผ๋กœ ์ถ”๊ฐ€ ๋นŒ๋“œ/ํŠธ๋žœ์ŠคํŒŒ์ผ ๋‹จ๊ณ„์™€ IDE ๋ฐ Dart SDK(๋ถ„์„๊ธฐ, ๋””๋ฒ„๊ฑฐ ๋“ฑ)์—์„œ ์ด ์ธํ”„๋ผ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•œ ๋งŽ์€ ์ž‘์—…์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์œผ๋ฉฐ @sethladd ๋Š” I believe one of the goals of Dart 2 was to create an infrastructure for more experimentation with the language and let the community create experiments like DSX.

@naiveaiguy

์ €๋Š” Flutter๊ฐ€ ์ฝ”๋“œ ๋ณ€๊ฒฝ์˜ 30-40%์—์„œ๋„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฐœ๋ฐœ ์ฃผ๊ธฐ๊ฐ€ ์ •๋ง ์ธ์ƒ์ ์ด๋ฉฐ ํŠธ๋žœ์ŠคํŒŒ์ผ ๋ ˆ์ด์–ด์— ์˜ํ•ด์„œ๋งŒ ๋Š๋ ค์งˆ ๊ฒƒ์ด๋ผ๊ณ  ์ฃผ์žฅํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

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

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

์„ค๋งˆ. ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ฐจ๋‹จ๋˜์ง€ ์•Š๊ธฐ๋ฅผ ์š”์ฒญํ•  ๋ฟ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ ์šฐ๋ฆฌ๋ฅผ ๊ฐ€๋ฅด์น  ์ง€์นจ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ๋ชจ๋“  ๊ฒƒ์„ ํ˜ผ์ž ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฏ€๋กœ ์ด์ œ ์šฐ๋ฆฌ ์ค‘ 2๋ช…์ด ์žˆ๊ณ (@NathanaelA์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค) ๋„์›€์„ ์›ํ•˜์‹œ๋ฉด ๋” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค(์ตœ์†Œ 1๋ช… ์ด์ƒ)์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”! ์šฐ์„ , ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ์•ž๋’ค๋กœ ๋…ผ์˜๋ฅผ ๊ณ„์†ํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค๋Š” ์ ์„ ์ง€์ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์„ ํ˜• ๊ตฌ์กฐ๋กœ ์ธํ•ด ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๊ณ  ๋”ฐ๋ฅด๊ธฐ ์–ด๋ ค์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ์ฃผ์žฅ์€ ์†์‹ค๋˜๊ณ  ๊ณ„์†ํ•ด์„œ ๋‹ค์‹œ ํ•ด์‹œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์ˆœ์ˆ˜ํ•œ ์ˆซ์ž๋กœ ์ค„์ด์ž:

  • ๋‹น์‹ ์ด ์ด ๊ธฐ๋Šฅ์— ์ฐฌ์„ฑํ•œ๋‹ค๋ฉด - ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ฒซ ๋ฒˆ์งธ ์˜๊ฒฌ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ๊ธฐ๋Šฅ์— ๋ฐ˜๋Œ€ํ•˜๋Š” ๊ฒฝ์šฐ - ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ฒซ ๋ฒˆ์งธ ์˜๊ฒฌ์„ ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ, @sethladd ์˜ ์ง„์ˆ ์„ ๋ช…ํ™•ํžˆ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. _"Dart 2์˜ ๋ชฉํ‘œ ์ค‘ ํ•˜๋‚˜ ๋Š” Dart ํŒ€์„ ์œ„ํ•œ ์–ธ์–ด๋กœ ๋” ๋งŽ์€ ์‹คํ—˜์„ ์œ„ํ•œ ์ธํ”„๋ผ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. "_.

Dart 2์—์„œ๋„ Dart SDK(๋˜๋Š” Flutter ์—”์ง„ ์•„ํ‹ฐํŒฉํŠธ)๋ฅผ ๋‹ค์‹œ ๋นŒ๋“œํ•˜์ง€ ์•Š๊ณ ๋„ Dart ์–ธ์–ด์˜ ๊ตฌ๋ฌธ์„ ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” API๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Dart 2๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ _๊ณตํ†ต ํ”„๋ŸฐํŠธ ์—”๋“œ_(CFE) ์ธํ”„๋ผ(Dart SDK ์†Œ์Šค์˜ pkg/front_end ์— ์žˆ์Œ)์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Dart๋กœ ์ž‘์„ฑ๋œ Dart ์–ธ์–ด์šฉ ํŒŒ์„œ์ž…๋‹ˆ๋‹ค. DSX์™€ ๊ฐ™์€ ์ˆœ์ˆ˜ํ•œ ๊ตฌ๋ฌธ ์„คํƒ• ์–ธ์–ด ๋ณ€๊ฒฝ์˜ ๊ฒฝ์šฐ CFE ์ฝ”๋“œ๋ฅผ ํŽธ์ง‘ํ•˜๊ณ  Dart SDK(๋˜๋Š” Flutter ์—”์ง„)๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๋ชจ๋“  ๋„๊ตฌ(๊ฐ IDE ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋นŒ๋“œ๋œ ๊ตฌ๋ฌธ ๊ฐ•์กฐ ์ฝ”๋“œ ์ œ์™ธ)๊ฐ€ ์ƒˆ ๊ตฌ๋ฌธ ํ™•์žฅ์„ ์„ ํƒํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ VM๊ณผ dart2js๋งŒ ์‹ค์ œ๋กœ CFE๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ๋ถ„์„๊ธฐ๋Š” ๋‹ค์Œ์— ์ „ํ™˜๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๋ณด์‹œ๋‹ค์‹œํ”ผ ์—ฌ๊ธฐ์— ์ง„์ž… ์žฅ๋ฒฝ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๊ฐ•์กฐํ•ด์•ผ ํ•  ์ค‘์š”ํ•œ ์ ์€ Dart ๊ตฌ๋ฌธ์„ ํ™•์žฅํ•˜๋Š” API๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— Dart ์–ธ์–ด ํŒ€๊ณผ ํ˜‘๋ ฅํ•˜์—ฌ ์–ธ์–ด๋ฅผ ํ™•์žฅํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ์ด์— ๋Œ€ํ•œ ๊ณต์‹ํ™”๋œ ํ”„๋กœ์„ธ์Šค๋Š” ์—†์ง€๋งŒ DSX์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์˜ ๊ฒฝ์šฐ Dart์— ํฌํ•จ๋˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋งŽ์€ ์ฆ๊ฑฐ์™€ ๋™๊ธฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. (/fyi @leafpetersen @lrhn - ๋‚ด๊ฐ€ ํ‹€๋ ธ๋‹ค๋ฉด ์ •์ •ํ•ด์ฃผ์„ธ์š”)

๋‹ค์Œ์€ DSX์™€ ๊ฐ™์€ ์†”๋ฃจ์…˜์„ ์ง€์ง€ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๊ถŒ์žฅํ•˜๋Š” ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

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

    • ์ œ์•ˆ์„œ๋ฅผ Google ๋ฌธ์„œ์— ๋„ฃ์œผ๋ฉด ์‚ฌ๋žŒ๋“ค์ด ๊ธฐ๋ณธ ์ฃผ์„์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œ์•ˆ์„œ์˜ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ์š”์†Œ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋˜๋Š” ์ œ์•ˆ์— ๋Œ€ํ•œ ๋งˆํฌ๋‹ค์šด ์„ค๋ช…์ด ํฌํ•จ๋œ GitHub ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  GitHub ๋ฌธ์ œ ๋ฐ PR์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œ์•ˆ์„ ์ˆ˜์ •ํ•˜๊ณ  ๋…ผ์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    ์ฐธ๊ณ ๋กœ, ์ˆ˜์ • ์ˆ˜์ค€์—์„œ Dart ์–ธ์–ด ์‚ฌ์–‘๊ณผ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด _๊ณต์‹ ์‚ฌ์–‘_์„ ์ œ์‹œํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋Œ€์‹  ์ œ์•ˆ๋œ ๋ณ€๊ฒฝ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๊ณ  ์–ด๋–ค ์ด์ ์„ ์ œ๊ณตํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ๊ด‘๋ฒ”์œ„ํ•œ ์˜ˆ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


  • ๋‹ค์Œ์œผ๋กœ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๊ตฌํ˜„์„ ์‹œ๋„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. CFE ์ธํ”„๋ผ์—์„œ๋„ ์žฅ๋ฒฝ์€ ๋†’์ง€๋งŒ ์ด์ „๋ณด๋‹ค ํ›จ์”ฌ ๋‚ฎ์Šต๋‹ˆ๋‹ค.

@mraleph Dart๋กœ์˜ ํ†ตํ•ฉ์— ๋Œ€ํ•œ ์ฃผ์žฅ์€ ์–ธ์–ด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ฝ”๋“œ ์ƒ์„ฑ ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•œ ํ›„ํฌ์— ๊ด€ํ•œ ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ๊ทธ๋Ÿฐ ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ „ํ˜€ ๋ชจ๋ฅธ๋‹ค.
HTML ๋Œ€์‹  DSX๋งŒ ์‚ฌ์šฉํ•˜๋Š” Analyzer ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์žˆ๋Š” Angular์ฒ˜๋Ÿผ ๋Œ€๋ถ€๋ถ„ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@mraleph

์„ค๋ช…ํ•ด์ฃผ์…”์„œ ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
์šฐ๋ฆฌ๋Š” ์‹ค์ œ๋กœ Dart ์–ธ์–ด๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ ๊ฒƒ์€ ์‹คํ—˜์ ์ธ DSX๋ฅผ Dart๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ์ „์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ  ๋‹ค์Œ์—์„œ ์˜จ๋ผ์ธ์œผ๋กœ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://spark-heroku-dsx.herokuapp.com/index.html

๋ฌธ์ œ๋Š” Dart๊ฐ€ ์ฒ˜์Œ ๋‚˜์™”์„ ๋•Œ Javascript๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  ์†Œ์Šค ๋งต์„ ์‚ฌ์šฉํ•˜์—ฌ Javascript ์ƒํƒœ๊ณ„์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค(์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์–ธ์–ด๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์˜€์Šต๋‹ˆ๋‹ค: Coffeescript, Typescript ๋“ฑ). ์šฐ๋ฆฌ๊ฐ€ ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์€ Dart/Flutter์— ๋Œ€ํ•ด ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ํŠธ๋žœ์ŠคํŒŒ์ผ ์–ธ์–ด๊ฐ€ Dart/Flutter ์œ„์— ๊ตฌ์ถ•๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์‚ฌ์ „ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํˆฌํ‘œ์™€ ๊ด€๋ จํ•˜์—ฌ ์ด์ „ ํ‹ฐ์ผ“์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆซ์ž๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/flutter/flutter/issues/11609

@cbazza

์šฐ๋ฆฌ๋Š” ์‹ค์ œ๋กœ Dart ์–ธ์–ด๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ ๊ฒƒ์€ ์‹คํ—˜์ ์ธ DSX๋ฅผ Dart๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ์ „์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

*.dsx ํŒŒ์ผ์ด ์‹ค์ œ๋กœ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Dart ํŒŒ์ผ์ด๋ผ๋Š” ๊ด€์ ์—์„œ ์ด์•ผ๊ธฐํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด ํ˜„์žฌ ์ด๋Ÿฌํ•œ ๊ตฌ๋ฌธ ํ™•์žฅ์ด Dart ์ƒํƒœ๊ณ„์˜ ๋ชจ๋“  ๋„๊ตฌ์™€ ํˆฌ๋ช…ํ•˜๊ฒŒ ์ƒํ˜ธ ์šด์šฉ๋˜๋„๋ก ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ด๋Ÿฌํ•œ ๊ตฌ๋ฌธ ํ™•์žฅ์˜ ์ƒ์„ฑ์„ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๋Š” API ๋˜๋Š” ํ™•์žฅ ์ง€์ ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋Ÿฌํ•œ API ๋˜๋Š” ํ™•์žฅ ์ง€์ ์„ ์„ค๊ณ„ํ•˜๊ณ  ์ œ๊ณตํ•  ์ฆ‰๊ฐ์ ์ธ ๊ณ„ํš์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ˜„์žฌ๋กœ์„œ๋Š” Dart SDK๋ฅผ ํฌํฌํ•˜๊ณ  CFE์— DSX ์ง€์›์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‹จ์ˆœํ•œ ์ผ€์ด์Šค๋ณด๋‹ค๋Š” ๋ชจ์„œ๋ฆฌ ์ผ€์ด์Šค์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด DSX ํŒŒ์ผ์„ ํŽธ์ง‘ํ•œ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ณด์‹ญ์‹œ์˜ค. ์ด ๊ฒฝ์šฐ ์ƒ์„ฑ์ž ์ด๋ฆ„ ๋ฐ ์†์„ฑ ์ด๋ฆ„๊ณผ ๊ฐ™์ด ๋ฐ˜์ฏค ์™„์„ฑ๋œ ์ฝ”๋“œ์—์„œ ์‹ค์‹œ๊ฐ„ ์™„์„ฑ์„ ๋ณด๊ณ  ์‹ถ์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค. ์†Œ์Šค ๋งคํ•‘์—์„œ๋Š” ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ• ๊นŒ์š”? ๊ทธ๋Ÿฐ ๊ฒƒ๋“ค์ด ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

@mraleph ๋‹ค์‹œ ํ•œ๋ฒˆ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ํ™•์‹คํžˆ DSX ์‚ฌ์šฉ์ž์—๊ฒŒ ํ›Œ๋ฅญํ•œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ์‚ผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

XML๊ณผ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์ข‹์•„ํ•˜๋Š” ์‚ฌ๋žŒ๋„ ์žˆ๊ณ  ์‹ซ์–ดํ•˜๋Š” ์‚ฌ๋žŒ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. jsx์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๋„ˆ๋ฌด ๊ณผ๋„ํ•ฉ๋‹ˆ๋‹ค. Flutter์— ๋Œ€ํ•œ ๋‚˜์˜ ์ฃผ์š” ๊ด€์‹ฌ์‚ฌ๋Š” ๊ฐ€๋…์„ฑ์ž…๋‹ˆ๋‹ค.IMHO, Dart ๋ฐ Flutter์˜ ํ˜„์žฌ ๊ตฌ๋ฌธ์„ ๊ฐœ์„ ํ•  ์—ฌ์ง€๊ฐ€ ์—ฌ์ „ํžˆ ์žˆ์Šต๋‹ˆ๋‹ค(์ €์—๊ฒŒ๋Š” ์ฃผ๋กœ ๊นŠ์€ ์ค‘์ฒฉ ๊ด„ํ˜ธ, child , children , ์„ธ๋ฏธ์ฝœ๋ก  ๋…ธ์ด์ฆˆ ๋“ฑ)
์—ฌ๊ธฐ์— ๋ช‡ ๊ฐ€์ง€ ์˜ˆ์‹œ ์ฝ”๋“œ[1]๋ฅผ ๋‹ค์‹œ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค.

// Comparing Flutter to what it might look like in Kotlin
class TutorialHome : StatelessWidget {
    override
    fun build(context: BuildContext) = scaffold {
        appBar = appBar {
            leading = iconButton {
                iconImage = Icon(Icons.menu)
                tooltip = "Navigation menu"
                onPressed = null
            } 
            titleText = "Example title"
            actions = [ // based on https://twitter.com/abreslav/status/867714627060322305
              iconButton { 
                iconImage = Icon(Icons.search)
                tooltip = "Search"
                onPressed = null  
              }
            ]
        }
        body = center {
            // Remember: This is a fully functional programming environment. You can execute any 
           //  code you can think of.
            child = Text("Hello ${MyApp.users.me.fullName.split(" ").first}!")
        }
        floatingActionButton = fab {
            tooltip = "Add"
            childImage = Icon(Icons.add)
            onPressed = null
        }
    }
}

new ๋ฐ ์„ธ๋ฏธ์ฝœ๋ก  ์˜ต์…˜์ด ์žˆ๋Š” Dart 2 ๋ฒ„์ „(@sethladd์˜ ์ฝ”๋“œ)[2],

class TutorialHome extends StatelessWidget {
  <strong i="13">@override</strong>
  Widget build(BuildContext context) => Scaffold(// implicit new!, also matching your Kotlin here
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.menu)
          tooltip: 'Navigation menu'
          onPressed: null
        )
        title: Text('Example title')
        actions: [ // Dart + strong mode will infer the contents of the list
          IconButton(
            icon: Icon(Icons.search)
            tooltip: 'Search'
            onPressed: null
          )
        ]
      )
      // body is the majority of the screen.
      body: Center(
        child: Text('Hello, world!')
      )
      floatingActionButton: FloatingActionButton(
        tooltip: 'Add' // used by assistive technologies
        child: Icon(Icons.add)
        onPressed: null
      )
   )
}

IMO, kotlin ๋ฒ„์ „์€ ๊นจ๋—ํ•˜๊ณ  ๋” ์ข‹์•„ ๋ณด์ž…๋‹ˆ๋‹ค.Dart 2 ๋ฒ„์ „์€ ๋งค์šฐ ๊ฐ€๊น๊ณ  ์—ฌ์ „ํžˆ ๊ฐœ์„ ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(Dart๊ฐ€ ํ™•์žฅ ๋ฐฉ๋ฒ•์„ ์ง€์›ํ•œ๋‹ค๋ฉด?). ๋”ฐ๋ผ์„œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด Dart ๊ตฌ๋ฌธ์„ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉํ–ฅ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

[1] https://gist.github.com/asarazan/b3c23bef49cf9a61f5a1a19de746f1b0
[2] https://gist.github.com/sethladd/7397a067deb43b6052032195fcb26d94

๋‹ค๋ฅธ ๊ฐ๋„์—์„œ๋Š” JSX์˜ ์ž‘์„ฑ ๊ธฐ๋Šฅ์ด ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ์š”์†Œ(์œ„์ ฏ)๋กœ ์ž‘์—…ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์‰ฝ๊ณ  ์•ก์„ธ์Šค ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํŽธ์ง‘๊ธฐ์—์„œ ํŠธ๋ฆฌ๋ฅผ ์œ„์•„๋ž˜๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์€ ํ‚ค๋ณด๋“œ ๋‹จ์ถ•ํ‚ค(Alt+UP / Alt+DOWN)์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ปจํ…Œ์ด๋„ˆ, ํ–‰, ์—ด ๋“ฑ์˜ ์•ˆํŒŽ์œผ๋กœ ๋ฌผ๊ฑด์„ ์ด๋™ํ•  ๋•Œ ํŠนํžˆ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ DSX๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์œ„์ ฏ ์ž์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด๊ฒƒ์ด ์ž‘๋™ํ•˜๋ ค๋ฉด ์†์„ฑ ์ด๋ฆ„ ์ง€์ •์ด ๋” ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. React์—์„œ ์ด๊ฒƒ์€ children ๋ผ๋Š” ์†์„ฑ์ด๋ฉฐ JSX์˜ ์ฃผ์š” ์ฃผ์ฒด์ž…๋‹ˆ๋‹ค. Flutter๋Š” ์ž์‹ ์ด๋ฆ„ ์ง€์ •์— ์œ ์—ฐ์„ฑ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค(child, children, body ๋“ฑ).

๋‹ค์Œ์€ ์ฐฌ๋ฐ˜ ์–‘๋ก ์— ๋Œ€ํ•œ ํ›Œ๋ฅญํ•œ ํ† ๋ก ์ž…๋‹ˆ๋‹ค. https://github.com/jsforum/jsforum/issues/1

๋‹คํŠธDSX

์ถœ์ฒ˜: https://github.com/flutter/flutter/blob/master/examples/platform_view/lib/main.dart

DSX ์ƒ˜ํ”Œ์ด ๋งค๋ ฅ์ ์œผ๋กœ ๋ณด์ธ๋‹ค๋Š” ๊ฒƒ์„ ์ธ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Dart Code์™€ ํ˜ผํ•ฉํ•˜๋Š” ์ฆ‰์‹œ ๋‘๋ ค์›Œ์ง‘๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋นŒ๋” ์œ„์ ฏ์„ ์‚ฌ์šฉํ•  ๋•Œ ์ •๋ง ๋ณด๊ธฐ ํ‰ํ•˜๊ฒŒ ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@birkir DSX๋Š” ์—ฌ๋Ÿฌ/๋น„ children ์ž์‹ ์Šฌ๋กฏ์— ๋Œ€ํ•œ ๋ Œ๋”๋ง ์†Œํ’ˆ ํŒจํ„ด๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค ์ฐธ์กฐ๋ฅผ ์†Œํ’ˆ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด(์•„๋งˆ๋„ ์ž๋™์œผ๋กœ) ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋„๊ตฌ ๊ตฌํ˜„์ด ์ง„ํ–‰๋˜๋Š” ํ•œ Javascript ๋„๊ตฌ๋Š” ์˜ค๋žซ๋™์•ˆ ๋น„ํ‘œ์ค€ ๊ตฌ๋ฌธ ๋ฐ ์–ธ์–ด ํ™•์žฅ(Flowtype/Typescript/Babel)์„ ์ง€์›ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— JSX์šฉ ๋„๊ตฌ๋Š” ๊ธฐ์กด ๋ณ€ํ™˜๊ธฐ๋ฅผ ๋งŽ์ด ํ™œ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. Afaik Dart๋Š” ๊ทธ๋Ÿฌํ•œ ์ˆ˜์ค€์˜ ๋‹จํŽธํ™”๋ฅผ ๊ฒฝํ—˜ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋„๊ตฌ๊ฐ€ ์•„์ง ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ง€๊ธˆ์ด ๊ตฌ์ถ•์„ ์‹œ์ž‘ํ•˜๊ธฐ์— ์ข‹์€ ์‹œ๊ธฐ์ž…๋‹ˆ๋‹ค ๐Ÿ˜„

IMHO, json๊ณผ ๊ฐ™์€ ๊ตฌ๋ฌธ์€ ~xml๊ณผ ๊ฐ™์€ ๊ตฌ๋ฌธ๋ณด๋‹ค ํ›จ์”ฌ ๋‚ซ์Šต๋‹ˆ๋‹ค!

container {
  padding: EdgeInsets.symmetric { vertical: 16.0  }
}

@jaychang0917
JSX๋Š” XML๊ณผ ๋น„๊ตํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” JSX์™€ XML์ด ์ดˆ์Œ์† ํ•ญ๊ณต๊ธฐ ๋Œ€ ํ”„๋กœํŽ ๋Ÿฌ ํ•ญ๊ณต๊ธฐ๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

JSX๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<supersonicAircarft 
          aircarft={{"F-22"}} 
          speed={{"mach2"}} 
          style={{"you can style it whatever you want as simple as css"}}
/>

๋˜๋Š”

<Image
          source={{uri: 'https://i.chzbgr.com/full/7345954048/h7E2C65F9/'}}
          style={{width: 320, height:180}}
        />

JSX๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์™€ ๊ฐ™์ด ๋ชจ๋“  ๊ฒƒ์„ ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜๋„ ์žˆ๊ณ  UI์˜ ๋งŽ์€ ๋ถ€๋ถ„์„ ํ•˜๋‚˜์˜ <> ํƒœ๊ทธ๋กœ ๊ทธ๋ฃนํ™”ํ•˜์—ฌ ์›ํ•˜๋Š” ์œ„์น˜์— ์ด ๋งŽ์€ ๋ถ€๋ถ„์„ ๋„ฃ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด React๊ฐ€ HTML๊ณผ XML์„ ๋Œ€์ฒดํ•˜๊ณ  iPhone ์•ฑ์ด๋‚˜ ์›น ์•ฑ์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด JSX๋ฅผ ์ฑ„ํƒํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ๋˜๋Š” ์‚ฌ๋žŒ๋“ค์€ JSX๊ฐ€ HTML์˜ ๋” ๋ฉ‹์ง„ ๋ฒ„์ „์ผ ๋ฟ์ด๋ผ๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค.

  • ๋‚˜๋Š” XML๊ณผ HTML์„ ๋ชจ๋‘ ์ข‹์•„ํ•˜์ง€ ์•Š์œผ๋ฉฐ JSX๋ฅผ ์‚ฌ๋ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ iPhone ๋Œ€ ๋ฐ์Šคํฌํƒ‘์˜ ์„ฑ๋Šฅ์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ iPhone ๋Œ€ ๋ฐ์Šคํฌํƒ‘์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด:

import React, { Component } from 'react';
import { Image, ScrollView, Text } from 'react-native';

class AwkwardScrollingImageWithText extends Component {
  render() {
    return (
      <ScrollView>
        <Image
          source={{uri: 'https://i.chzbgr.com/full/7345954048/h7E2C65F9/'}}
          style={{width: 320, height:180}}
        />
        <Text>
                        JSX is the philosophy, everything is a component. Simple is Complicate because you can 
                        form everything to your own perfect shape. 
        </Text>
      </ScrollView>
    );
  }
}

๋˜๋Š” ์“ฐ๊ธฐ

< AwkwardScrollingImage/>

๋ชจ๋“  ๊ณณ์—์„œ ํ•œ ๋ฒˆ๋งŒ ์“ฐ๊ธฐ ์œ„ํ•ด

import { AwkwardScrollingImage } from './your-native-code';
class SomethingFast extends Component {
  render() {
    return (
      <View>
          <AwkwardScrollingImage/>
        <Text>
            JSX is the philosophy, everything is a component. Simple is Complicate because you can form everything to your own perfect shape. Everything is a widget or component.
        </Text>
      </View>
    );
  }
}

~Flutter๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI๋ฅผ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค. ~

์ฐธ์กฐ:

์‹ค๋ฃฉ ๊ฑฐ๋ฆฌ๋‹ค:
https://flutter.io/tutorials/layout/
Android, Iphone, ์‹ฌ์ง€์–ด ๋ฐ์Šคํฌํƒ‘๊นŒ์ง€ ๋นŒ๋“œํ•˜๋Š” React Native:
https://facebook.github.io/react-native/

@birkir
์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค์˜ค ๋ผˆ๋Š” ์—†๊ณ  ๊ณ ๊ธฐ๋งŒ ์žˆ์–ด์š” :)
https://builderx.io/ ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์„ธ์š”(๋‘ ๋ฒˆ์งธ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ด๋ฏธ์ง€๋ฅผ ์‚ดํŽด๋ณด์„ธ์š” - Flex์™€ ๊ฐ™์€ ์–‘๋ฐฉํ–ฅ UI ๊ตฌ์ถ•์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ).

@escamoteur
์ธ๋ผ์ธ ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ˜„์žฌ ๋ฐฉ์‹์ฒ˜๋Ÿผ ์ง€์ €๋ถ„ํ•ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒ˜ํ”Œ์€ ์œ„์— ์ œ๊ณต๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
https://github.com/flutter/flutter/issues/15922#issuecomment -377780062

์–ด์จŒ๋“  ํ˜„์žฌ์˜ ๋ฐฉ์‹์€ ๋ช…ํ™•ํ•˜๊ณ  ์ผ๊ด€์„ฑ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. dart ํŒŒ์ผ ์— ์ผ๋ถ€ dart ์ฝ”๋“œ์™€ < ํƒœ๊ทธ๋ฅผ ํ˜ผํ•ฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์–ด์ƒ‰ํ•˜๊ณ  ๋ช…ํ™•ํ•˜์ง€ ์•Š๋‹ค๋Š” ๋Š๋‚Œ์ด ๋“ญ๋‹ˆ๋‹ค. ์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐœ๋ฐœ์ž ์ž…์žฅ์—์„œ๋Š” ๋ ˆ์ด์•„์›ƒ xml ํŒŒ์ผ์— ์ž๋ฐ”/์ฝ”ํ‹€๋ฆฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. :)

๊ทธ๋ƒฅ ๋‚ด 2 ์„ผํŠธ

@JonathanSum ์Œ...

๊ทธ๋ ‡๋‹ค๋ฉด ํ˜„์žฌ์˜ ํ”Œ๋Ÿฌํ„ฐ ๋ฐฉ์‹์œผ๋กœ๋Š” ํ•  ์ˆ˜ ์—†๋Š” JSX๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ค ์ด์ ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋‹น์‹ ์ด ๋งํ•œ ๊ฐ•๋ ฅํ•œ ์ฃผ์žฅ์„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

JSX๋Š” XML๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. JSX๋Š” XML๋ณด๋‹ค ๊ฐ„๋‹จํ•˜๊ณ  ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค.

Btw, ํŽ˜์ด์Šค ๋ถ ํŒ€์ด ๋‚˜์—๊ฒŒ ๊ฑฐ์ง“๋ง์„ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด JSX๋Š” xml๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค . :)

@jaychang0917
JSX๋Š” XML๋ณด๋‹ค ๊ฐ„๋‹จํ•˜๊ณ  ๊ฐ•๋ ฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— JSX๋Š” XML์ด ์•„๋‹™๋‹ˆ๋‹ค. (์ €๋Š” JSX๊ฐ€ XML๊ณผ ๊ฐ™์ง€ ์•Š๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค)

๊ฐ•๋ ฅํ•œ ์ฃผ์žฅ์ด ์—†๋‹ค๊ณ  ํ•˜์‹œ๋ฉด ์ œ๊ฐ€ ์งˆ๋ฌธ์„ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.
์ œ ์–˜๊ธฐ๋Š” ์—ฌ๊ธฐ์„œ ๋งˆ์น˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด JSX๋‚˜ DSX๋ฅผ ์›ํ•˜๋ฉด ๋ฏธ๋ž˜์— ๋น„์Šทํ•œ ๊ฒƒ์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • ์ฐธ์กฐ:
    https://facebook.github.io/jsx/
    This specification does not attempt to comply with any XML or HTML specification. JSX is designed as an ECMAScript feature and the similarity to XML is only for familiarity.

๋‚˜๋Š” XML์˜ ์‹ค์ œ ๋‹ซ๋Š” ํƒœ๊ทธ๋ฅผ ๊ทธ๋ฆฌ์›Œํ•ฉ๋‹ˆ๋‹ค. :)
์•„์ด๋””์–ด: ์ž๋™ ์ƒ์„ฑ๋œ ๋‹ซ๋Š” ํƒœ๊ทธ

Kotlin๋„ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. Kotlin-react ์™€ Anko ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋ฉ‹์ง„์ง€ ๋ณด์„ธ์š”.

Kotlin-react๋Š” ๊ทธ๋ ‡๊ฒŒ ๊ต‰์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. KSX๊ฐ€ ๋” ์ข‹์•˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

import React from 'react';

export function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
package hello

import react.*
import react.dom.*

fun RBuilder.hello(name: String) {
    h1 {
        +"Hello, $name"
    }
}
package hello

import react.*
import react.dom.*

fun RBuilder.hello(name: String) {
   <h1>Hello, {name}</h1>
}

ํƒœ๊ทธ๋Š” ๊ฑฐ๊ธฐ์— ์†ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. :)

JSX/DSX/KSX ์บ ํ”„์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํƒœ๊ทธ๊ฐ€ ์ฝ”๋“œ ๋‚ด๋ถ€์— ์†ํ•œ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. :)

@saied89
ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML์ฒ˜๋Ÿผ ๋‹ค๋ฅธ ์š”์†Œ ์•ˆ์— ์š”์†Œ๋ฅผ ์ค‘์ฒฉํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด "children", "child", ๋˜๋Š” [ ]๋ผ๋Š” ๋‹จ์–ด๋ฅผ ์ž…๋ ฅํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋˜ํ•œ JSX๋Š” ํƒœ๊ทธ ํ•˜๋‚˜๋งŒ ์ž…๋ ฅํ•˜์—ฌ ์ˆ˜๋ฐฑ ๊ฐœ์˜ UI ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ๋‹ค๋ฅธ ์ธก๋ฉด์€ dart format ๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋ณธ ํ˜•์‹์ž…๋‹ˆ๋‹ค. IMHO ํŠนํžˆ ์ฃผ๋„์ ์ธ ์•„์ด์™€ ํ•จ๊ป˜ ์ฝ๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค: /children.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๊ฐ•์กฐํ•˜๋Š” ์„œ์‹์„ ์ •๋ง ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

 Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text("WeatherDemo")),
      resizeToAvoidBottomPadding: false,
      body: 
        new Column(children: <Widget>
        [
          new Padding(
            padding: const EdgeInsets.all(16.0),
            child: 
            new TextField(
                    key: AppKeys.textField,
                    autocorrect: false,
                    controller: _controller,
                    decoration: new InputDecoration(hintText: "Filter cities",),
                    style:  TextStyle(fontSize: 20.0,),
                    onChanged: ModelProvider.of(context).textChangedCommand,
                    ),
          ),
          new Expanded(
                child: 
                new RxLoader<List<WeatherEntry>>(
                        key: AppKeys.loadingSpinner,
                        radius: 25.0,
                        commandResults: ModelProvider.of(context).updateWeatherCommand,
                        dataBuilder: (context, data) => new WeatherListView(data ,key: AppKeys.weatherList),
                        ),
          ),
          new Padding(
            padding: const EdgeInsets.all(8.0),
            child: 
            new Row(children: <Widget>
            [
                new Expanded(
                    child: 
                    // This might be solved with a Streambuilder to but it should show `WidgetSelector`
                    new WidgetSelector(
                            buildEvents: ModelProvider.of(context).updateWeatherCommand.canExecute,   //We access our ViewModel through the inherited Widget
                            onTrue:  new RaisedButton(    
                                            key: AppKeys.updateButtonEnabled,                           
                                            child: new Text("Update"), 
                                            onPressed: ModelProvider.of(context).updateWeatherCommand,
                                            ),
                            onFalse:  new RaisedButton(                               
                                            key: AppKeys.updateButtonDisabled,                           
                                            child: new Text("Please Wait"), 
                                            onPressed: null,
                                            ),

                        ),
                ),
                new StateFullSwitch(
                        state: true,
                        onChanged: ModelProvider.of(context).switchChangedCommand,
                   )
              ],
            ),
          ),
        ],
      ),
    );
  }

์ด๊ฒƒ์€ ์ด์ƒ์ ์ธ ์†”๋ฃจ์…˜์€ ์•„๋‹ˆ์ง€๋งŒ ๋ฐฉํ–ฅ์„ ์ œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
@sethladd ๊ทธ ๋ฐฉํ–ฅ์œผ๋กœ ๋ญ”๊ฐ€๋ฅผ ํ•  ๊ธฐํšŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์šฐ์„ , ๋‚˜๋Š” ์ด๊ฒƒ์ด ๊ทธ๊ฒƒ์˜ ์ž๋งค ๋ฌธ์ œ์ธ ๋ฏธ์†Œ: ๋งŒํผ ๋œจ๊ฑฐ์›Œ์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

2๊ฐ€์ง€ ๊ตฌ๋ฌธ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜๋ผ๋Š” ์š”์ฒญ์„ ๋ฐ›์€ ๊ฒฝ์šฐ Dart ์ชฝ์„ ํƒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ์‚ฌ์‹ค์— ๊ทผ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ€๋Šฅํ•œ ํ•œ ์ ์€ ์ˆ˜์˜ ์ปจํ…์ŠคํŠธ ๊ฐ„์— ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ์ข‹๋“  ์‹ซ๋“ , ๊ตฌ๋ฌธ ์‚ฌ์ด๋ฅผ ์ด๋™ํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋„๊ตฌ ์ง€์›์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ์•„๋ž˜ ์š”์ ์œผ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค.
  • ์ €๋Š” ๊ฐœ๋ฐœ ํŒ€์ด ํŠน์ • ๊ธฐ๋Šฅ์„ ์ฝ”๋”ฉํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๊ฑฐ๋‚˜ ์‚ฌ๋žŒ๋“ค์ด Flutter๋กœ ๋›ฐ์–ด๋“œ๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ๋‹ค๋ฅธ ๋ฌธ์ œ์— ์‹œ๊ฐ„์„ ํ• ์• ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. JSX์™€ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ด ํšŒ์‚ฌ/๊ฐœ๋ฐœ์ž/๋ฌด์—‡์ด๋“  Flutter๋ฅผ ๋ฌด์‹œํ•˜๋Š” ์ด์œ ๊ฐ€ ๋˜์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
  • ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  Dart ์—…๋ฐ์ดํŠธ๋กœ๋ถ€ํ„ฐ ํ˜œํƒ์„ ๋ฐ›์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Flutter๊ฐ€ ์ฃผ์š” ๊ณ ๊ฐ ์ค‘ ํ•˜๋‚˜์ด๊ณ  UI ํ”„๋ ˆ์ž„์›Œํฌ์ด๊ธฐ ๋•Œ๋ฌธ์— Dart์— ํŠนํžˆ ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด new/const ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.
  • ๋‚˜๋Š” ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ๋งค์šฐ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. JSX์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์ด ์œ ํ˜• ์•ˆ์ „ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ง์€ ์•„๋‹ˆ์ง€๋งŒ ์ด๋ฅผ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๋…ธ๋ ฅ์ด ์ˆ˜์ต์„ ๋‚ผ ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ ์™ธ์—๋Š” ์‚ฌ์‹ค Kotlin๊ณผ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ํ•ด๋‹น ๊ตฌ๋ฌธ์ด ์ผ๋ถ€ Kotlin ๊ธฐ๋Šฅ์„ Dart: innocent: ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ.

@์— ๋ง๋ผ๋ฉœ๋ผ ,

์ด๊ฒƒ์ด ๋ฐ”๋กœ ๋‹น์‹ ์ด ๋ถ€๋ฅด๋Š” ๋Œ€๋กœ ์ปจํ…์ŠคํŠธ ์ „ํ™˜์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋…ธ๋ จํ•œ React ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ฌธ์˜ํ•˜์‹ญ์‹œ์˜ค. ๋˜ํ•œ ์ด ๊ตฌ๋ฌธ ๋ถ„๋ฆฌ๋Š” ์‹ค์ œ๋กœ ํ›Œ๋ฅญํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋ฌด์—‡์ด ์„ ์–ธ์ ์ด๊ณ  ๋ฌด์—‡์ด ํ•„์ˆ˜์ธ์ง€ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

JSX์™€ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ด ํšŒ์‚ฌ/๊ฐœ๋ฐœ์ž/๋ฌด์—‡์ด๋“  Flutter๋ฅผ ๋ฌด์‹œํ•˜๋Š” ์ด์œ ๊ฐ€ ๋˜์–ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋ถˆํ–‰ํžˆ๋„ ๊ทธ๊ฒƒ์€ ๋งŽ์€ React ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ํ•ด๋‹น๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋ชจ๋“  Dart ์—…๋ฐ์ดํŠธ๋กœ๋ถ€ํ„ฐ ํ˜œํƒ์„ ๋ฐ›์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

DSX๋Š” Dart์˜ ์ƒ์œ„ ์ง‘ํ•ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— Dart ์—…๋ฐ์ดํŠธ์˜ ์ด์ ๋„ ์–ป์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ๋งค์šฐ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. JSX์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์ด ์œ ํ˜• ์•ˆ์ „ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ง์€ ์•„๋‹ˆ์ง€๋งŒ ์ด๋ฅผ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๋…ธ๋ ฅ์ด ์ˆ˜์ต์„ ๋‚ผ ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

DSX๋Š” Dart ์œ„์— ์žˆ๋Š” ์•„์ฃผ ์ž‘์€ syntatic sugar layer์ด๊ธฐ ๋•Œ๋ฌธ์— DSX์—์„œ ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ๋‹ฌ์„ฑํ•˜๋ ค๋Š” ๋…ธ๋ ฅ์€ 0์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Dart ์ œ์–ด๋ฌธ ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Dart ์œ ํ˜• ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
https://github.com/flutter/flutter/issues/15922#issuecomment -377780062

์ž…๋ ฅํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @cbazza !

์ด๊ฒƒ์ด ๋ฐ”๋กœ ๋‹น์‹ ์ด ๋ถ€๋ฅด๋Š” ๋Œ€๋กœ ์ปจํ…์ŠคํŠธ ์ „ํ™˜์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋…ธ๋ จํ•œ React ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ฌธ์˜ํ•˜์‹ญ์‹œ์˜ค.

์ €๋Š” ๋…ธ๋ จํ•œ React ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ ์ €์—๊ฒŒ๋Š” ์ปจํ…์ŠคํŠธ ์Šค์œ„์น˜์ž…๋‹ˆ๋‹ค. Android์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Java/Kotlin์—์„œ XML๋กœ ์ด๋™ํ•ด์•ผ ํ•˜์ง€๋งŒ ์ ํ”„๊ฐ€ ๋” ํฝ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ์–ธ์–ด, ๋™์ผํ•œ ๋„๊ตฌ, ์ ์€ ์˜ค๋ฒ„ํ—ค๋“œ.

๋˜ํ•œ ์ด ๊ตฌ๋ฌธ ๋ถ„๋ฆฌ๋Š” ์‹ค์ œ๋กœ ํ›Œ๋ฅญํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋ฌด์—‡์ด ์„ ์–ธ์ ์ด๊ณ  ๋ฌด์—‡์ด ํ•„์ˆ˜์ธ์ง€ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ง€๊ธˆ์˜ ๋ฐฉ์‹์€ ๋‚ด ์˜๊ฒฌ์œผ๋กœ๋Š” ๋งค์šฐ ์„ ์–ธ์ ์ž…๋‹ˆ๋‹ค.

DSX๋Š” Dart์˜ ์ƒ์œ„ ์ง‘ํ•ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— Dart ์—…๋ฐ์ดํŠธ์˜ ์ด์ ๋„ ์–ป์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.
DSX๋Š” Dart ์œ„์— ์žˆ๋Š” ์•„์ฃผ ์ž‘์€ syntatic sugar layer์ด๊ธฐ ๋•Œ๋ฌธ์— DSX์—์„œ ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ๋‹ฌ์„ฑํ•˜๋ ค๋Š” ๋…ธ๋ ฅ์€ 0์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Dart ์ œ์–ด๋ฌธ ๋“ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Dart ์œ ํ˜• ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ณต์ •ํ•œ ํฌ์ธํŠธ. ๊ทธ๋Ÿฌ๋‚˜ DSX๋Š” ์—ฌ์ „ํžˆ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ณ  ๊ฐœ์„ ํ•ด์•ผ ํ•  ์‚ฌํ•ญ์ด๋ฉฐ, ์ด๋Š” ์ƒํƒœ๊ณ„์˜ ๋‹ค๋ฅธ ๋” ์ค‘์š”ํ•˜๊ฑฐ๋‚˜ ๋ถ€์กฑํ•œ ์ธก๋ฉด์— ์ง‘์ค‘๋˜๊ธฐ๋ฅผ ๋ฐ”๋ผ๋Š” ๋…ธ๋ ฅ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

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

๋‚ด๊ฐ€ ์•„๋Š” ํ•œ, DSX/JSX๊ฐ€ ์ง€์›๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— Flutter์—์„œ ๊ฐœ๋ฐœํ•˜์ง€ ์•Š๊ธฐ๋กœ ํ•œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ ์‚ฌ๋žŒ์€ Flutter์— ์ „ํ˜€ ์ฐธ์—ฌํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋™์˜ํ•˜์ง€ ์•Š๋Š” ํ† ๋ก ์— ๋Œ€ํ•œ ๋˜ ๋‹ค๋ฅธ ์ธก๋ฉด์€ React์™€์˜ ์ง€์†์ ์ธ ๋น„๊ต์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ ๊ด€๋ จ์„ฑ์„ ์ดํ•ดํ•˜์ง€๋งŒ Flutter๊ฐ€ JS ๋ธŒ๋ฆฌ์ง€ ์—†์ด React์˜ ์‚ฌ๋ณธ์ด ๋˜๊ณ  ๊ตฌ์„ฑ ์š”์†Œ ์ด๋ฆ„์„ ์œ„์ ฏ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜‘๊ฐ™๋‹ค๋ฉด ์™œ ๋ฐ”๊พธ๋‚˜์š”?

React๋Š” Flutter๊ฐ€ ์ฑ„์šธ ์ˆ˜ ์žˆ๋Š” ๊ณต๋ฐฑ์ด ์žˆ๊ณ  React์˜ ๋‹จ์ ์„ Dart ์„ฑ๋Šฅ ๋ฐ GPU ๊ฐ€์† ๊ทธ๋ž˜ํ”ฝ์œผ๋กœ ์ˆ˜์ •ํ•˜๋ฉด์„œ ์นœ์ˆ™ํ•จ๊ณผ ํ•จ๊ป˜ React์˜ ๊ฐ€์žฅ ์ข‹์€ ๋ถ€๋ถ„์„ ์œ ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— React๋ณด๋‹ค ๋” ๋‚˜์€ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์•„๋Š” ํ•œ, DSX/JSX๊ฐ€ ์ง€์›๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— Flutter์—์„œ ๊ฐœ๋ฐœํ•˜์ง€ ์•Š๊ธฐ๋กœ ํ•œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ ์‚ฌ๋žŒ์€ Flutter์— ์ „ํ˜€ ์ฐธ์—ฌํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ตœ์ข… ๊ฒฐ๊ณผ๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋ฐ”์ผ ๊ฐœ๋ฐœ์ž๊ฐ€ Flutter์— ํ•ฉ๋ฅ˜ํ•˜์ง€ ์•Š์œผ๋ฉด ์‹œ์žฅ์—์„œ ์‹คํŒจํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Flutter๋Š” ์ƒ์กด์„ ์œ„ํ•ด React Native ๊ฐœ๋ฐœ์ž๋ฅผ ๋Œ์–ด๋“ค์ผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง„ํ™”๋ก ์ด๋ผ๊ณ  ํ•˜๋ฉด '์ ์ž์ƒ์กด'์ด ์•„๋‹ˆ๋ผ '์ ์ž์ƒ์กด'์ด๋‹ค. ์ ์‘ํ•˜์ง€ ์•Š์œผ๋ฉด ์ฃฝ๋Š”๋‹ค.

@cbazza

์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ตœ์ข… ๊ฒฐ๊ณผ๋Š” ํฌ๋กœ์Šค ํ”Œ๋žซํผ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋ฐ”์ผ ๊ฐœ๋ฐœ์ž๊ฐ€ Flutter์— ํ•ฉ๋ฅ˜ํ•˜์ง€ ์•Š์œผ๋ฉด ์‹œ์žฅ์—์„œ ์‹คํŒจํ•˜๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ญ๋ผ๊ณ  ์š”? ์™œ ํ•„์š”ํ• ๊นŒ์š”? Flutter๋Š” ๋ฒ ํƒ€์— ์žˆ๋Š” ๋™์•ˆ ์ž์ฒด ํ‹ˆ์ƒˆ ์‹œ์žฅ์„ ํ˜•์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ(๋งค์šฐ ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—), ํ‘œ๋ฉด์ ์œผ๋กœ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ ๋‚˜๋ฐฉ์„ ์œ ์ธํ•  ํ•„์š” ์—†์ด ์œ ๊ธฐ์ ์œผ๋กœ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ "์‹คํŒจ"๋Š” ๋ฌด์—‡์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ? Flutter๊ฐ€ ์„ฑ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ธ๊ธฐ๊ฐ€ ์žˆ์„ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

@naiveaiguy
์ด๋ด, ๋‚˜๋Š” ๋‹น์‹ ์ด cbazza์˜ ๋‹ต์žฅ์— ๋ฐ˜๋Œ€ ํˆฌํ‘œ๋ฅผ ํ•œ ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋‚ด ๋‹ต๋ณ€์— ๋ฐ˜๋Œ€ ์˜๊ฒฌ์„ ์ œ์‹œํ•˜๊ธฐ ์ „์— 15์ดˆ ๋™์•ˆ ์ด ๋‚ด์šฉ์„ ์‚ดํŽด๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

DSX์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ธฐ ์ „์—.
์•„๋ž˜๋ฅผ ์‚ดํŽด๋ณด๋ฉด JSX์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

ํƒ์ƒ‰ ๋ชจ์Œ๊ณผ ๋ณธ๋ฌธ์„ ๋งŒ๋“  ํ›„์—๋Š” ํƒ์ƒ‰ ๋ฐ”์ฝ”๋“œ์—์„œ ํƒ์ƒ‰ ๋ฐ”์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import XXXXX, { Component } from 'XXXXX';
import { Text, View } from 'XXXXX-native';
import navbar from "your code1"
import body from "your code2"

class SomethingFast extends Component {
  render() {
    return (
      <View>
        <navbar
            style={{width: 360, height:90}}
         />
        <Image
          source={{uri: 'https://google.com/dsx.jpg/'}}
          style={{width: 320, height:180}}
        />
        <body/>
        <Text>
          Look at <strong i="11">@escamoteur</strong> s code from above.
           Can you export part of UI code to another place,
           separate it into different modules, and read everything in few seconds or less?
        </Text>
      </View>
    );
  }
}
       I think cbazza is right.
       If flutter uses DSX or whatever that is JSX,
       it is a perfect UI framework.

       So, could we have something
       similar or better in the future?
       Or do you really think that the
       current is fine?

๋ˆ„๊ตฐ๊ฐ€๋Š” JSX๊ฐ€ Facebook์—์„œ ์ œ๊ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ซ์–ดํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์ž‘์€ ์ผ๋ณธ ๊ฒŒ์ž„ ํšŒ์‚ฌ์—์„œ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

React Native์™€ Flutter๋กœ ์•ฑ์„ ๋งŒ๋“  ํ›„ ํ˜„์žฌ ์ƒํƒœ์—์„œ JSX๋Š” ์ˆœ์ˆ˜ ์ค‘์ฒฉ Dart ํด๋ž˜์Šค๋ณด๋‹ค ์ฝ๊ณ  ์กฐ์ •ํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์•ž์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด Facebook์€ JavaScript๊ฐ€ ์ž‘์„ฑ๋˜๋Š” ๋ฐฉ์‹(์˜ˆ: ๋ช…๋ช…๋œ ์ƒ์„ฑ์ž ๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์Œ)์œผ๋กœ ์ธํ•ด JSX๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” Dart์˜ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๋˜ํ•œ ์ถ”๊ฐ€๋œ Dart ์œ ํ˜• ์•ˆ์ „์„ฑ์€ ์ •๋ง ์ข‹์Šต๋‹ˆ๋‹ค!
๋”ฐ๋ผ์„œ Flutter๊ฐ€ ๊ฒฐ๊ตญ ์ˆœ์ˆ˜ํ•œ Dart ๊ตฌ๋ฌธ์„ ๊ณ ์ˆ˜ํ•˜๋Š” ๊ฒฝ์šฐ ๊ตฌ๋ฌธ ํ˜•๊ด‘ํŽœ๊ณผ ์ž๋™ ํฌ๋งทํ„ฐ๋ฅผ ํ†ตํ•ด ๊ฐœ์„  ์‚ฌํ•ญ์„ ๋ณผ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋‹ซ๋Š” ํƒœ๊ทธ ์ฃผ์„์€ ์ด๋ฏธ ํฌ๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์ง€๋งŒ JSX ์ƒ์‚ฐ์„ฑ์— ๋„๋‹ฌํ•˜๊ธฐ์—๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@JonathanSum ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ์„ค๋ช…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ JSX๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Dart์˜ ๊ตฌ๋ฌธ์„ ์ˆ˜์ •ํ•˜์—ฌ ๋” ๋‚˜์€ ๊ฒƒ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ DSX๋Š” ์ „ํ˜€ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์•„๋‹™๋‹ˆ๋‹ค.

@hartmannj ์šฐ๋ฆฌ๋Š” ์ƒ์‚ฐ์„ฑ์— ๋„์›€์ด ๋  Dart ๊ตฌ๋ฌธ, ํ˜•๊ด‘ํŽœ ๋ฐ ํฌ๋งทํ„ฐ์˜ ๊ฐœ์„  ์‚ฌํ•ญ์„ ํ•ญ์ƒ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜ ๋˜๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์ƒ๊ฐํ–ˆ์„ ์ˆ˜ ์žˆ๋Š” ๊ฐœ์„  ์‚ฌํ•ญ์— ๋Œ€ํ•œ ๊ตฌ์ฒด์ ์ธ ์•„์ด๋””์–ด๋‚˜ ์ œ์•ˆ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

new/const ๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋Š” IMHO๋Š” ์ด๋ฏธ ๋งŽ์€ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹คํŠธ ํ˜•์‹์ด ๋‚˜๋ฌด๋ฅผ ํ˜•์‹ํ™”ํ•˜๋Š” ๋ฐฉ์‹์— ์ •๋ง ์–ด๋ ค์›€์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๋น„๊ตํ•˜์—ฌ ํŠธ๋ฆฌ ๊ตฌ์กฐ IMHO๋ฅผ ์ถฉ๋ถ„ํžˆ ๊ฐ•์กฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    return Scaffold(
      appBar: AppBar(title: Text("WeatherDemo")),
      resizeToAvoidBottomPadding: false,
      body: 
        Column(children: <Widget>
        [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: 
            TextField(
                    key: AppKeys.textField,
                    autocorrect: false,
                    controller: _controller,
                    decoration: InputDecoration(hintText: "Filter cities",),
                    style:  TextStyle(fontSize: 20.0,),
                    onChanged: ModelProvider.of(context).textChangedCommand,
                    ),
          ),

https://reactjs.org/docs/introducing-jsx.html

React๋Š” JSX๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ JavaScript ์ฝ”๋“œ ๋‚ด์—์„œ UI๋กœ ์ž‘์—…ํ•  ๋•Œ ์‹œ๊ฐ์  ๋ณด์กฐ ์žฅ์น˜๋กœ ๋„์›€์ด ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ React๊ฐ€ ๋” ์œ ์šฉํ•œ ์˜ค๋ฅ˜ ๋ฐ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด JSX์™€ ์œ ์‚ฌํ•œ UI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ, ์ด๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋ฉฐ ๋ฌด์‹œํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

@woodstream JSX ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์ด๋ฏธ React ํŒฌ๋ณด์ด ํŒฌ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ด๋ฏธ React Native๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Flutter๋Š” ๋งค์šฐ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ๊ฐœ๋ฐœ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘ : ๋‚˜๋Š” fanboy์˜ ์‚ฌ์šฉ์ด ์—ฌ๊ธฐ์„œ ์ž˜๋ชป๋˜์—ˆ์Œ์„ ์ธ์ •ํ•ฉ๋‹ˆ๋‹ค.

@naiveaiguy , @Hixie

JSX๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ดํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ ์ด๋ฏธ React ํŒฌ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ด๋ฏธ React Native๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Flutter๋Š” ๋งค์šฐ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ๊ฐœ๋ฐœ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ํ‹€๋ ธ๊ณ  ๋ถ„์—ด์ ์ธ ๋Œ“๊ธ€('React fanboys' & '๋‹ค๋ฅธ ์œ ํ˜•์˜ ๊ฐœ๋ฐœ์ž')์„ ๋ถ€๋ฅด๋Š” ์ด๋ฆ„์€ ํ™˜์˜๋ฐ›์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. JSX/DSX๋Š” ๊ธฐ์ˆ ์  ์žฅ์ ์ด ์žˆ๊ณ  ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ ๊ทธ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ์ด ์Šค๋ ˆ๋“œ๋Š” ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์œผ๋ฉด ๊ตฌ๋…์„ ์ทจ์†Œํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‚ด ์˜๊ฒฌ ํ•˜๋‚˜ํ•˜๋‚˜์— ๋Œ€ํ•ด ๋ฐ˜๋Œ€ ํˆฌํ‘œ๋ฅผ ์ค‘์ง€ํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๊ฒƒ์€ ๋‹น์‹ ์—๊ฒŒ ์ข‹์€ ์ง•์กฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž๊ฐ€ ์ž์‹ ์ด ์ข‹์•„ํ•˜๋Š” ๊ฒƒ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ์•ˆํ•˜๊ณ  ๋ˆ„๊ตฐ๊ฐ€ ๋‹ค๋ฅธ ์˜๊ฒฌ ์•ž์—์„œ ์—„์ง€์†๊ฐ€๋ฝ์„ ํฌ๊ธฐํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๊นŒ? ๊ธฐ์ˆ ์€ ํ์‡„๋œ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ํ”Œ๋ ˆ์ดํ•˜๊ธฐ๋ณด๋‹ค ๊ฐœ๋ฐฉ์ ์ด๊ณ  ํฌ๊ด„์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@anders-sandholm ์œ„์ ฏ ํŠธ๋ฆฌ์˜ ๊ฐ€์‹œ์„ฑ์„ ํ–ฅ์ƒ์‹œ์ผœ์•ผ ํ•  ํ•„์š”์„ฑ์— ๋Œ€ํ•ด @escamoteur ์˜ ์˜๊ฒฌ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ทธ์˜ ์˜ˆ๋ฅผ ๋“ค์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

return
      Scaffold(
          appBar: AppBar(title: Text("WeatherDemo")),
          resizeToAvoidBottomPadding: false,
          body:
        Column(children: <Widget> [
          Padding(
              padding: const EdgeInsets.all(16.0),
              child:
            TextField(
                key: AppKeys.textField,
                autocorrect: false,
                controller: _controller,
                decoration: InputDecoration(hintText: "Filter cities",),
                style:  TextStyle(fontSize: 20.0,),
                onChanged: ModelProvider.of(context).textChangedCommand,
            ),
          ),
        ])
      );

๋˜ํ•œ ์œ„์ ฏ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋‹ค๋ฅธ ์ƒ‰์ƒ, ๊ธ€๊ผด ์Šคํƒ€์ผ ๋˜๋Š” ๋‘๊ป˜๋กœ ๊ฐ•์กฐ ํ‘œ์‹œํ•˜์—ฌ ์ฆ‰์‹œ ๋” ์ž˜ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@cbazza

์ด๋ฆ„ ๋ถ€๋ฅด๊ธฐ? ๋‚˜๋Š” ์ด ์‚ฌ๋žŒ๋“ค์ด ๋ถ€์ •์ ์ด๋ผ๋Š” ๊ฒƒ์„ ์•”์‹œํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋‹จ์ง€ ๊ทธ๋“ค์ด ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ์•”์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ข‹์•„ํ•˜์ง€๋งŒ ์•…์˜๋กœ ๋…ผ์Ÿํ•œ๋‹ค๊ณ  ๋‚˜๋ฅผ ๋น„๋‚œํ•˜๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„ ์•„์ด๋Ÿฌ๋‹ˆํ•ฉ๋‹ˆ๋‹ค.

"fanboy"๋ผ๋Š” ๋‹จ์–ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฒฝ๋ฉธ์ ์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜๋ฉฐ ์ด๋Ÿฌํ•œ ๋งฅ๋ฝ์—์„œ๋„ ๊ทธ๋ ‡๊ฒŒ ๋ฐ›์•„๋“ค์—ฌ์กŒ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ํ† ๋ก ์—์„œ ๊ทธ๋Ÿฐ ๋‹จ์–ด๋ฅผ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

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

@hartmannj

์•ฝ๊ฐ„์˜ ์„ค๋ช…๋งŒ...

๊ทธ๋Ÿฌ๋‚˜ ์•ž์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด Facebook์€ JavaScript๊ฐ€ ์ž‘์„ฑ๋˜๋Š” ๋ฐฉ์‹(์˜ˆ: ๋ช…๋ช…๋œ ์ƒ์„ฑ์ž ๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์Œ)์œผ๋กœ ์ธํ•ด JSX๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” Dart์˜ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ES2015/ES6๋ถ€ํ„ฐ JS๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์— ์ด๋ฆ„์„ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. '๊ตฌ์กฐํ™” ํ•ด์ œ'๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. :)
๋‹ค์Œ์€ ์˜ˆ์ž…๋‹ˆ๋‹ค.

// function declaration
function findUsersByRole ({
  role,
  withContactInfo, 
  includeInactive
}) {
  if (role === 'admin' && withContactInfo) {
  ...
  }
...
}


// usage
findUsersByRole({
  role: 'admin', 
  withContactInfo: true, 
  includeInactive: true
})

https://medium.freecodecamp.org/elegant-patterns-in-modern-javascript-roro-be01e7669cbd

๋˜ํ•œ ์ถ”๊ฐ€๋œ Dart ์œ ํ˜• ์•ˆ์ „์„ฑ์€ ์ •๋ง ์ข‹์Šต๋‹ˆ๋‹ค!

DSX์—์„œ๋„ ๋™์ผํ•œ ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ •๋ง ์ข‹์€ ์ผ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ด์ „์— ๋ณด๊ณ ๋œ https://github.com/flutter/flutter/issues/11609 ์˜ ๋ณต์ œ๋ณธ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด ํ•ญ๋ชฉ์„ ์œ„ํ•ด ๋‹ซ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ์ธํ„ฐ๋„ท ์‹œ๋Œ€์— ์„ ์–ธ์  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹์— ๋งค์šฐ ๋‘ ๋ฒˆ์งธ ์ฒœ์„ฑ์ธ ์ด๊ฒƒ์— ๋ฐ˜๋Œ€ํ•˜๋Š” ํˆฌํ‘œ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ •๋ง๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

<like><this /></like>

ํ”Œ๋Ÿฌํ„ฐ๊ฐ€ ๋‚  ์ˆ˜ ์žˆ๋„๋ก ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์ฒ˜ํ•ด์ฃผ์„ธ์š”!

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

๋„ค์ดํ‹ฐ๋ธŒ ๋˜๋Š” html์— ๋ฐ˜์‘ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ xml ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์•„๋งˆ๋„... ๋‹คํŠธ์— ํฌํ•จ๋œ xml! ;ํ”ผ

2018๋…„ 8์›” 28์ผ ํ™”์š”์ผ 21:29์— Touseef [email protected] ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

๋„ค์ดํ‹ฐ๋ธŒ ๋˜๋Š” html์— ๋ฐ˜์‘ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ xml ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/flutter/flutter/issues/15922#issuecomment-416550338 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AC8aNdVb_NV8c8JH4t36OS1OOvX6kY58ks5uVSmjgaJpZM4S6HPa
.

--
ํ† ๋‹ˆ ํด๋ฆฌ๋„ฌ๋ฆฌ

๋‚˜์—๊ฒŒ JSX์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์€ ๋ฏธ๋ž˜์ด๋ฉฐ React, Vue ๋ฐ Flutter์™€ ๊ฐ™์€ ์„ ์–ธ์  ํ”„๋ ˆ์ž„์›Œํฌ์˜ ํ‘œ์ค€ ๊ตฌ์กฐ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

UI์™€ ๋กœ์ง์„ ์œ„ํ•œ 2๊ฐœ์˜ ๊ฐœ๋ณ„ ํŒŒ์ผ๋งŒ ์žˆ์œผ๋ฉด dart์— xml์„ ํฌํ•จํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด mvvm, mvc ๋˜๋Š” ๊ธฐํƒ€ ์›ํ•˜๋Š” ํŒจํ„ด์„ ์‰ฝ๊ฒŒ ๋”ฐ๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๊ทธ๊ฒƒ์„ ๋งํ–ˆ์ง€๋งŒ :

JSX๋ฅผ ์ •๋ง๋กœ ์›ํ•˜์‹ ๋‹ค๋ฉด ์ข‹์€ ์‹œ์ž‘ ๋„๊ตฌ๋Š” ์ฝ”๋“œ ์ƒ์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. .html ๋˜๋Š” .xml ํŒŒ์ผ๋กœ ์ด๋™ํ•˜์—ฌ ์ด๋“ค๋กœ๋ถ€ํ„ฐ ์œ„์ ฏ์„ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค.

๋ถ„๋ช…ํžˆ ์ด๊ฒƒ์€ ๋ณธ๊ฒฉ์ ์ธ JSX๋Š” ์•„๋‹ˆ์ง€๋งŒ ์‹œ์ž‘์ž…๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์ด์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ๋ฐ˜์‘ํ• ์ง€ ์ถฉ๋ถ„ํžˆ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•ด๋‹น ๊ตฌ๋ฌธ์ด ๊ด€์‹ฌ์„ ๋Œ๋ฉด Flutter ํŒ€์ด ํ•ด๋‹น ์ฃผ์ œ๋ฅผ ์žฌ๊ณ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

Flutter๊ฐ€ ์†Œ๊ฐœํ•˜๊ณ  xml / jsx / UI๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์›ํ•˜๋Š” ๋Œ€๋กœ ํ˜ธ์ถœํ•˜๋ฉด ์‹ฌ์žฅ ๋ฐ•๋™์— ํ”„๋กœ๋•์…˜ ์ˆ˜์ค€ ์•ฑ์— ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค!

@leossmith ๋Š” ํ”„๋กœ๋•์…˜ ์ˆ˜์ค€ ์•ฑ์˜ ์œ ์ผํ•œ ์žฅ์• ๋ฌผ์ด๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ JSX๋‚˜ ์™ธ๋ถ€ ๋งˆํฌ์—… ์–ธ์–ด๋ฅผ ์ถ”๊ฐ€ _ํ•˜์ง€_ ์•Š๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ชจ๋“  ๊ฒƒ์„ ๋‹จ์ผ ์œ ํ˜• ๊ฒ€์‚ฌ ์–ธ์–ด๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๊นŠ์ด ์ค‘์ฒฉ๋œ ์„ ์–ธ์  UI ํŠธ๋ฆฌ๋ฅผ ์ฝ”๋”ฉํ•  ๋ชฉ์ ์œผ๋กœ Dart ์–ธ์–ด๋ฅผ ๊ณ„์† ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์€ ์ ‘๊ทผ ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ด๋ฏธ ์ด ์˜์—ญ์— ๋ช‡ ๊ฐ€์ง€ ๋ฉ‹์ง„ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • new ๋ฐ const ํ‚ค์›Œ๋“œ๋ฅผ ์„ ํƒ ์‚ฌํ•ญ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.
  • IDE์˜ ๊ฐ€์ƒ ๋‹ซ๊ธฐ ํƒœ๊ทธ
  • dartfmt๋„ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค

๋ชจ๋“  ๊ฒƒ์„ ๋‹จ์ผ ์œ ํ˜• ๊ฒ€์‚ฌ ์–ธ์–ด๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ DSX/JSX๊ฐ€ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค. ์–ธ์–ด๋Š” DSX์šฉ Dart, JSX์šฉ Javascript์ž…๋‹ˆ๋‹ค!!!

๊นŠ์ด ์ค‘์ฒฉ๋œ ์„ ์–ธ์  UI ํŠธ๋ฆฌ๋ฅผ ์ฝ”๋”ฉํ•  ๋ชฉ์ ์œผ๋กœ Dart ์–ธ์–ด๋ฅผ ๊ณ„์† ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์€ ์ ‘๊ทผ ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

DSX๋Š” ๊นŠ์ด ์ค‘์ฒฉ๋œ ์„ ์–ธ์  ํŠธ๋ฆฌ๋ฅผ ๋” ์ž˜ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด Dart ์–ธ์–ด๋ฅผ ๊ฐœ์„ ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. JSX๊ฐ€ Javascript์šฉ์ธ ๊ฒƒ์ฒ˜๋Ÿผ.

https://facebook.github.io/jsx/

์ด ์‚ฌ์–‘์˜ ๋ชฉ์ ์€ ์†์„ฑ์ด ์žˆ๋Š” ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ„๊ฒฐํ•˜๊ณ  ์นœ์ˆ™ํ•œ ๊ตฌ๋ฌธ์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@cbazza ์ข‹์€ ์ง€์ ์„ ํ•˜์…จ์Šต๋‹ˆ๋‹ค. JSX๋Š” JavaScript์— ๋Œ€ํ•œ ๊ฐœ์„  ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋จผ์ € ๋‘ ๊ฐ€์ง€๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. UI ์ •์˜๋ฅผ ์œ„ํ•œ ์™ธ๋ถ€ DSL. ์ €๋Š” ์ด์— ๋Œ€ํ•ด 100% ๋ฐ˜๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐํ•œ๋‹ค๊ณ  ํ•ญ์ƒ ๋ฏฟ์–ด์™”์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ์ ์„ ์ฃผ์žฅํ•˜๋Š” ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ๋ฅผ ์ผ๋‹ค. 58K ์กฐํšŒ์ˆ˜๋ฅผ ๊ธฐ๋กํ–ˆ๊ณ  ๋†€๋ž๊ฒŒ๋„ ๋ฐ˜๋Œ€ ์˜๊ฒฌ์ด ๊ฑฐ์˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ฝ”๋”ฉ์˜ 80%๊ฐ€ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(๋˜๋Š” ํ…œํ”Œ๋ฆฟ์ด ์ฃฝ์€ ์ด์œ ).
  2. ์–ธ์–ด ๊ฐœ์„ . ๊นŠ์ด ์ค‘์ฒฉ๋œ UI ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋” ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•˜๊ณ  ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด ์šฐ๋ฆฌ๋Š” ๋‘˜ ๋‹ค ๊ฐœ์„ ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์—์„œ ์•ฝ๊ฐ„ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. JSX๊ฐ€ React์— ๋” ์ ํ•ฉํ•œ ๋‘ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ: ์›น์—์„œ JSX๋Š” ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค(HTML DOM ๋…ธ๋“œ). Flutter์—์„œ๋Š” ์œ„์ ฏ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ์ต์ˆ™ํ•จ: ์‚ฌ๋žŒ๋“ค์€ html ์ฝ”๋“œ๋ฅผ ๋ณด๋Š” ๋ฐ ์ต์ˆ™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ DSX ์ œ์•ˆ์€ ์ด ์ ์„ ๋ฌดํšจํ™”ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•  ์ •๋„๋กœ JSX/XML์—์„œ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์€ XML์„ UI ํŠธ๋ฆฌ ๊ตฌ์„ฑ์— ์ ํ•ฉํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๋‘ ๊ฐ€์ง€ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ์–ธ์–ด์— XML์„ ๋„์ž…ํ•˜์ง€ ์•Š๊ณ ๋„ ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š๋ƒ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  1. XML์—๋Š” End ํƒœ๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ xml-ish ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. Visual Basic์€ 90๋…„๋Œ€์— ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค(End If๋ฅผ ์ƒ๊ฐํ•ด ๋ณด์„ธ์š”). ๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ์–ธ์–ด์—๋„ ์žˆ์Šต๋‹ˆ๋‹ค. IDE๋Š” "๊ฐ€์ƒ ์ข…๋ฃŒ ํƒœ๊ทธ"๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ์ผ์ข…์˜ ์Šค์ผ€์น˜์ž…๋‹ˆ๋‹ค. ์–ธ์–ด ์ง€์›์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.
  2. XML์€ ์–ด๋ฆฐ์ด๋ฅผ ํŠน๋ณ„ํ•˜๊ฒŒ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ์€ ์ž์‹๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ์ด๊ฒƒ์ด ์–‘๋‚ ์˜ ๊ฒ€์ด๋ผ๊ณ  ์ฃผ์žฅํ•˜๊ณ  ์‹ถ๋‹ค. ์ด ์ ์—์„œ Dart๊ฐ€ ์‹ค์ œ๋กœ XML๋ณด๋‹ค ๋” ๋ช…ํ™•ํ•˜๊ณ  ํ‘œํ˜„๋ ฅ์ด ๋›ฐ์–ด๋‚œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค๋ฅธ ํ•˜์œ„ ์ฝ˜ํ…์ธ  ๋ชจ๋ธ์ด ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ ์œ„์ ฏ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
MyWidgetA(children: [ w1, w2 ])
MyWidgetB(child: w1)
MyWidgetC(top: w1, bottom: w2)

๋ ํƒœ๊ทธ ๋ฌธ์ œ์— ๋Œ€ํ•œ Dave ์ œ์•ˆ

ButtonsView(
        onDeal: onDeal,
        onHit: onHit,
        onStay: onStay,
)ButtonsView

์ด๊ฒƒ์€ ์ธ๊ฐ„์ด ์ฝ๊ธฐ ์‰ฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํŒŒ์„œ๋Š” )ButtonsView ๋ฅผ ) ๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ IDE๋Š” ์ด ์ฒด๊ณ„์— ๋Œ€ํ•ด ๋” ๋‚˜์€ ํ™•์ธ ๋ฐ ์ง€์›์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ด๋ฆฐ ๊ด„ํ˜ธ์™€ ๋‹ซ๋Š” ๊ด„ํ˜ธ๊ฐ€ ๊ฐ™์€ ์ค„์— ์žˆ์ง€ ์•Š์„ ๋•Œ๋งˆ๋‹ค ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ค‘์ฒฉ๋œ ์ž์‹ ๋ฌธ์ œ์— ๋Œ€ํ•œ Dave ์ œ์•ˆ

์ผ๋ถ€ ์–ธ์–ด(์˜ˆ: kotlin)์—์„œ๋Š” ๋žŒ๋‹ค ์œ ํ˜•์˜ ์ธ์ˆ˜์— ๋Œ€ํ•œ ํŠน์ˆ˜ ์ฒ˜๋ฆฌ๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋“ค์„ ์‚ฌ์šฉํ•˜๋ฉด ๋žŒ๋‹ค ์ธ์ˆ˜๋ฅผ ๊ด„ํ˜ธ ์™ธ๋ถ€์— ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋žŒ๋‹ค ์ „๋‹ฌ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” Dart์— ๋Œ€ํ•ด ๋น„์Šทํ•œ ๊ฒƒ์„ ์ œ์•ˆํ•˜์ง€๋งŒ ๋žŒ๋‹ค๊ฐ€ ์•„๋‹Œ List ์œ ํ˜•์˜ arg๋กœ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. "children"์ด๋ผ๋Š” ์ด๋ฆ„์˜ ๋ชฉ๋ก ์œ ํ˜•์˜ ์ธ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ํŠน์ˆ˜ ๊ตฌ๋ฌธ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

```
//์ด ๋Œ€์‹ :
ํ‘ธ(a: 1, b:10, c:44, ์–ด๋ฆฐ์ด:[...])

// ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ํ•œ๋‹ค:
ํ‘ธ(a: 1, b:10, c:44)[

]

ํ•˜๋‚˜์˜ ์ž์‹ ๋˜๋Š” 2๊ฐœ์˜ ์ž์‹(์ƒ๋‹จ ๋ฐ ํ•˜๋‹จ๊ณผ ๊ฐ™์€)์„ ์ทจํ•˜๋Š” ์ƒ์„ฑ์ž/ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ ๊ทธ๋Œ€๋กœ ๋‘์‹ญ์‹œ์˜ค. ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์—†์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ฒƒ์„ ๋‹จ์ผ ์œ ํ˜• ๊ฒ€์‚ฌ ์–ธ์–ด๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์ด ๋ฐ”๋กœ DSX/JSX๊ฐ€ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค. ์–ธ์–ด๋Š” DSX์šฉ Dart, JSX์šฉ Javascript์ž…๋‹ˆ๋‹ค!!!

๊นŠ์ด ์ค‘์ฒฉ๋œ ์„ ์–ธ์  UI ํŠธ๋ฆฌ๋ฅผ ์ฝ”๋”ฉํ•  ๋ชฉ์ ์œผ๋กœ Dart ์–ธ์–ด๋ฅผ ๊ณ„์† ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์€ ์ ‘๊ทผ ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

DSX๋Š” ๊นŠ์ด ์ค‘์ฒฉ๋œ ์„ ์–ธ์  ํŠธ๋ฆฌ๋ฅผ ๋” ์ž˜ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด Dart ์–ธ์–ด๋ฅผ ๊ฐœ์„ ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. JSX๊ฐ€ Javascript์šฉ์ธ ๊ฒƒ์ฒ˜๋Ÿผ.

https://facebook.github.io/jsx/

์ด ์‚ฌ์–‘์˜ ๋ชฉ์ ์€ ์†์„ฑ์ด ์žˆ๋Š” ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ„๊ฒฐํ•˜๊ณ  ์นœ์ˆ™ํ•œ ๊ตฌ๋ฌธ์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@StokeMasterJack - ๋ ํƒœ๊ทธ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์ œ์•ˆ์€ ์–ผ๋งˆ ์ „ ์ œ ์ œ์•ˆ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.
์•„์ด๋””์–ด: ์ž๋™ ์ƒ์„ฑ๋œ ๋‹ซ๋Š” ํƒœ๊ทธ

ํ”Œ๋Ÿฌํ„ฐ์—๋Š” ์ด๋Ÿฐ ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๋‚  ๊นŠ์€ ๋‘ฅ์ง€ ์•ˆ์— ์ƒˆ ์œ„์ ฏ์„ ์‚ฝ์ž…ํ•˜๋Š” ๋ฐ ์–ด๋ ค์›€์„ ๊ฒช์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ ํƒœ๊ทธ ํ‘œ๊ธฐ๋ฒ•์„ ์–ป๊ธฐ ์œ„ํ•ด JSX์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ซ๋Š” ํƒœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. JSX/html/xml์˜ ๊ณ ํ†ต์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ๋‚ด๊ฐ€ ๋ฆฌํŒฉํ† ๋งํ•˜๊ณ  ์‹ถ์„ ๋•Œ.
๊ฐ€์ƒ ๋‹ซ๋Š” ํƒœ๊ทธ๊ฐ€ ๊ฝค ๊น”๋”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‘ ์„ธ๊ณ„ ์‚ฌ์ด์˜ ์ข‹์€ ํƒ€ํ˜‘์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ช‡ ๊ฐ€์ง€ ๊ฐœ์„  ์‚ฌํ•ญ์ด ์ •๋ง๋กœ ํ•„์š”ํ•œ ๊ฒฝ์šฐ IDE ์ธก๋ฉด์—์„œ ๊ณ„์† ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด vscode๋Š” ๋‹ค์Œ ํŒจ๋„์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

screen shot 2018-10-11 at 01 31 33

(Android Studio๋„ ๋™์ผํ•˜๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค)

์ง‘์ค‘๋œ ๋ฉ”์„œ๋“œ์—์„œ ๋ฉˆ์ถ”๋Š” ๋Œ€์‹  ์ƒ์„ฑ์ž ์ค‘์ฒฉ๋„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํŠน์ • ํด๋ž˜์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉด ๋‹ค์Œ UI๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

lib > main.dart > Foo > build > Container > Center > Text 

์‹œ๊ฐ์  ์œ„์ ฏ์„ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ์ฝ˜ํ…์ธ ์™€ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋ผ๋ฉด IDE์—์„œ๋„ ๋‹ค์‹œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์ ฏ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ๊ตฌ๋ฌธ ๊ฐ•์กฐ ํ‘œ์‹œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค์— ์‚ฌ์šฉ๋˜๋Š” ์ผ๋ฐ˜์ ์ธ ์ƒ‰์ƒ ๋Œ€์‹  ์œ„์ ฏ ํ•˜์œ„ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํŠน์ • ์ƒ‰์ƒ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


ํŽธ์ง‘ ๊ฐ€๋Šฅ์„ฑ์— ๊ด€ํ•œ ๊ฒƒ์ด๋ผ๋ฉด Flutter๋Š” ์ด๋ฏธ ํ•„์š”ํ•œ ๋ชจ๋“  ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์„ ํฌํ•จํ•˜์—ฌ ๋ช‡ ๊ฐ€์ง€ ๋ฆฌํŒฉํ† ๋ง ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ƒˆ ์œ„์ ฏ์œผ๋กœ ๋ž˜ํ•‘
  • ์œ„์ ฏ ์ œ๊ฑฐ
  • ์ž์‹์œผ๋กœ ์œ„์ ฏ ๋ฐ”๊พธ๊ธฐ
  • ๋ถ€๋ชจ์™€ ์œ„์ ฏ ๊ต์ฒด

์ด๋ฅผ ์—ผ๋‘์— ๋‘๊ณ  ๋” ์ด์ƒ ๊ด„ํ˜ธ๋ฅผ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.


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

@rrousselGit - ์œ ์šฉํ•œ ๋ฆฌํŒฉํ† ๋ง ์˜ต์…˜์ž…๋‹ˆ๋‹ค. Android Studio 3.2์—์„œ๋Š” ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
Android Studio๊ฐ€ Flutter ๊ฐœ๋ฐœ์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

@๋ก๋ณผ

๋‹ค์Œ์€ Android Studio์˜ ์Šคํฌ๋ฆฐ์ƒท์ž…๋‹ˆ๋‹ค.

image

๋น ๋ฅธ ์ˆ˜์ • Option+Enter (macOS)์œผ๋กœ ํ™œ์„ฑํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ์ด๊ฒƒ๋“ค์„ ํ•ญ์ƒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์ œ: Flutter ํŒ€์ด "์ฝ”๋“œ๋กœ์„œ์˜ UI" ์˜ต์…˜์„ ํƒ์ƒ‰ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ด๋ฉฐ ์กฐ๋งŒ๊ฐ„ ์ด ๋ถ€๋ถ„์—์„œ ๋” ๋งŽ์€ ๊ฐœ์„  ์‚ฌํ•ญ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @StokeMasterJack ์˜ ์•„์ด๋””์–ด๋Š” ํฅ๋ฏธ๋กญ๊ฒŒ ๋“ค๋ฆฌ์ง€๋งŒ.

@Rockvole ์œ„๋Œ€ํ•œ ๋งˆ์Œ์€ ๋น„์Šทํ•˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค!

@StokeMasterJack

์ข‹์€ ๋‹ต๋ณ€ !!!

JSX๊ฐ€ React์— ๋” ์ ํ•ฉํ•œ ๋‘ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ: ์›น์—์„œ JSX๋Š” ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค(HTML DOM ๋…ธ๋“œ). Flutter์—์„œ๋Š” ์œ„์ ฏ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

JSX์˜ ํž˜์€ HTML/DOM ๋…ธ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ตฌ์„ฑ ์š”์†Œ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์žˆ์Šต๋‹ˆ๋‹ค. React Native์—๋Š” HTML/DOM ๋…ธ๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๊นŒ?

  1. ์ต์ˆ™ํ•จ: ์‚ฌ๋žŒ๋“ค์€ html ์ฝ”๋“œ๋ฅผ ๋ณด๋Š” ๋ฐ ์ต์ˆ™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ DSX ์ œ์•ˆ์€ ์ด ์ ์„ ๋ฌดํšจํ™”ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•  ์ •๋„๋กœ JSX/XML์—์„œ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค.

์œ„์™€ ๊ฐ™์ด HTML ์ฝ”๋“œ ์— ๋Œ€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ˜ธ์ŠคํŠธ ์–ธ์–ด์˜ ๋ช…๋ น์  ๊ตฌ์„ฑ์—์„œ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌ๋˜๊ณ  ํŠธ๋ฆฌ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ์„ ์–ธ์  ๋งˆํฌ์—…์„ ์™ธ์น˜๋Š” ๊ตฌ๋ฌธ์— ๋Œ€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค .

๋‚˜๋Š” ๋‹น์‹ ์˜ ์ œ์•ˆ์ด๋‚˜ Kotlin์˜ ํŒฌ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ์€ ์ ์ ˆํ•œ ๋””์ž์ธ์„ ํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ํ–‰ํ•ด์ง„ ํ•ดํ‚น์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋šœ๋ ทํ•˜๊ฒŒ ๋ณด์ด๋Š” DSL์„ ์„ค๊ณ„ํ•˜๋Š” ๋Œ€์‹  ์ด์ œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ๊ทธ๊ฒƒ์ด ํ•˜๋Š” ์ผ์„ ํŒŒ์•…ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ์ด ๋ชจํ˜ธํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ๋ช…๋ น ๊ตฌ๋ฌธ๊ณผ ์„ ์–ธ ๊ตฌ๋ฌธ์„ ๋ถ„๋ฆฌํ•˜๋ฉด ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํƒ€์‚ฌ ๋„๊ตฌ๋Š” ์˜ˆ๋ฅผ ๋“ค์–ด ์ฝ”๋“œ ๋‚ด์—์„œ XML ๋งˆํฌ์—…์„ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@๋ก๋ณผ

์ข…๋ฃŒ ํƒœ๊ทธ ํ‘œ๊ธฐ๋ฒ•์„ ์–ป๊ธฐ ์œ„ํ•ด JSX์™€ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์•Œ์•„ ๋‘˜๋งŒ ํ•œ ;)

@rrousselGit

๋‹ซ๋Š” ํƒœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿด ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด WebStorm์€ ๋‹ซ๋Š” ํƒœ๊ทธ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ๋‹ค๋ฅธ ํƒœ๊ทธ๋ฅผ ํŽธ์ง‘ํ•  ๋•Œ ์—ด๊ฑฐ๋‚˜ ๋‹ซ๋Š” ํƒœ๊ทธ์˜ ์ด๋ฆ„๋„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ๋”ฐ๋ผ์•ผ ํ•˜๋Š” ์ •๋ง ํ›Œ๋ฅญํ•œ ํŽธ์ง‘๊ธฐ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค('VS ์ฝ”๋“œ' ์ฐธ์กฐ).

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

๊ท€ํ•˜์˜ ๊ฒฝํ—˜์ด ๋‹ค๋ฅธ ๋ชจ๋“  ์‚ฌ๋žŒ์˜ ๊ฒฝํ—˜์„ ๋ฐ˜์˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์ดํ•ดํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž‘์„ฑ์ด ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ๊ฒƒ๋งŒํผ ๊ณ ํ†ต์Šค๋Ÿฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์˜ ์ฝ”๋“œ๋ฅผ ์ฝ์œผ๋ ค๋ฉด github์œผ๋กœ ์ด๋™ํ•˜์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ์ฝ๊ธฐ๊ฐ€ ํž˜๋“ค๊ณ  ์ฝ”๋“œ๊ฐ€ ์ค‘์ฒฉ ๊ตฌ์กฐ๋กœ ์ธํ•ด ๋„ˆ๋ฌด ์žฅํ™ฉํ•˜๊ณ  ๊ธธ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. async/await๊ฐ€ ๋” ๋‚˜์€ ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์ „์— promise-chains๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ์„ ๋•Œ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ์„ ์–ธ์  ๊ธฐ์ˆ ์ด ๋ช…๋ น์  ๊ธฐ์ˆ ๋ณด๋‹ค ๋œ ์ค‘์š”ํ•˜๋‹ค๊ณ  ๋Š๊ปด์ง‘๋‹ˆ๋‹ค. ์„ ์–ธ์  ๋ฒกํ„ฐ ๊ทธ๋ž˜ํ”ฝ ๊ตฌ์กฐ๊ฐ€ ์—†๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋Œ€์‹  ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฒกํ„ฐ ๊ทธ๋ž˜ํ”ฝ ๊ทธ๋ฆฌ๊ธฐ๋ฅผ ์œ„ํ•ด Skia์— ๋Œ€ํ•œ ๋ช…๋ นํ˜• ํ˜ธ์ถœ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿด ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด WebStorm์€ ์ž๋™ ์ƒ์„ฑ

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

๊ท€ํ•˜์˜ ๊ฒฝํ—˜์ด ๋‹ค๋ฅธ ๋ชจ๋“  ์‚ฌ๋žŒ์˜ ๊ฒฝํ—˜์„ ๋ฐ˜์˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์ดํ•ดํ•ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

ํ™•์‹คํžˆ! ํˆด๋ง์— ๋Œ€ํ•œ ๊ฒฝํ—˜ ๋ถ€์กฑ์ด๋ผ๊ธฐ๋ณด๋‹ค๋Š” ์‹ค์ œ ๋ถ€์กฑ์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ์ง€์ ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜„

github์œผ๋กœ ์ด๋™ํ•˜์—ฌ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์˜ ์ฝ”๋“œ๋ฅผ ์ฝ์œผ๋ฉด ์ฝ๊ธฐ๊ฐ€ ๊ณ ํ†ต์Šค๋Ÿฝ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. [...]

๋‚˜๋Š” ๋‹น์‹ ์˜ ์ฃผ์žฅ์ด ์ฃผ์ œ์™€ ์–ด๋–ค ๊ด€๋ จ์ด ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
๊ท€ํ•˜๊ฐ€ ๋‚˜์—ดํ•œ ๋ฌธ์ œ๋Š” ์ž˜๋ชป๋œ ๊ตฌ๋ฌธ์ด ์•„๋‹ˆ๋ผ ์ž˜๋ชป๋œ ๊ด€ํ–‰์—์„œ ๋น„๋กฏ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด 500๊ฐœ์˜ ๊ธด ์œ„์ ฏ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์–ดํ•˜๋Š” ๊ฒƒ์€ Flutter์˜ ์ž˜๋ชป์ด ์•„๋‹™๋‹ˆ๋‹ค.

@pulyaevskiy - ์œ ์šฉํ•œ ํŒ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. Linux์—์„œ ๋น ๋ฅธ ์ˆ˜์ •์€ Alt-Enter์ž…๋‹ˆ๋‹ค. ๋ฐœ๊ฒฌํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ตœ์ƒ์œ„ ๋ฉ”๋‰ด ์˜ต์…˜์„ ์ƒ…์ƒ…์ด ๋’ค์กŒ์ง€๋งŒ ๋งˆ๋ฒ•์˜ ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋Š” ๊ฒƒ ์™ธ์—๋Š” ์–ด๋””์—๋„ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. :)

์—ฌ๊ธฐ์—์„œ ๊ฐ€์ƒ ํƒœ๊ทธ๊ฐ€ ํ›จ์”ฌ ๋” ๋ถ€๋“œ๋Ÿฌ์šด ๊ฒฝํ—˜์„ ์ œ๊ณตํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ด๋Ÿฌํ•œ ๊ฐ€์ƒ ํƒœ๊ทธ๊ฐ€ github์˜ ์†Œ์Šค ํŒŒ์ผ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๊นŒ?

๋‚˜๋Š” ๋‹น์‹ ์˜ ์ฃผ์žฅ์ด ์ฃผ์ œ์™€ ์–ด๋–ค ๊ด€๋ จ์ด ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์–ธ์–ด๋Š” ๋‚ด๊ฐ€ promise ๋Œ€ async/await ์˜ˆ์ œ์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋œ ์žฅํ™ฉํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ตฌ์„ฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Flutter Widget์—์„œ ์ƒ์„ฑ์ž๋Š” ๊ฑฐ๋Œ€ํ•˜๊ณ  ๋งŽ์€ ๊ฒฝ์šฐ ๋งŽ์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. DSX๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์˜ˆ๋ฅผ ๋“ค์–ด ํ™•์‚ฐ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 10์ค„ ์ƒ์„ฑ์ž๋ฅผ 1์ค„ ์ƒ์„ฑ์ž๋กœ ์••์ถ•ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ๋ณ€ ์†Œ์Œ์ด ์ ์€ ์™„์ „ํ•œ ํŠธ๋ฆฌ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๊ณ  ์˜ˆ๋ฅผ ๋“ค์–ด ํŠธ๋ฆฌ ๊ตฌ์กฐ์—์„œ ์Šคํƒ€์ผ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด Dart ์ฝ”๋“œ๋ฅผ ์žฌ๊ตฌ์„ฑํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ง์€ ์•„๋‹ˆ์ง€๋งŒ ๋งŽ์€ ๋…ธ๋ ฅ์ด๋‚˜ ์ฃผ๋ณ€์˜ ๊ฒƒ์„ ์žฌ๊ตฌ์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ์–ธ์–ด์˜ ํ•œ๊ณ„์— ๋งž์ถœ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค, ์–ธ์–ด๋Š” ๋‹น์‹ ์—๊ฒŒ ๋งž์Šต๋‹ˆ๋‹ค.

๊ท€ํ•˜๊ฐ€ ๋‚˜์—ดํ•œ ๋ฌธ์ œ๋Š” ์ž˜๋ชป๋œ ๊ตฌ๋ฌธ์ด ์•„๋‹ˆ๋ผ ์ž˜๋ชป๋œ ๊ด€ํ–‰์—์„œ ๋น„๋กฏ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

์ด๊ฒƒ์€ ๋”์ฐํ•œ ์˜ˆ ์ž…๋‹ˆ๋‹ค @woodstream

์—…๋ฐ์ดํŠธ : ๋‚ด ์š”์ ์„ ๋ฐํžˆ๊ณ  ๋…ผ์Ÿ์—†์ด ๋‹จ์–ด๋ฅผ ๋‘๋“œ๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. DSX์™€ ๋™๋“ฑํ•œ ๊ธธ์ด๋Š” ... ์ด๊ฒƒ์€ ์ค„ ์ˆ˜ ๋˜๋Š” HTML๊ณผ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.

class MusicImage extends StatelessWidget {

  TextStyle titleTextStyle = TextStyle(
    fontWeight: FontWeight.w800,
    letterSpacing: 0.5,
    fontSize: 20.0
  );

  Container titleText = (
    <Container height={116.0} padding={EdgeInsets.all(10.0)}>
      <Text style={titleTextStyle}>title</Text>
    </Container>
  );

  TextStyle authorTextStyle = TextStyle(
    fontWeight: FontWeight.w800,
    letterSpacing: 0.5,
    fontSize: 10.0,
  );

  Container music = (
    <Container
      height={40.0}
      decoration={BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(8.0))
      )}
      padding={EdgeInsets.fromLTRB(0.0, 5.0, 5.0, 0.0)}
      margin={EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0)}
    >
      <Stack>
        <Row>
          <Container
            height={30.0}
            width={30.0}
            decoration={BoxDecoration(
              borderRadius: BorderRadius.all(Radius.circular(8.0))
            )}
            margin={EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0)}
          >
            {Image.asset('images/bg2.jpg')}
          </Container>
          <Column>
            <Text>music</Text>
            <Text style={authorTextStyle}>author</Text>
          </Column>
        </Row> 
        <Align alignment={FractionalOffset.centerRight}>
          <Icon icon={Icons.play_arrow} />
        </Align>
      </Stack>
    </Container>
  )

  <strong i="9">@override</strong>
  Widget build(BuildContext context) {
    return (
      <Container
        height={168.0}
        margin={EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 8.0)}
        decoration={BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(8.0)),
          image: DecorationImage(
            image: new AssetImage('images/bg.jpg'),
            fit: BoxFit.cover,
          ),
        )}
      >
        {titleText}
        {music}
      </Container>
    );
  }
}

React ๊ฐœ๋ฐœ์ž๋กœ์„œ ์ด ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ํ•ด์•ผ ํ•  ์ผ์€ ์ด ๊ธฐ๋Šฅ์„ ์ž์ฒด์ ์œผ๋กœ ์ œ๊ณตํ•˜๊ณ  ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•  ๋•Œ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ฃผ์š” ๊ธฐ์—ฌ์ž๋“ค๋„ ์ด๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” React ๊ฐœ๋ฐœ์ž์ด๊ณ  UI๊ฐ€ ํ”Œ๋Ÿฌํ„ฐ๋กœ ์ž‘์„ฑ๋˜๋Š” ๋ฐฉ์‹์„ ๋‹ค๋ฃจ๋Š” ๋ฐ ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”Œ๋Ÿฌํ„ฐ๋กœ ์ด๋™ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ๊ตฌ๋ฌธ์ด ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. JSX์™€ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋„ ์—ฐ๊ตฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜ ์ž์‹ , "์„ ํƒ๊ถŒ์ด ์žˆ์–ด์„œ ์ข‹๋‹ค" ์ „์— ๋งํ–ˆ๋“ฏ์ด.

์‚ฌ๋žŒ๋“ค์ด ์ด๊ฒƒ์„ ๋ฐ˜๋Œ€ํ•˜๋Š” ์ฃผ๋œ ์ด์œ  ์ค‘ ํ•˜๋‚˜๋Š” ๊ทธ๋“ค์ด ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ง„์‹ค์€ ์‚ฌ๋žŒ๋“ค์ด <Component /> #$์™€ ๋‹ฌ๋ฆฌ React.createElement(Component, {}, null) ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ (๋ฐ˜์‘๊ณผ ๋น„๊ตํ•˜์—ฌ) ์‹ค์ œ๋กœ ๊ทธ๋ ‡๊ฒŒ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ตฌํ˜„๋˜๋ฉด ์‚ฌ๋žŒ๋“ค์ด ์ฒ˜์Œ์— Flutter๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์žฅ์†Œ, ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ์ •๋ง๋กœ ์›ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„œ๋กœ์˜ ์ง€์›์„ ๋ฐ›์•„ Flutter์— ์ „๋…ํ•˜๋Š” ๋Œ€๊ทœ๋ชจ ์ปค๋ฎค๋‹ˆํ‹ฐ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ๋ฌธ ์œ ํ˜•์ด ์•„๋‹ˆ๋ผ๋ฉด ์˜ค ๊ธ€์Ž„์š”. ๊ทธ๋Ÿฌ๋‚˜ ํ†ค์€ ํ˜„์žฌ ๋ฐฉ๋ฒ•๊ณผ ๋ฐ˜๋Œ€๋กœ JSX์™€ ๊ฐ™์€ ํ‘œ๊ธฐ๋ฒ•์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ์ธ์ ์œผ๋กœ ๋‚˜๋Š” SGML๊ณผ ๊ทธ ํŒŒ์ƒ๋ฌผ์ด ๊ทธ์ € ๋ณด๊ธฐ ํ‰ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. DSL์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ QML๊ณผ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋‚˜๋Š” ๋˜ํ•œ DSX๋ฅผ ์ง€์ง€ํ•˜๋Š” ํฌ์ธํŠธ ์ค‘ ์ผ๋ถ€๊ฐ€ ์–ธ์–ด๋กœ์„œ์˜ Javascript์˜ ๊ธฐ๋Šฅ(์–ธ์–ด๋กœ์„œ์˜ Dart์—๋Š” ์—†๋Š”)๊ณผ DSL๋กœ์„œ์˜ JSX์˜ ๊ธฐ๋Šฅ์„ ํ˜ผ๋™ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด,

๊ธฐ๋ณธ์ ์œผ๋กœ ์–ธ์–ด๋Š” ๋‚ด๊ฐ€ promise ๋Œ€ async/await ์˜ˆ์ œ์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋œ ์žฅํ™ฉํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ตฌ์„ฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Flutter Widget์—์„œ ์ƒ์„ฑ์ž๋Š” ๊ฑฐ๋Œ€ํ•˜๊ณ  ๋งŽ์€ ๊ฒฝ์šฐ ๋งŽ์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. DSX๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์˜ˆ๋ฅผ ๋“ค์–ด ํ™•์‚ฐ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 10์ค„ ์ƒ์„ฑ์ž๋ฅผ 1์ค„ ์ƒ์„ฑ์ž๋กœ ์••์ถ•ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ๋ณ€ ์†Œ์Œ์ด ์ ์€ ์™„์ „ํ•œ ํŠธ๋ฆฌ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ DSX๊ฐ€ ๋งˆ๋ฒ•์ฒ˜๋Ÿผ ๋ถ€์—ฌํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ Javascript์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— JSX๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์–ธ์–ด๋กœ์„œ์˜ Dart๋Š” ํ™•์‚ฐ ์—ฐ์‚ฐ์ž๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(IMO๋Š” ๊ฑฐ์˜ ์—†์Œ). ์ด ๊ฒฝ์šฐ ํŠน๋ณ„ํ•œ DSL ์—†์ด๋„ ์ƒ์„ฑ์ž ๋ฐ ๊ธฐํƒ€ ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Javascript์˜ ๊ฐœ์ฒด, ํ•ด์‹œ๋งต ๋ฐ ๋ฐฐ์—ด์ด ๋ชจ๋‘ ๋ณธ์งˆ์ ์œผ๋กœ ๋™์ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํฌ๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” Dart์˜ ๊ฒฝ์šฐ๊ฐ€ ๊ฐ€์žฅ ํ™•์‹คํ•˜๊ณ  ๊ฑฐ์˜ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ œ ์ƒ๊ฐ์—๋Š” ์ œ์•ˆ์— ๋ฐ˜๋Œ€ํ•˜๋Š” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋ชฉ์†Œ๋ฆฌ๋ฅผ ๋‚ด์ง€ ์•Š๋”๋ผ๋„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ Dart๊ฐ€ Javascript์ฒ˜๋Ÿผ ํ–‰๋™ํ•˜๋„๋ก(๋˜๋Š” ํ–‰๋™ํ•˜๋Š” ์ฒ™) ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ผ๋ถ€ ์ฐฌ์„ฑ์ด ์žˆ์ง€๋งŒ ์‚ฌ์‹ค์€ ๊ทธ๋“ค์€ ๋‹จ์ˆœํžˆ Dart 1์˜ ์ดˆ๊ธฐ๋ถ€ํ„ฐ ์ ์  ๋” ๋‹ค์–‘ํ•ด์ง„ ๋‹ค๋ฅธ ์–ธ์–ด์ž…๋‹ˆ๋‹ค.

ํŽธ์ง‘: UI์šฉ ๋งˆํฌ์—…/๋ชจ๋ธ๋ง DSL์ด ์™„์ „ํžˆ ๋‚˜์œ ์ƒ๊ฐ์ด๋ผ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์†”์งํžˆ ๊ทธ๋ ‡์ง€๋Š” ์•Š์ง€๋งŒ Javascript๋ณด๋‹ค Dart/Flutter(ํƒ€์ดํ•‘ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ฐ ๊ธฐํƒ€ ์˜๋ฏธ๋ก ์  ์„ธ๋ถ€ ์‚ฌํ•ญ์—์„œ - ๋‚˜๋Š” ์ผ๋ฐ˜ ๊ตฌ๋ฌธ์— ๋Œ€ํ•ด ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹˜)์™€ ์กฐ๊ธˆ ๋” ์œ ์‚ฌํ•œ ์–ธ์–ด/ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์˜๊ฐ์„ ์–ป์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋‹ค.

์–ธ์–ด๋กœ์„œ์˜ Dart๋Š” ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(IMO๋Š” ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅ)

์‚ฌ์‹ค ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ ์Šคํ”„๋ ˆ๋“œ๋Š” ์ด๋ฏธ ์ง€์ •๋˜์–ด ์žˆ๊ณ  ๊ตฌํ˜„ํ•  ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ–ฅํ›„ Dart ์–ธ์–ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์Šคํ”„๋ ˆ๋“œ ์ปฌ๋ ‰์…˜ ๋ฐ ์ „์ฒด "์–ธ์–ด ํผ๋„" ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

@mraleph ๋ชฉ๋ก์ด๋‚˜ ๋งต๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜/์ƒ์„ฑ์ž ํ˜ธ์ถœ ๋ฐ ๊ฐ์ฒด์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋Š” ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿด ๊ฐ€๋Šฅ์„ฑ์€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค!

(๋‚˜๋Š” ๊ทธ ์ œ์•ˆ์„ ๋ง‰์—ฐํ•˜๊ฒŒ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ๋งˆ์ง€๋ง‰์œผ๋กœ ํ™•์ธํ•œ ๊ฒƒ์€ Javascript Size { width: 10, height: 10 } ๋ฅผ ํผ๋œจ๋ฆฌ๊ฑฐ๋‚˜ ํŒŒ๊ดดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ Dart Size(10, 10) ๋ฅผ ํผ๋œจ๋ฆฌ๊ฑฐ๋‚˜ ๋ชฉ๋ก์„ ํผ๋œจ๋ฆด ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. /์ผ๋ฐ˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ์— ๋Œ€ํ•œ ์ธ์ˆ˜ ๋งคํ•‘(์œ ํ˜• ์•ˆ์ „์„ฑ์„ ํฌ์ƒ์‹œํ‚ค๋Š” Function.apply ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ)

@filleduchaos

๊ฐœ์ธ์ ์œผ๋กœ ๋‚˜๋Š” SGML๊ณผ ๊ทธ ํŒŒ์ƒ๋ฌผ์ด ๊ทธ์ € ๋ณด๊ธฐ ํ‰ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. DSL์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ QML๊ณผ ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋‹น์‹ ๊ณผ ๋‹ฌ๋ฆฌ ๋ชป์ƒ๊ฒผ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๊ณ  ์„ ํ˜ธํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์—ด์ •์ ์ธ React ๊ฐœ๋ฐœ์ž๋ฅผ ๋ชจ๋‘ ๋ณด๊ธฐ ์œ„ํ•ด ๋งŽ์€ ๋น„์ „์„ ๊ฐ€์งˆ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

JSX/DSX๋Š” ํ˜ธ์ŠคํŠธ ์–ธ์–ด๋ฅผ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ๋งˆํฌ์—…์— ๋Œ€ํ•œ ๋ชจ๋“  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๊ตฌ์„ฑ์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ˜ธ์ŠคํŠธ ์–ธ์–ด Javascript/Dart์— ๋งˆํฌ์—…์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ DSX๊ฐ€ ๋งˆ๋ฒ•์ฒ˜๋Ÿผ ๋ถ€์—ฌํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ Javascript์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— JSX๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

์ „ํ˜€ ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค. DSX๋Š” ์ž์ฒด์ ์œผ๋กœ ํ™•์‚ฐ ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด Dart๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•„์ˆ˜ ์กฐ๊ฑด์€ ์•„๋‹ˆ์ง€๋งŒ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ณ ๊ธ‰ ์–ธ์–ด์—์„œ Dart๋กœ ํŠธ๋žœ์ŠคํŒŒ์ผํ•˜๋Š” ๊ฒƒ์˜ ์•„๋ฆ„๋‹ค์›€์ž…๋‹ˆ๋‹ค. ๊ณ ๊ธ‰ ์–ธ์–ด๋Š” Dart์— ์˜ํ•ด ์ œํ•œ๋  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋‚ด ํ”„๋กœํ† ํƒ€์ž… ์˜จ๋ผ์ธ DSX ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ ํ”„๋กœ์„ธ์Šค ํ™•์‚ฐ ์—ฐ์‚ฐ์ž, ํ™•์ธ:
https://spark-heroku-dsx.herokuapp.com/index.html

๊ทธ๋ฆฌ๊ณ  ์ œ ์ƒ๊ฐ์—๋Š” ์ œ์•ˆ์— ๋ฐ˜๋Œ€ํ•˜๋Š” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋ชฉ์†Œ๋ฆฌ๋ฅผ ๋‚ด์ง€ ์•Š๋”๋ผ๋„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ Dart๊ฐ€ Javascript์ฒ˜๋Ÿผ ํ–‰๋™ํ•˜๋„๋ก(๋˜๋Š” ํ–‰๋™ํ•˜๋Š” ์ฒ™) ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ผ๋ถ€ ์ฐฌ์„ฑ์ด ์žˆ์ง€๋งŒ ์‚ฌ์‹ค์€ ๊ทธ๋“ค์€ ๋‹จ์ˆœํžˆ Dart 1์˜ ์ดˆ๊ธฐ๋ถ€ํ„ฐ ์ ์  ๋” ๋‹ค์–‘ํ•ด์ง„ ๋‹ค๋ฅธ ์–ธ์–ด์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ Dart๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ƒ๊ฐํ•˜์ง€ ๋ง๊ณ  ๋‹ค๋ฅธ ๋ชจ๋“  ์–ธ์–ด์—์„œ ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๋ฅผ ์ทจํ•˜์—ฌ ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์ผ ์ˆ˜ ์žˆ๋Š”์ง€์— ์ง‘์ค‘ํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ์˜๊ฐ์ด Javascript๋ณด๋‹ค Dart/Flutter์™€ ์กฐ๊ธˆ ๋” ์œ ์‚ฌํ•œ ์–ธ์–ด/ํ”„๋ ˆ์ž„์›Œํฌ(ํƒ€์ดํ•‘ ํŒจ๋Ÿฌ๋‹ค์ž„ ๋ฐ ๊ธฐํƒ€ ์˜๋ฏธ๋ก ์  ์„ธ๋ถ€ ์‚ฌํ•ญ์—์„œ - ๋‚˜๋Š” ์ผ๋ฐ˜ ๊ตฌ๋ฌธ์— ๋Œ€ํ•ด ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค)์—์„œ ์™€์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

Typescript๊ฐ€ ์ž…๋ ฅ๋˜๊ณ  JSX๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Flutter์— ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด UI ํ”„๋ ˆ์ž„์›Œํฌ๋Š” React์ด๋ฉฐ, JSX๋กœ ์ธํ•ด React๊ฐ€ ๋ฌด์—‡์„ ์‹œ์ž‘ํ–ˆ๋Š”์ง€ ์ถ”์ธกํ•ด ๋ณด์„ธ์š”. JSX/DSX๋ณด๋‹ค ๋” ๋‚˜์€ ๊ฒƒ์„ ์ƒ๊ฐํ•ด ๋‚ด์‹ญ์‹œ์˜ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ๋žŒ๋“ค์ด JSX/DSX์— ๋Œ€ํ•ด ๋” ์ด์ƒ ์š”๊ตฌํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. .

Dart ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด Python(๋ชฉ๋ก ๋ฐ ์‚ฌ์ „ ์ดํ•ด)๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๋ฅผ ์ทจํ•˜๋Š” ๊ฒƒ์„ ๋ณด๋‹ˆ ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค.

@cbazza

๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๋‹น์‹ ๊ณผ ๋‹ฌ๋ฆฌ ๋ชป์ƒ๊ฒผ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๊ณ  ์„ ํ˜ธํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ ๋ฐ˜๋Œ€. ํŠนํžˆ ์–ธ์–ด์™€ ๊ฐ•๋ ฅํ•œ ๊ด€๊ณ„๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์ด ๊ตฌ๋ฌธ์€ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค๋ฅธ ๊ตฌ๋ฌธ์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? (Android SDK์™€ ํ•จ๊ป˜ Java์™€ XML์€ ์ˆ˜๋…„๊ฐ„ ๊ด€๊ณ„๋ฅผ ์œ ์ง€ํ•ด ์™”์Šต๋‹ˆ๋‹ค. JSX๊ฐ€ ๋งค์šฐ ์œ ์‚ฌํ•œ Javascript ๋ฐ HTML๊ณผ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ œ์•ˆ๋œ DSX๋Š” ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” SGML ๊ตฌ๋ฌธ์„ ๋‹ค๋ฅธ ์–ธ์–ด์— ๋Œ€ํ•ด ์˜๋ฏธ๊ฐ€ ์žˆ์ง€๋งŒ ๋ฐ˜๋“œ์‹œ _Dart_์— ๋Œ€ํ•ด์„œ๋Š” ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.)

JSX/DSX๋Š” ํ˜ธ์ŠคํŠธ ์–ธ์–ด๋ฅผ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ๋งˆํฌ์—…์— ๋Œ€ํ•œ ๋ชจ๋“  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๊ตฌ์„ฑ์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ˜ธ์ŠคํŠธ ์–ธ์–ด Javascript/Dart์— ๋งˆํฌ์—…์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋งค์šฐ ๊ฐ„๋‹จํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ „ํ˜€ ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค. DSX๋Š” ์ž์ฒด์ ์œผ๋กœ ํ™•์‚ฐ ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด Dart๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•„์ˆ˜ ์กฐ๊ฑด์€ ์•„๋‹ˆ์ง€๋งŒ ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๊ณ ๊ธ‰ ์–ธ์–ด์—์„œ Dart๋กœ ํŠธ๋žœ์ŠคํŒŒ์ผํ•˜๋Š” ๊ฒƒ์˜ ์•„๋ฆ„๋‹ค์›€์ž…๋‹ˆ๋‹ค. ๊ณ ๊ธ‰ ์–ธ์–ด๋Š” Dart์— ์˜ํ•ด ์ œํ•œ๋  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ด ๋‘ ์ง„์ˆ ์„ ๋ณ‘์น˜๋กœ ๋ณด๋Š” ๊ฒƒ์€ ๋‹ค์†Œ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ๋“ค์€ ๋‹จ์ง€ ์ œ ์š”์ ์„ ์ฆ๋ช…ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. JSX๋Š” ํŠนํžˆ ๋‹จ์ˆœ์„ฑ ๋•Œ๋ฌธ์— (Javascript์˜ ๊ฒฝ์šฐ) ํ›Œ๋ฅญํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ JS ์–ธ์–ด ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ๋‹จ์ˆœํ•œ ์„คํƒ•์ผ ๋ฟ์ด๋ฉฐ ์‹ค์ œ๋กœ ํŠน๋ณ„ํ•œ ์˜๋ฏธ ์ž์ฒด๋ฅผ ๊ตฌํ˜„ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ ๋‹จ์ˆœํ•จ์„ ์˜ณ๊ฒŒ ์นญ์ฐฌํ•œ ๋‹ค์Œ DSX๊ฐ€ 1) ์–ผ๋งˆ๋‚˜ ๋” ๋งŽ์€ ์ž‘์—…์„ ์š”๊ตฌํ•ด์•ผ ํ•˜๋Š”์ง€, 2) DSX๊ฐ€ ๋ชฉํ‘œ ์–ธ์–ด์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์˜๋ฏธ๋ก ์„ ์ž์ฒด์ ์œผ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•˜์ง€๋งŒ ๊ฐ•๋ ฅํ•œ DSL.

๋‚ด ํ”„๋กœํ† ํƒ€์ž… ์˜จ๋ผ์ธ DSX ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ ํ”„๋กœ์„ธ์Šค ํ™•์‚ฐ ์—ฐ์‚ฐ์ž, ํ™•์ธ:
https://spark-heroku-dsx.herokuapp.com/index.html

์ด์ „์— ๊ท€ํ•˜์˜ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๋ฅผ ๋ณธ ์ ์ด ์žˆ์œผ๋ฉฐ ์ธ์ƒ์ ์ธ ์ž‘์—…์ด์ง€๋งŒ Javascript๋ฅผ ์–ธ์–ด๋กœ(๋”ฐ๋ผ์„œ JSX) ๊ธฐ๋ณธ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์ „ํ˜€ ๊ทผ์ ‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์ปฌ๋ ‰์…˜์„ ํ™•์‚ฐ(๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ตญ์—๋Š” ๊ตฌ์กฐํ™”)ํ•˜๋Š” ๊ฒƒ์€ Dart์™€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์œผ๋ฉฐ ์‹ค์ œ๋กœ ๊ตฌํ˜„๋  ํŒŒ์ดํ”„๋ผ์ธ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฐ์ฒด(JS์™€ ๋‹ฌ๋ฆฌ Maps์™€ ๊ฑฐ์˜ ๋™์ผํ•˜์ง€ ์•Š์Œ)๋ฅผ ํ™•์‚ฐ ๋ฐ ๊ตฌ์กฐ ํ•ด์ œํ•˜๋Š” ๊ฒƒ์€ ํ•ด๋‹น๋˜๋ฉฐ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” Dart(์˜ˆ๋ฅผ ๋“ค์–ด ์ ์ ˆํ•œ ์œ ํ˜• ์•ˆ์ „ ๋ฐฉ์‹์œผ๋กœ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์—†์Œ).

ํ˜„์žฌ Dart๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ƒ๊ฐํ•˜์ง€ ๋ง๊ณ  ๋‹ค๋ฅธ ๋ชจ๋“  ์–ธ์–ด์—์„œ ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๋ฅผ ์ทจํ•˜์—ฌ ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์ผ ์ˆ˜ ์žˆ๋Š”์ง€์— ์ง‘์ค‘ํ•˜์‹ญ์‹œ์˜ค.

ํ™•์‹ ํ•˜๋Š”. ๊ทธ๋Ÿฌ๋‚˜ Dart๊ฐ€ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด ์ค‘์—์„œ ๊ฐœ์ธ์ ์œผ๋กœ JS๋Š” ๋ชฉ๋ก์—์„œ ๊ทธ๋‹ค์ง€ ๋†’์€ ์ˆœ์œ„๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์†”์งํžˆ ๋งํ•ด์„œ JS(์ƒํ˜ธ ์šด์šฉ์„ฑ์„ ์œ„ํ•ด)๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์ดˆ๊ธฐ์— Dart๊ฐ€ ๋ถˆ๊ตฌ๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก  UI DSL์„ ์›ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ DSL์€ _Dart_์—๊ฒŒ ๊ด€์šฉ์ ์ด์–ด์•ผ ํ•˜๋ฉฐ, ์ธ๊ธฐ ๋•Œ๋ฌธ์— ์˜๋ฏธ๋ก ์ ์œผ๋กœ ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ ์™„์ „ํžˆ ์ œ๊ฑฐ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์–ธ๊ธ‰๋œ ์ด์  ์ค‘ ์ผ๋ถ€๋Š” ์‹ค์ œ๋กœ ์œ„์žฅ๋œ ์–ธ์–ด ์ˆ˜์ค€ ๊ธฐ๋Šฅ ์š”์ฒญ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ๋žŒ๋“ค์ด Javascript์™€ JSX DSL์„ ํ˜ผ๋™ํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ํ™•์‚ฐ ์—ฐ์‚ฐ์ž๋ฅผ ๊ณ„์†ํ•˜๋ ค๋ฉด Dart๊ฐ€ ์‹ค์ œ๋กœ JS์—์„œ์™€ ๊ฐ™์ด ์ „์ฒด ์—ฐ์‚ฐ์ž ๋ฒ”์œ„๋ฅผ ์ง€์›ํ–ˆ๋‹ค๋ฉด return SomeWidget(...someArgs, arg: newValue); return <SomeWidget {...someArgs, arg: newValue } />; ๋ฅผ ์ฝ๋Š” ๊ฒƒ์ด ๋” ๋‚˜์€์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” SGML์— ๋Œ€ํ•œ ์ฒจ๋ถ€ ํŒŒ์ผ์ด ์—†๋Š” ํ•œ QML๊ณผ ์œ ์‚ฌํ•œ return SomeWidget { ...someArgs, arg: newValue }; ์ž…๋‹ˆ๋‹ค.

@filleduchaos

ํŠนํžˆ ์–ธ์–ด์™€ ๊ฐ•๋ ฅํ•œ ๊ด€๊ณ„๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์ด ๊ตฌ๋ฌธ์€ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค๋ฅธ ๊ตฌ๋ฌธ์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? (Android SDK์™€ ํ•จ๊ป˜ Java์™€ XML์€ ์ˆ˜๋…„๊ฐ„ ๊ด€๊ณ„๋ฅผ ์œ ์ง€ํ•ด ์™”์Šต๋‹ˆ๋‹ค. JSX์™€ ๋งค์šฐ ์œ ์‚ฌํ•œ Javascript ๋ฐ HTML๊ณผ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ œ์•ˆ๋œ DSX๋Š” ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” SGML ๊ตฌ๋ฌธ์„ ๋‹ค๋ฅธ ์–ธ์–ด์— ๋Œ€ํ•ด ์˜๋ฏธ๊ฐ€ ์žˆ์ง€๋งŒ ๋ฐ˜๋“œ์‹œ Dart์— ๋Œ€ํ•ด์„œ๋Š” ๊ทธ๋ ‡์ง€๋Š” ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

์„œ๋กœ ์–ด์šธ๋ฆฐ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ๋“ค์„ ์ง์ง“๊ธฐํ•˜์ง€ ๋ง๊ณ (๊ทธ๋ฆฌ๊ณ  ๊ด€๊ณ„๋ฅผ ์œ ์ง€ํ•˜์‹ญ์‹œ์˜ค) ์–ด๋””์—์„œ ์™”๋Š”์ง€์— ๊ด€๊ณ„์—†์ด ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๋ฅผ ์„ ํƒํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•˜์‹ญ์‹œ์˜ค. ๋‹น์‹ ์€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๋•Œ ์ธ์œ„์ ์œผ๋กœ ๋ฌผ๊ฑด์„ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

JSX ๊ตฌ๋ฌธ์„ ์„ ํƒํ•˜๋Š” ์ด์œ ๋Š” React์—์„œ ์ž˜ ์ธ์‹๋˜๊ณ  React ์‚ฌ๋žŒ๋“ค์ด ๊ธฐ๋Œ€ํ•˜๊ณ  ์›ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ํ‹ฐ์ผ“์€ ๊ทธ๊ฒƒ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋‹น์‹ ์„ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

์ด ๋‘ ์ง„์ˆ ์„ ๋ณ‘์น˜๋กœ ๋ณด๋Š” ๊ฒƒ์€ ๋‹ค์†Œ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ๋“ค์€ ๋‹จ์ง€ ์ œ ์š”์ ์„ ์ฆ๋ช…ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. JSX๋Š” ํŠนํžˆ ๋‹จ์ˆœ์„ฑ ๋•Œ๋ฌธ์— (Javascript์˜ ๊ฒฝ์šฐ) ํ›Œ๋ฅญํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ JS ์–ธ์–ด ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ๋‹จ์ˆœํ•œ ์„คํƒ•์ผ ๋ฟ์ด๋ฉฐ ์‹ค์ œ๋กœ ํŠน๋ณ„ํ•œ ์˜๋ฏธ ์ž์ฒด๋ฅผ ๊ตฌํ˜„ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๊ทธ ๋‹จ์ˆœํ•จ์„ ์˜ณ๊ฒŒ ์นญ์ฐฌํ•œ ๋‹ค์Œ DSX๊ฐ€ 1) ์–ผ๋งˆ๋‚˜ ๋” ๋งŽ์€ ์ž‘์—…์„ ์š”๊ตฌํ•ด์•ผ ํ•˜๋Š”์ง€, 2) DSX๊ฐ€ ๋ชฉํ‘œ ์–ธ์–ด์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์˜๋ฏธ๋ก ์„ ์ž์ฒด์ ์œผ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•˜์ง€๋งŒ ๊ฐ•๋ ฅํ•œ DSL.

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

์ด์ „์— ๊ท€ํ•˜์˜ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๋ฅผ ๋ณธ ์ ์ด ์žˆ์œผ๋ฉฐ ์ธ์ƒ์ ์ธ ์ž‘์—…์ด์ง€๋งŒ Javascript๋ฅผ ์–ธ์–ด๋กœ(๋”ฐ๋ผ์„œ JSX) ๊ธฐ๋ณธ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์ „ํ˜€ ๊ทผ์ ‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

DSX์— ๋Œ€ํ•œ ํ™•์‚ฐ ์— ๋Œ€ํ•œ ๋‚˜์˜ ์˜๋„๋Š” ํ™•์‚ฐ์˜ ์™„์ „ํ•œ JS ๊ตฌํ˜„์ด ์•„๋‹ˆ๋ผ ์†์„ฑ์„ ํ™•์‚ฐํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๊ทธ๋Œ€๋กœ ์ž˜ ์ž‘๋™ํ•˜๋ฉฐ ์œ ํ˜• ์•ˆ์ „ ๋ฌธ์ œ๊ฐ€ ์ „ํ˜€ ์—†์Šต๋‹ˆ๋‹ค. ์œ ํ˜• ๊ฒ€์‚ฌ/์ •ํ™•์„ฑ์€ Dart๊ฐ€ DSX๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์ปดํŒŒ์ผํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ดˆ๊ธฐ์— ๋‹คํŠธ๋ฅผ ๋ถˆ๊ตฌ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐ์— Dart๋ฅผ ๋ฐฉํ•ดํ•œ ๊ฒƒ์€ ๊ฐ„๋‹จํ•œ JS ์ƒํ˜ธ ์šด์šฉ์„ฑ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ Dart ์ฝ”๋“œ์™€ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค(๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€). ๋˜ํ•œ ์ด๊ฒƒ์€ Dart๊ฐ€ ์‹คํŒจํ•œ ๊ณณ์—์„œ Typescript๊ฐ€ ์„ฑ๊ณตํ•œ ๊ฒƒ๊ณผ ๋˜‘๊ฐ™์€ ์ด์œ ์ž…๋‹ˆ๋‹ค.

๋ฌผ๋ก  UI DSL์„ ์›ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ DSL์€ ์ธ๊ธฐ ๋•Œ๋ฌธ์— ์˜๋ฏธ๋ก ์ ์œผ๋กœ ๋‹ค๋ฅธ ์–ธ์–ด์—์„œ ์™„์ „ํžˆ ์ œ๊ฑฐ๋˜์–ด์„œ๋Š” ์•ˆ๋˜๋ฉฐ Dart์—๊ฒŒ ๊ด€์šฉ์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ธ๊ธฐ๊ฐ€ ๋ชจ๋“  ๊ฒƒ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๋Š” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ ์ด์ ์„ ๋†’์ด ํ‰๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์ค‘ํ™”๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์–ธ๊ธ‰๋œ ์ด์  ์ค‘ ์ผ๋ถ€๋Š” ์‹ค์ œ๋กœ ์œ„์žฅ๋œ ์–ธ์–ด ์ˆ˜์ค€ ๊ธฐ๋Šฅ ์š”์ฒญ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ๋žŒ๋“ค์ด Javascript์™€ JSX DSL์„ ํ˜ผ๋™ํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.

Google(Dart/Flutter) ์ง์›์—๊ฒŒ ์ •๋ง ํ•„์š”ํ•œ ๊ฒƒ์€ ์†Œ์Šค ๋งต์„ ํ†ตํ•œ ์ผ๋ฐ˜์ ์ธ ํŠธ๋žœ์ŠคํŒŒ์ผ๋ง ์ง€์›์œผ๋กœ, Dart/Flutter๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๋” ๋†’์€ ์ˆ˜์ค€์˜ ์–ธ์–ด๋ฅผ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ณ  ํ˜„์žฌ ๋„๊ตฌ(IDE, ๋””๋ฒ„๊ฑฐ ๋“ฑ)์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. . ๊ฒฝ์Ÿ์˜ ์žฅ์„ ํ‰์ •ํ•˜๋ฉด ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋กœ๋ถ€ํ„ฐ ํ”Œ๋žซํผ์œผ๋กœ ๋‚˜์˜ฌ ๊ฒƒ์ž„์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

@cbazza

JSX ๊ตฌ๋ฌธ์„ ์„ ํƒํ•˜๋Š” ์ด์œ ๋Š” React์—์„œ ์ž˜ ์ธ์‹๋˜๊ณ  React ์‚ฌ๋žŒ๋“ค์ด ๊ธฐ๋Œ€ํ•˜๊ณ  ์›ํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ํ‹ฐ์ผ“์€ ๊ทธ๊ฒƒ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋‹น์‹ ์„ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋ฉด ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

๊ทธ๊ฒƒ์€ ์˜คํžˆ๋ ค ๋ถ„์—ด์ ์ด๋ฉฐ ๋‚˜์—๊ฒŒ ์ƒ๋‹นํ•œ ์ž๊ฒฉ์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Flutter๊ฐ€ ํŠน์ • React ๊ตฌ๋ฌธ์— ๋Œ€ํ•ด ์ผ๋ฅ˜ ์ง€์›์„ ์ œ๊ณตํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? Vue ๊ตฌ์„ฑ ์š”์†Œ ํŒŒ์ผ ๋˜๋Š” Xamarin.Forms ๊ตฌ๋ฌธ์ด ์•„๋‹Œ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? Flutter์šฉ (์•„๋งˆ๋„ ๊ณต์‹) UI DSL์ด ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŠน์ • ์‚ฌ๋žŒ๋“ค์ด ๊ธฐ๋Œ€ํ•˜๊ณ  ์›ํ•˜๋Š” ๊ฒƒ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? React/JS ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋„๊ตฌ๋ฅผ ์›ํ•˜์‹ ๋‹ค๋ฉด ๊ทธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ”„๋ ˆ์ž„์›Œํฌ ์ž์ฒด์— ์˜ค๋กœ์ง€ ์—ฌ๋Ÿฌ๋ถ„ ๋ชจ๋‘๋ฅผ ์ˆ˜์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ๊ฒƒ์„ ํฌํ•จํ•˜๋„๋ก ์š”๊ตฌํ•˜๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„ ๋งŽ์€ IMO์ž…๋‹ˆ๋‹ค.

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

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

DSX์— ๋Œ€ํ•œ ํ™•์‚ฐ ์— ๋Œ€ํ•œ ๋‚˜์˜ ์˜๋„๋Š” ํ™•์‚ฐ์˜ ์™„์ „ํ•œ JS ๊ตฌํ˜„์ด ์•„๋‹ˆ๋ผ ์†์„ฑ์„ ํ™•์‚ฐํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๊ทธ๋Œ€๋กœ ์ž˜ ์ž‘๋™ํ•˜๋ฉฐ ์œ ํ˜• ์•ˆ์ „ ๋ฌธ์ œ๊ฐ€ ์ „ํ˜€ ์—†์Šต๋‹ˆ๋‹ค. ์œ ํ˜• ๊ฒ€์‚ฌ/์ •ํ™•์„ฑ์€ Dart๊ฐ€ DSX๊ฐ€ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์ปดํŒŒ์ผํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ „ํ˜€ ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋งŒ "์œ ํ˜• ์•ˆ์ „ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค". ๋‚ด๊ฐ€ ๋งํ•œ ๊ฒƒ์€ ์ธ์ˆ˜ ๋งต์ด Dart ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„๊ณผ ์™„์ „ํžˆ ์•ˆ์ „ํ•œ ๋ฐฉ์‹์œผ๋กœ _์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ_์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ์•„๋งˆ๋„ JavaScript์—์„œ ์†Œํ’ˆ ๋“ฑ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ด๋Ÿฌํ•œ ์ธ์ˆ˜์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œ„์ ฏ, ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ ๋“ฑ - ํ•œ ๊ณณ์—์„œ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ผ๋ฐ˜์ ์ธ ์ƒ์„ฑ์ž ํ˜ธ์ถœ์— ๋Œ€ํ•œ ์š”์ ์ด ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋‚ด ๋ง์„ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด JS์—์„œ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

class MyCustomSize {
  constructor(length, width, height) {
    this.length = length;
    this.width = width;
    this.height = height;
    this.calculateVolume.bind(this);
  }

  calculateVolume() {
    return this.length * this.width * this.height;
  }
}

const Cuboid = ({ length, width, height }) => { // blah blah }

const literalSize = { 'length': 30, 'width': 20, 'height': 10 };
const size = new MyCustomSize(30, 20, 10);

size.length = 100; // Can interact with the object as normal, no compromises
console.log(size.getVolume()); // and even call methods
size.foo = 50 // If you're using TypeScript, you get a nice error
literalSize.height = 15 // can interact with the hashmap as though it were an object

const SomeComponent = () => (
  <div>
    <Cuboid {...literalSize} />{/* valid */}
    <Cuboid {...size} />{/* also valid even though size is an object */}
  </div>
)

๊ทธ๋Ÿฌ๋‚˜ Dart์™€ ์ธ์ˆ˜์˜ ํ•ด์‹œ๋งต์ด ํ•„์š”ํ•œ ๋ณ€ํ™˜๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฉ๋‹ˆ๋‹ค.

class MyCustomSize {
  int length, width, height;

  MyCustomSize(this.length, this.width, this.height);

  calculateVolume() {
    return length * width * height;
  }
}

class Cuboid extends StatelessWidget {
  final int length, width, height;

  Cuboid(this.length, this.width, this.height);

  <strong i="9">@override</strong>
  Widget build(BuildContext context) { // blah }
}

Map literalSize = { 'length': 30, 'width': 20, 'height': 10 };
Map invalidSize = { 'length': 300, 'width': 200, 'height': 100 };
final size = MyCustomSize(30, 20, 10);

literalSize.height = 15; // Invalid, you must use square bracket notation which is honestly ugly to do a lot of the time
invalidSize['foo'] = 50; // No indication of anything wrong here

class SomeWidget extends StatelessWidget {
  <strong i="10">@override</strong>
  Widget build(BuildContext context) {
    return (
      <Column>
        <Cuboid {...literalSize} />{/* Yes, works */}
        <Cuboid {...invalidSize} />{/* Sure the transpiled code errors as there is no parameter named foo. But this is now a completely opaque error. What if the `foo:50` key-value pair was added in some other section of your codebase? In a third party library even? How do you debug that*/}
        <Cuboid {...size} />{/* How do you plan on handling this as a plain transpilation step? */}
      </Column>
    )
  }
}

์ดˆ๊ธฐ์— Dart๋ฅผ ๋ฐฉํ•ดํ•œ ๊ฒƒ์€ ๊ฐ„๋‹จํ•œ JS ์ƒํ˜ธ ์šด์šฉ์„ฑ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ Dart ์ฝ”๋“œ์™€ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค(๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€). ๋˜ํ•œ ์ด๊ฒƒ์€ Dart๊ฐ€ ์‹คํŒจํ•œ ๊ณณ์—์„œ Typescript๊ฐ€ ์„ฑ๊ณตํ•œ ๊ฒƒ๊ณผ ๋˜‘๊ฐ™์€ ์ด์œ ์ž…๋‹ˆ๋‹ค.

Dart์™€ JS์˜ ์ƒํ˜ธ ์šด์šฉ์€ ๊ฒฐ์ฝ” ๋ณต์žกํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์ด ์ œ๊ฐ€ ๊ณ„์† ๊ฐ•์กฐํ•˜๋Š” ์ ์ž…๋‹ˆ๋‹ค) ๋‹จ์ˆœํžˆ Javascript๋ฅผ ์ž‘์„ฑ ํ•˜๊ณ  ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์„ ์‹ซ์–ดํ•˜์ง€ ์•Š๋Š” ํ•œ. Typescript๊ฐ€ ์ƒ์œ„ ์ง‘ํ•ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— JS์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋‹ค์ง€ ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. JS์— ๋งž์ถ”๊ธฐ ์œ„ํ•ด ์˜๋„์ ์œผ๋กœ ๋ถˆ๊ฑด์ „ํ•œ ์œ ํ˜• ์‹œ์Šคํ…œ์„ ๊ฐ–์ถœ ์ •๋„์ž…๋‹ˆ๋‹ค. ๋นŒ์–ด๋จน์„ ๋ถ€๋„๋Ÿฌ์šด ์ด ๋ช‡ ๋…„ ๋™์•ˆ). ํ•˜์ง€๋งŒ ์ œ ์š”์ ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ ๊ฐœ์ธ์ ์œผ๋กœ Dart๋Š” JS๋ฅผ ์œ„ํ•ด ์ƒ๋‹นํžˆ ์ž˜๋ชป๋œ ๋””์ž์ธ ๊ฒฐ์ •์„ ๋‚ด๋ ธ๊ณ  Dart 2๋Š” ์‹ค์ œ๋กœ ์–ธ์–ด์˜ ์ฒซ ๋ฒˆ์งธ ๋ฐ˜๋ณต์ด์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ธ๊ธฐ๊ฐ€ ๋ชจ๋“  ๊ฒƒ์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๋Š” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ ์ด์ ์„ ๋†’์ด ํ‰๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์ค‘ํ™”๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค.

"Best" ๋˜๋Š” ์˜คํžˆ๋ ค ์ข‹์€ ์•„์ด๋””์–ด๋Š” ์žฅ์  ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์€ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. ์ธ๊ธฐ๊ฐ€ ์žˆ์„ ๋•Œ๋„ ์žˆ๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์„ ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์œ ์•„์ด๋””์–ด๊ฐ€ ์ธ๊ธฐ๋ฅผ ๋Œ ๋•Œ๋„ ์žˆ์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์„ ๋•Œ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๊ธฐ๊ฐ€ ์žฅ์ ์˜ ์ง์ ‘์ ์ธ ์ง€ํ‘œ๋ผ๊ณ  ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์€ ์†”์งํžˆ ํ„ฐ๋ฌด๋‹ˆ์—†์œผ๋ฉฐ ๊ฐœ์ธ์ ์œผ๋กœ ์ž‘์€ ๊ทœ๋ชจ์˜ Dart ์ปค๋ฎค๋‹ˆํ‹ฐ์— ํผ์ง€์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ผ๋Š” ํƒœ๋„์ž…๋‹ˆ๋‹ค.

Google(Dart/Flutter) ์ง์›์—๊ฒŒ ์ •๋ง ํ•„์š”ํ•œ ๊ฒƒ์€ ์†Œ์Šค ๋งต์„ ํ†ตํ•œ ์ผ๋ฐ˜์ ์ธ ํŠธ๋žœ์ŠคํŒŒ์ผ๋ง ์ง€์›์œผ๋กœ, Dart/Flutter๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๋” ๋†’์€ ์ˆ˜์ค€์˜ ์–ธ์–ด๋ฅผ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ณ  ํ˜„์žฌ ๋„๊ตฌ(IDE, ๋””๋ฒ„๊ฑฐ ๋“ฑ)์—์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. . ๊ฒฝ์Ÿ์˜ ์žฅ์„ ํ‰์ •ํ•˜๋ฉด ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋กœ๋ถ€ํ„ฐ ํ”Œ๋žซํผ์œผ๋กœ ๋‚˜์˜ฌ ๊ฒƒ์ž„์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

...๋‹น์‹ ์ด ์ „๋ณด๋‹ค ๋” ๋งŽ์€ ์ž๊ฒฉ์„ ๊ฐ–๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์•˜์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ ์ด ํ•˜๋‚˜์˜ UI SDK๊ฐ€ ์ „ ์„ธ๊ณ„์˜ ๋ชจ๋“  ๊ณ ๊ธ‰ ์–ธ์–ด์—์„œ ํƒ€๊ฒŸํŒ…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ œ์•ˆ์€ "Dart/Flutter๋ฅผ ๋‚ด ์–ธ์–ด/ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ๋งŒ๋“ค๊ธฐ"๋กœ ๊ฐ•๋ ฅํ•˜๊ฒŒ ๋‚˜์˜ต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ๋‚˜์™€์„œ Javascript๋กœ Flutter ์•ฑ์„ ๋นŒ๋“œํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๋งํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋„ค, ๋‹น์‹ ์˜ ํŒ”๊ฟˆ์น˜์— ๋” ๋งŽ์€ ๊ธฐ๋ฆ„์„ ๋ฐ”๋ฅด๊ณ  ์ €๋Š” ๊ทธ๋Ÿฐ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๋Š” ๋ฐ ๋ชจ๋‘ ๊ธฐ์—ฌํ•˜๊ฒ ์ง€๋งŒ, ๊ณต์‹์ ์ธ ์ง€์›์„ ์š”์ฒญํ–ˆ์„ ๋•Œ ๊ธ์ •์ ์ธ ๋Œ€๋‹ต์„ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ์€ ์†”์งํžˆ ๋ง๋„ ์•ˆ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” UI DSL์— ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๊ณ  ์‹ค์ œ๋กœ ๊ทธ๊ฒƒ์„ ์ข‹์•„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŒ€์— ๊ตฌ์›Œ๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•œ๋‹ค๋ฉด Dart์— ๊ด€์šฉ์ ์ธ DSL์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ, ์‹ค์ œ๋กœ Dart๋ฅผ ์–ธ์–ด๋กœ ์ข‹์•„ํ•˜๋Š” ์ˆ˜์‹ญ ๋ช…์˜ ์‚ฌ๋žŒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ํŽธ์ง‘: DSL์„ ์š”์ฒญํ•˜๊ณ , JSX๋ฅผ ๊ฐ€๋Šฅํ•œ ๊ตฌ๋ฌธ/๊ตฌ๋ฌธ ์˜๊ฐ์œผ๋กœ ์ œ์•ˆํ•˜๊ณ , ๋‹ค๋ฅธ ์ œ์•ˆ์— ์—ด๋ ค ์žˆ๋Š” ๊ฒƒ์ด ํ•œ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ๋‚˜๋ฅผ ๋ฌธ์ง€๋ฅด๋Š” ๊ฒƒ์€ DSX ์— ๋Œ€ํ•œ ์ฃผ์žฅ์ž…๋‹ˆ๋‹ค.

@filleduchaos

๋‹น์‹ ์€ ์šฐ์Šค๊ฝ์Šค๋Ÿฝ๊ฒŒ ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œํ•˜๊ณ  ๋‚˜๋Š” ์•„์ง ๋‚ญ๋น„ํ•  ์‹œ๊ฐ„์ด ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ Dart/Flutter ํŒ€์—๊ฒŒ ๋ฌป๊ณ  ์‹ถ์€ ๊ฒƒ์€ ๋‚ด๊ฐ€ ์ „์— ๋งํ•œ ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค.

What we really need from Google (Dart/Flutter) people is generic transpiling support via source maps so that any higher level language can be developed that targets Dart/Flutter and it would work just fine with the current tools (IDE, debugger, etc). Level the playing field and you guarantee the best ideas will come to the platform from others.

์ด๋Š” DSX, Vue ๊ตฌ์„ฑ ์š”์†Œ ํŒŒ์ผ, Xamarin.Forms, NativeScript, QML ๋“ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์ œ๊ณตํ•˜๋ฏ€๋กœ ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์›ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์ œ์‹œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์•„๋ฌด๋„ ๋‚ด DSX๋ฅผ '์ทจ๊ธ‰'ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. DSX๊ฐ€ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์œผ๋ฉด ์ผ๋ฐ˜ Dart๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์‰ฝ๊ฒŒ ์ž์‹ ๋งŒ์˜ ๊ฒƒ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://github.com/dart-lang/build ๋ฐ dartanalyzer์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ฐพ๊ณ  ์žˆ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
๋ถ„์„๊ธฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ pub ์ข…์†์„ฑ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ธฐ๋Šฅ๊ณผ ๊ฐ™์€ ํ•œ๋‘ ๋ถ€๋ถ„์„ ๋†“์น  ์ˆ˜ ์žˆ์ง€๋งŒ Dart ํŒ€์ด ์ด๋ฅผ ์ž˜ ๋„์™€์ค„ ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

์–ด์จŒ๋“  ๊ณ„์†ํ•ด์„œ ์„œ๋กœ์—๊ฒŒ ๊ฐ€ํ˜นํ•œ ํ–‰๋™์„ ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋–ค ์‹์œผ๋กœ๋“  ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋ฐœ์ „์— ๋„์›€์ด ๋  ๊ฒƒ์ด๋ผ๊ณ ๋Š” ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
์ด ๋ฌธ์ œ์—์„œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋Œ€๋ถ€๋ถ„์€ "๋„ˆ๋ฌด ๋œจ๊ฑฐ์›Œ์กŒ๊ธฐ" ๋•Œ๋ฌธ์— ์˜๊ตฌ์ ์œผ๋กœ ๋‹ซํžŒ ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

@filleduchaos

'foo' ์˜ˆ์™€ ๊ด€๋ จํ•˜์—ฌ DSX ์Šคํ”„๋ ˆ๋“œ ๋Š” ์ปดํŒŒ์ผ ์‹œ๊ฐ„์ด๋ฏ€๋กœ ๋งต์€ const ๋กœ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ DSX ํ‚ค์›Œ๋“œ ๋˜๋Š” ์ด์— ๋Œ€ํ•œ ์ฃผ์„ ๋’ค์— const ๋งต). Dart๋Š” ๋Ÿฐํƒ€์ž„์— ๋™์  ์ƒ์„ฑ์ž ๋งค๊ฐœ๋ณ€์ˆ˜ ์‚ฝ์ž…์„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋Ÿฐํƒ€์ž„์ด ์•„๋‹Œ ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฌธ์ œ, ์ฆ‰ ์ƒ์„ฑ์ž์— ์†์„ฑ์„ ํผ๋œจ๋ฆฌ๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

@cbazza ์š”์ ์€ JS/JSX์—์„œ ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž๋ฅผ ๋งค์šฐ ํŽธ๋ฆฌํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ถ€๋ถ„์€ "ํ•ด์‹œ๋งต๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ" ๋˜๋Š” "์ปดํŒŒ์ผ ์‹œ ๋ชจ๋“  ์ธ์ˆ˜๋ฅผ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค"์™€ ๊ฐ™์€ ์ œํ•œ์„ ๋ถ€๊ณผํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜๋Š” "๋‹ค๋ฅธ ๋ชจ๋“  ๊ฒƒ๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์œ„์ ฏ์— ์ „๋‹ฌํ•˜๋ ค๋Š” ์ธ์ˆ˜/์†Œํ’ˆ๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค"(์†์„ฑ์ด ์žˆ๋Š” ํ•ญ๋ชฉ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ฌด ๊ฒƒ๋„ ์ œ์•ˆํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. need๋Š” ์‹ค์ œ๋กœ ๋งต ๋ฆฌํ„ฐ๋Ÿด์ด ์•„๋‹ˆ๋ผ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.) -0 ๊ฐ„๋‹จํ•œ ์˜ˆ์ผ ๋•Œ๋Š” ๋ชจ๋‘ ํ›Œ๋ฅญํ•˜์ง€๋งŒ, ์ค‘๊ฐ„ ๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ๊ทธ๋Ÿฐ ์ข…๋ฅ˜์˜ ์ผ์€ ๋งค์šฐ ์‹ค๋ง์Šค๋Ÿฌ์šด _๋น ๋ฅธ_ ์ผ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ œ ๋ง์€, ์–ด๋Š ์‹œ์ ์—์„œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•, ํƒ€ํ˜‘ ๋ฐ ์ฃผ์„์— ๋Œ€ํ•œ ์Œ“์ด๋Š” ๊ฒƒ์„ ๋ฉˆ์ถ”๊ณ  ํ•œ ๊ฑธ์Œ ๋ฌผ๋Ÿฌ๋‚˜์„œ ํ™•์žฅ ๊ธฐ๋Šฅ์ด ์‹ค์ œ๋กœ ์กด์žฌํ•˜๋Š” ์–ธ์–ด์— ์ ํ•ฉํ•œ์ง€ ๊ถ๊ธˆํ•ดํ•ฉ๋‹ˆ๊นŒ?

JSX๋Š” (๋Œ€๋ถ€๋ถ„์˜ ํ…œํ”Œ๋ฆฟ๊ณผ ๋น„๊ตํ•˜์—ฌ) ๋งค์šฐ ์„ฑ๊ณต์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ๋ฐฉ์‹์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๋„๋ก ๊ฐ•์š” ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. _any_ JavaScript์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ฑฐ์˜ ์™„์ „ํžˆ ๊ณ ํ†ต์Šค๋Ÿฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ ์–ธ์–ด์— ๋งž๋Š” DSL์„ ์ƒ์„ฑํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. Redux๋„ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. JS ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ Redux๋Š” ์•„๋ฆ„๋‹ค์šด ๊ฒƒ์ž…๋‹ˆ๋‹ค(์ ์ ˆํ•˜๊ฒŒ ์‚ฌ์šฉ๋  ๋•Œ). ๋ฐ˜๋ฉด์— Redux๋ฅผ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜์—ฌ ๋ณธ ๋ชจ๋“  Flutter ์˜ˆ์ œ๋Š” Streams/BLoC ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋น„๊ตํ•  ๋•Œ ์†”์งํžˆ ๊ณ ํ†ต์Šค๋Ÿฌ์›Œ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ํ•ด์„œ ํฐ ์„ฑ๊ณต๊ณผ ๊ฒน์น˜๋Š” ๋ถ€๋ถ„์ด ์—†๋‹ค๋Š” ๋ง์€ ์•„๋‹™๋‹ˆ๋‹ค. React์˜ Context ์™€ Flutter์˜ InheritedWidget ๋Š” ๋‘ ๊ฐ€์ง€ ์žฅ์ ์„ ๋ชจ๋‘ ์ˆ˜์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ณตํ†ต ๊ฐœ๋…์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. JSX๊ฐ€ ํ˜„์žฌ ๊ทธ๋Ÿฌํ•œ ๊ฒƒ๋“ค ์ค‘ ํ•˜๋‚˜๋ผ๊ณ  ํ™•์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์–ธ์–ด ์ˆ˜์ค€์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ œ์™ธํ•˜๊ณ  ์†”์งํžˆ DSX๋Š” ๊ฐœ๋ฐœํ•˜๊ธฐ ํž˜๋“  _๊ทธ๋ฆฌ๊ณ _ ์‚ฌ์†Œํ•œ ์˜ˆ์ œ ์ด์ƒ์— ์‚ฌ์šฉํ•˜๋Š” ๊ณ ํ†ต์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์•„๋งˆ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. JS์— ๋งคํ•‘ํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ๊ฐ„๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฒŒ์œผ๋ฅธ ์ฃผ๋ง์— ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ธฐ๋Šฅ์ด ์™„๋ฒฝํ•œ JSX ๋ณ€ํ™˜๊ธฐ.

๊ทธ๋ฆฌ๊ณ  ์ œ๊ฐ€ ์ข€ ๋” ์ผ์ฐ ๊ณต๊ฒฉ์ ์ด์—ˆ๊ณ  ์‚ฌ๊ณผ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

@filleduchaos

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

์Šคํ”„๋ ˆ๋“œ ์ปฌ๋ ‰์…˜
https://github.com/dart-lang/language/issues/47

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

@cbazaa React Native๋ฅผ ์‚ฌ์šฉํ• ์ง€ Flutter๋ฅผ ์‚ฌ์šฉํ• ์ง€ ํ‰๊ฐ€ ์ค‘์ž…๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋‚ด UI ์˜คํƒ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ชจ๋“  ๊ฒƒ์ด Dart์ด๊ธฐ ๋•Œ๋ฌธ์— Flutter์— ๊ธฐ๋Œ€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ์กฐ: https://medium.com/flutter-io/out-of-depth-with-flutter-f683c29305a8

JSX๋Š” ๋‚ด ์˜คํƒ€๋„ ๊ฐ์ง€ํ•ฉ๋‹ˆ๊นŒ? ์ €๋Š” TypeScript๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

HTML/๋ณ„๋„์˜ ๋งˆํฌ์—…์„ ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Angular์—์„œ HTML์—์„œ ๋ฌด์–ธ๊ฐ€/๋ณ€์ˆ˜๋ฅผ ์ž˜๋ชป ์ž…๋ ฅํ•˜๋ฉด ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋งํ•œ ํ›„์—๋งŒ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

@sivabudh

JSX๋Š” ๋‚ด ์˜คํƒ€๋„ ๊ฐ์ง€ํ•ฉ๋‹ˆ๊นŒ? ์ €๋Š” TypeScript๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ์ผ๋ถ€ JSX ์˜คํƒ€๋Š” ์ปดํŒŒ์ผ ์‹œ๊ฐ„(์˜ˆ: ๊ตฌ์„ฑ ์š”์†Œ ์ด๋ฆ„)์— ํฌ์ฐฉ๋˜์ง€๋งŒ JS/ES6์„ ์‚ฌ์šฉํ•  ๋•Œ ์†Œํ’ˆ ์ด๋ฆ„(๋Ÿฐํƒ€์ž„์— ํฌ์ฐฉ๋จ)์€ ํฌ์ฐฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ํ˜• ์‹œ์Šคํ…œ์€ ์ปดํŒŒ์ผ ํƒ€์ž„์— ๋ชจ๋“  JSX ์˜คํƒ€๋ฅผ ํฌ์ฐฉํ•ฉ๋‹ˆ๋‹ค.
https://www.typescriptlang.org/docs/handbook/jsx.html

@cbazza ๋Š” dsx ์˜คํ”ˆ ์†Œ์Šค์ž…๋‹ˆ๊นŒ?

@pushqrdx
์•„์ง ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๊ณต๊ฐœํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

React + TypeScript ๋ฐ Flutter์˜ ์†Œ๋น„์ž๋กœ์„œ ์ €๋Š” ์Šค์Šค๋กœ๋ฅผ ํ…Œ์Šคํ„ฐ๋กœ ์ œ์•ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฑด๋ฐฐ

dsx ์†Œ์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„์ฃผ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

cbazza์˜ ๋…ธ๋ ฅ์— ๋ฐ•์ˆ˜๋ฅผ ๋ณด๋‚ด์ง€๋งŒ Flutter์—์„œ DSX๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ํ…Œ์ŠคํŠธํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ #27141์€ ๋นŒ๋“œ ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ์ฝ”๋“œ ์ƒ์„ฑ ์ง€์› ์ถ”๊ฐ€๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ https://github.com/dart-lang/build with Builder ๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋ก ์ ์œผ๋กœ ์ด ๊ธฐ๋Šฅ์ด ์ค€๋น„๋˜๋ฉด dsx ์ปดํŒŒ์ผ๋Ÿฌ/ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ์ƒ๋‹นํžˆ ๊ฐ„๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

2ํšŒ๋งŒ์— ์ด๋ ‡๊ฒŒ ๋ˆ์งˆ๊ธด ํŒ€์€ ์ฒ˜์Œ ๋งŒ๋‚ฌ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ JSX์— ๋Œ€ํ•œ ํ† ๋ก ์ด ์•„๋‹ˆ๋ผ ์ค‘์ฒฉ ์ง€์˜ฅ์— ๋Œ€ํ•œ ํ† ๋ก ์ž…๋‹ˆ๋‹ค.

JSX ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋”๋ผ๋„ ์ค‘์ฒฉ์„ ์ค„์ด๊ณ  ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ๋†’์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

JSX์˜ ์žฅ์ ์€ ๋‹น์—ฐํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”๋ฐ ํ”Œ๋Ÿฌํ„ฐํŒ€์€ ์ด๋ฅผ ๊ฐ„๊ณผํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.

JSX๋Š” ์ค‘์ฒฉ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ๋ฌธ์ œ์— ์ง๋ฉดํ•œ ๋ฐ˜์‘

๊ทธ ๋„ค์ŠคํŒ…์ด ์‹ซ๋‹ค๋ฉด ๋„ค์ŠคํŒ… ์ง€์˜ฅ์„ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ์‹œ๋„์ธ React hooks์˜ ํฌํŠธ์ธ hooks ๋ฅผ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

JSX๊ฐ€ ๋“ฑ์žฅํ•œ ์ด์œ ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. h/createElement ํ•จ์ˆ˜๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘์„ฑ๋˜์ง€ ์•Š์•˜๊ณ  ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ์ข‹์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋œป๋ฐ–์—๋„ ์ด์ œ flutter๋Š” ๋ˆˆ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋Š” h/createElement ํ•จ์ˆ˜๋ณด๋‹ค 10,000๋ฐฐ ๋” ๋‚˜์˜๊ฒŒ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค.

JSX๋Š” React๊ฐ€ ํ•ต์‹ฌ์ ์œผ๋กœ Javascript์™€ HTML์˜ ํ˜ผํ•ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๊ฒจ๋‚ฌ์Šต๋‹ˆ๋‹ค. Javascript ๋ณด๊ฐ„/์‚ฝ์ž…์ด ํฌํ•จ๋œ XML ๊ตฌ๋ฌธ์€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ JSX๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Flutter๋Š” Javascript ๋ฐ HTML๊ณผ ์™„์ „ํžˆ ๋ณ„๊ฐœ์ด๋ฏ€๋กœ JSX๋กœ ์ž˜ ๋ณ€ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Flutter ํ”„๋กœ์ ํŠธ๋Š” ์ข…์ข… ๋งค์šฐ ์ค‘์ฒฉ๋˜์–ด ์žˆ์œผ๋ฉฐ ํŠนํžˆ dartfmt ๊ฐ€ ์ค‘์ฒฉ์ด ๋งŽ์ด ๋œ ๋ผ์ธ์„ ๋ถ€์ˆ˜๋Š” ๊ฒฝ์šฐ ์ •๋ง ๊ณ ํ†ต์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋”์ฐํ•˜๋‹ค.

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

์ค‘์ฒฉ ๋ฌธ์ œ๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”๋ฐ JSX๊ฐ€ ๋‹ต์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ์•„์ด๋””์–ด:

  1. ์‚ฌ๋žŒ๋“ค์ด ๊ฑฐ๋Œ€ํ•œ ํ”Œ๋Ÿฌํ„ฐ ํŠธ๋ฆฌ๋ฅผ ๋” ์ž‘์€ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ถ„ํ•ดํ•˜๋„๋ก ์š”๊ตฌํ•˜๋Š” ๋‚ด๋ถ€ ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ๋ฅผ ๊ฐœ๋ฐœํ•˜์‹ญ์‹œ์˜ค.

  2. dartfmt ๋ฅผ ์–ป์œผ๋ฉด Flutter๊ฐ€ Dart ํŒจํ‚ค์ง€์™€ ๋น„๊ตํ•  ๋•Œ ๊ณ ์œ ํ•œ ํ˜•์‹ํ™” ์š”๊ตฌ ์‚ฌํ•ญ์ด ์žˆ์Œ์„ ๊ณต์‹์ ์œผ๋กœ ์ธ์‹ํ•˜๊ณ  Flutter/Dart ํŒ€๊ณผ ํ˜‘๋ ฅํ•˜์—ฌ ํ•ฉ๋ฆฌ์ ์ธ ์†”๋ฃจ์…˜์„ ๋‚ด๋†“์Šต๋‹ˆ๋‹ค. @munificent

  3. @rrousselGit ์˜ @stateless ํŒจํ‚ค์ง€์™€ ๊ฐ™์€ ์ฝ”๋“œ ์ƒ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ 1๋ฒˆ์„ ๋” ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๊ณตํ‰ํ•˜๊ฒŒ, ์ค‘์ฒฉ ๋ฌธ์ œ๋Š” ์ฃผ๋กœ ์ฝ”๋“œ ๊ตด์ ˆ์„ ์›ํ•˜์ง€ ์•Š์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์œ„์ ฏ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ ์กฐ๊ฐ์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.
extract widget ๋ฆฌํŒฉํ† ๋ง ๋„๊ตฌ์˜ ์‚ฌ์šฉ ๋ฐ ๋‚จ์šฉ.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ํ›จ์”ฌ ๋” ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ณ  ์ค‘๋ณต์„ฑ์„ ์ค„์ด๋ฉฐ ์ž ์žฌ์ ์œผ๋กœ ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์„ฑ๋Šฅ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

JSX๋Š” React๊ฐ€ ํ•ต์‹ฌ์ ์œผ๋กœ Javascript์™€ HTML์˜ ํ˜ผํ•ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๊ฒจ๋‚ฌ์Šต๋‹ˆ๋‹ค. Javascript ๋ณด๊ฐ„/์‚ฝ์ž…์ด ํฌํ•จ๋œ XML ๊ตฌ๋ฌธ์€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ JSX๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

React Native๊ฐ€ JSX๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  HTML๊ณผ ๊ด€๋ จ์ด ์—†๋‹ค๋Š” ์‚ฌ์‹ค์„ ์–ด๋–ป๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๊นŒ?

React Native๊ฐ€ JSX๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  HTML๊ณผ ๊ด€๋ จ์ด ์—†๋‹ค๋Š” ์‚ฌ์‹ค์„ ์–ด๋–ป๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๊นŒ?

React๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์•„๋งˆ๋„ ๊ตฌ๋ฌธ์„ ์žฌ๋ฐœ๋ช…ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

React๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์•„๋งˆ๋„ ๊ตฌ๋ฌธ์„ ์žฌ๋ฐœ๋ช…ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ JSX๋Š” @lukepighetti ๊ฐ€ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์‹ค์ œ๋กœ Javascript์™€ HTML์˜ ํ˜ผํ•ฉ์ด ์•„๋‹ˆ๋ผ XML-like syntax extension to ECMAScript without any defined semantics... who's purpose is to define a concise and familiar syntax for defining tree structures with attributes. ์ž…๋‹ˆ๋‹ค.
์‚ฌ์–‘์— ๋ชจ๋‘ ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค. https://facebook.github.io/jsx/

๋‚ด๊ฐ€ ์•Œ๊ธฐ๋กœ๋Š” React๋Š” jsx ์ปดํŒŒ์ผ๋Ÿฌ์™€ ํ•จ๊ป˜ react + react-dom ๋กœ ์ฒ˜์Œ ์ถœ์‹œ๋˜์—ˆ์œผ๋ฏ€๋กœ HTML + JavaScript ํ˜ผํ•ฉ์ด ์ž์—ฐ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ๊ทธ ํ›„ react ๋Š” react-native , react-vr , react-pdf ๋“ฑ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ Œ๋”๋Ÿฌ๋ฅผ ๊ตฌ๋™ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. React์˜ ์—ญ์‚ฌ์™€ ํ˜ˆํ†ต์— ํ•ฉ๋ฆฌ์ ์ด๊ณ  ๋ฏผ๊ฐํ•ฉ๋‹ˆ๋‹ค. 2019๋…„ ์‚ฌ์–‘์€ 2019๋…„ ํ˜„์žฌ ์‚ฌ์–‘์ด๋ฉฐ React์˜ ์—ญ์‚ฌ๋ฅผ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋™์˜ํ•œ๋‹ค

๊ทธ๋Ÿฌ๋‚˜ ๋‚˜์—๊ฒŒ๋Š” ๋” ํฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Vue์™€ React๋Š” ๊ทธ ์ธก๋ฉด์—์„œ ์œ ์‚ฌํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
React์—๋Š” createElement ๊ฐ€ ์žˆ๊ณ  Vue์—๋Š” h ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

React์™€ Vue ๋ชจ๋‘์—์„œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ธ์Šคํ„ด์Šคํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ”„๋ ˆ์ž„ ์›Œํฌ์ž…๋‹ˆ๋‹ค.


Flutter๋Š” ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์œ„์ ฏ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ง์ ‘ ์กฐ์ž‘ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Flutter ์„ธ๊ณ„์—์„œ <Foo /> ๋Š” new Foo() ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด ๊ฒฝ์šฐ JSX๋Š” ์œ„์ ฏ๊ณผ ์ „ํ˜€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹จ์ง€ dart์—์„œ ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ๊ตฌ๋ฌธ์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์žˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ ์ด๊ฒƒ์€ ์œ„์ ฏ ์ƒ์„ฑ์˜ ์˜๋ฏธ๋ฅผ ์žƒ์–ด๋ฒ„๋ฆฐ ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

@lukepighetti
react-pdf ๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐ˜์‘ ๋ Œ๋”๋Ÿฌ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. react-canvas ๋ฅผ ์ƒ๊ฐํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ react != react-dom != react-native . react ํŒจํ‚ค์ง€๋Š” JSX ์˜ ๋„์›€์œผ๋กœ ๊ตฌ์„ฑ ์š”์†Œ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ react ๋Š” react-dom , react-native ์ƒ์„ฑ ์—ฌ๋ถ€๋ฅผ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. react-canvas , ๋”ฐ๋ผ์„œ react ๋Š” HTML์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

2019๋…„ ์‚ฌ์–‘์€ 2019๋…„ ํ˜„์žฌ ์‚ฌ์–‘์ด๋ฉฐ React์˜ ์—ญ์‚ฌ๋ฅผ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

JSX์˜ 2019 ์‚ฌ์–‘๊ณผ ๊ฐ™์€ ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค. JSX์˜ ๋ฒ„์ „์€ ๋‹จ ํ•˜๋‚˜์ด๋ฉฐ ์ œ๊ฐ€ ์ œ๊ณตํ•œ ๋งํฌ(https://facebook.github.io/jsx/)์—์„œ 2014๋…„์— ๊ฒŒ์‹œ๋œ ์›๋ณธ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

@rrousselGit

์šฐ๋ฆฌ๋Š” ๋‹จ์ง€ dart์—์„œ ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ๊ตฌ๋ฌธ์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์žˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค.

Flutter๊ฐ€ ์žˆ๋Š” DSX์˜ ๊ฒฝ์šฐ ์ด๊ฒƒ์ด ๋ฐ”๋กœ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ ์ด๊ฒƒ์€ ์œ„์ ฏ ์ƒ์„ฑ์˜ ์˜๋ฏธ๋ฅผ ์žƒ์–ด๋ฒ„๋ฆฐ ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

์•„๋ฌด๊ฒƒ๋„ ์ œ๊ฑฐํ•˜์ง€ ์•Š์œผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ฌด์–ธ๊ฐ€๋ฅผ ์žƒ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? (์žฅ์ ๊ณผ ๋‹จ์ ์ด ์žˆ๋Š”) ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์–ป๊ณ  ์žˆ๊ณ  ์ด์ œ ์„ ํƒ์˜ ์ž์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๊ฒƒ์„ ์„ ํƒํ•˜์‹ญ์‹œ์˜ค.

์•ˆ๋…•ํ•˜์„ธ์š”, ์ œ ๊ธ€์„ ์ž˜๋ชป ์ดํ•ดํ•˜์‹  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. react ๋Š” react-dom , react-native , react-pdf , react-vr ๋“ฑ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ฐ˜์‘ ๋ Œ๋”๋Ÿฌ๋ฅผ ๊ตฌ๋™ํ•ฉ๋‹ˆ๋‹ค. Afaik, react ๋ฐ react-dom ๊ฐ€ ๋™์‹œ์— ์ถœ์‹œ๋˜์—ˆ์œผ๋ฏ€๋กœ jsx ์˜ ์œ ์‚ฐ์€ ์ œ ์ƒ๊ฐ์— ๋งค์šฐ ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. Flutter์˜ ๋งฅ๋ฝ์—์„œ JSX์˜ ๊ฐ€์น˜์— ๋Œ€ํ•ด ์„œ๋กœ ๋‹ค๋ฅธ ์˜๊ฒฌ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ œ ๋ฉ”์‹œ์ง€๋ฅผ ๊นŠ์ด ํŒŒ๊ณ ๋“ค์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ฃผ์ œ์— ๊ทธ๊ฒƒ์„ ์œ ์ง€ํ•˜๊ณ  ๋จธ๋ฆฌ์นด๋ฝ์„ ๋‚˜๋ˆ„์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” lukepighetti๋‹˜, JSX์™€ ํ•จ๊ป˜ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฐ˜์‘์„ ํ•œ ๋‹ฌ์—์„œ ๋‘ ๋‹ฌ ๋™์•ˆ ์‚ฌ์šฉํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด JSX๋กœ ์•ฑ์„ ๋นŒ๋“œํ•˜๊ณ  ๋„ค์ดํ‹ฐ๋ธŒ๋กœ ๋ฐ˜์‘(๋˜๋Š” ๋ฐ˜์‘, ๋‚˜๋Š” ๊ทธ๋“ค์ด ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Œ) ํ”„๋ ˆ์ž„์›Œํฌ ์Šคํƒ€์ผ์ด ๊ฐ„๋‹จํ•˜๊ณ  ์ž˜ ๊ตฌ์กฐํ™”๋œ ์ด์œ ๋ฅผ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ผ์ • ๊ธฐ๊ฐ„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด JSX๊ฐ€ ์™œ ๊ทธ๋ ‡๊ฒŒ ์œ ์šฉํ•˜๊ณ  ์ค‘์š”ํ•œ์ง€ ์ ˆ๋Œ€ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์—ฌ์ „ํžˆ Google์ด JSX์˜ ์•„๋ฆ„๋‹ค์›€์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ด๋ฅผ ์ง€์›ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Google ํŒ€์€ ์–ธ์  ๊ฐ€ React์—์„œ ์˜๊ฐ์„ ๋ฐ›์€ ํ”„๋ ˆ์ž„์›Œํฌ์ธ flutter๋ฅผ ์œ„ํ•ด DSX ๋˜๋Š” JSX์— ๋Œ€ํ•ด ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” lukepighetti๋‹˜, JSX์™€ ํ•จ๊ป˜ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฐ˜์‘์„ ํ•œ ๋‹ฌ์—์„œ ๋‘ ๋‹ฌ ๋™์•ˆ ์‚ฌ์šฉํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด JSX ๋ฐ React ๋„ค์ดํ‹ฐ๋ธŒ(๋˜๋Š” React, ๋‚˜๋Š” ๊ทธ๊ฒƒ๋“ค์ด ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Œ) ํ”„๋ ˆ์ž„์›Œํฌ ์Šคํƒ€์ผ๋กœ ์•ฑ์„ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์ด ์™œ ๊ฐ„๋‹จํ•˜๊ณ  ์ž˜ ๊ตฌ์กฐํ™”๋˜์–ด ์žˆ๋Š”์ง€ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

lukepighetti์— ๋Œ€ํ•ด ๋งํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ 2๋…„ ๋™์•ˆ React์™€ ์ „๋ฌธ์ ์œผ๋กœ ์ผํ•ด ์™”์œผ๋ฉฐ ์ง€๊ธˆ์€ Vue๋ฅผ ์ผ๋ถ€ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ €๋Š” JSX์— ๋Œ€ํ•ด ์•„์ฃผ ์ž˜ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ €๋„ Flutter๋ฅผ ์•ฝ 2๋…„ ๋™์•ˆ ์‚ฌ์šฉํ•ด ์™”์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” Flutter์—๋„ ์ผ์ข…์˜ JSX๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๊ทธ ๊ธฐ๊ฐ„ ๋™์•ˆ Flutter๊ฐ€ ์ƒ๋‹นํžˆ ๊ฐœ์„ ๋˜์—ˆ๊ณ  ์ƒ๊ฐ์ด ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค.

  • JSX๋Š” ์†์œผ๋กœ ์“ฐ๊ธฐ์— ๋”์ฐํ•ฉ๋‹ˆ๋‹ค. ์ž๋™ ๋‹ซ๊ธฐ ํƒœ๊ทธ, ์ž๋™ ์ด๋ฆ„ ๋ฐ”๊พธ๊ธฐ ํƒœ๊ทธ ๋ฐ emmet์„ ํฌํ•จํ•˜์—ฌ ๊ฒฌ๋”œ ์ˆ˜ ์žˆ๋„๋ก ๋งŽ์€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  Flutter์˜ ๊ตฌ๋ฌธ๋งŒํผ ๊ฐ„๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด Foo() ๋ฅผ Foo(child: Bar()) ๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ <Foo /> ๋ฅผ <Foo><Bar /></Foo> ๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

  • Flutter๋Š” ๊ด„ํ˜ธ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋งŽ์€ ๋ฆฌํŒฉํ† ๋ง ์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • Flutter๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฐ€์ƒ ๋‹ซ๋Š” ํƒœ๊ทธ๋Š” ๋ ํƒœ๊ทธ์˜ ๋ถ€์กฑ์„ ๋ณด์™„ํ•ฉ๋‹ˆ๋‹ค.
    _ํ•˜์ง€๋งŒ ์ฝ”๋“œ ๋ฆฌ๋ทฐ์—๋Š” ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!_
    ๊ทธ๋“ค์€ ์‹ค์ œ๋กœํ•ฉ๋‹ˆ๋‹ค! IDE์—์„œ ์ฝ”๋“œ ๊ฒ€ํ† ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://code.visualstudio.com/blogs/2018/09/10/introducing-github-pullrequests ์ฐธ์กฐ

    • JSX๋Š” Flutter ๋ชจ๋ธ์— ๋Œ€ํ•ด ์ž˜ ๋ฒˆ์—ญ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์œ„์ ฏ์ด child ์™€ children ๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ์–ป์Šต๋‹ˆ๊นŒ?

<Foo
  child={<Bar />}
>
  <Bar />
</Foo>

?

์ด ๊ฒฝ์šฐ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด $ children ์Šฌ๋กฏ์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  child ๋ฅผ ํ•ญ์ƒ ๋ช…๋ช…๋œ ์ธ์ˆ˜๋กœ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” children ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์œ„์ ฏ์ด ๊ฑฐ์˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋‹ค์ˆ˜๋Š” ๋‹จ์ผ child ๋˜๋Š” Scaffold ์™€ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ •์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์กฐํ•ฉ์ž…๋‹ˆ๋‹ค.

์ฆ‰, JSX๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์œ„์ ฏ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<Container
  child={<Bar />}
/>

๋‹ค์Œ์€ _๋‚˜์œ_ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Container(
  child: Bar(),
)

์š”์•ฝํ•˜๋ฉด Flutter๊ฐ€ ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  JSX๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค ํ•˜๋”๋ผ๋„ ์‹ค์ œ๋กœ ์ƒํ™ฉ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์„์ง€๋Š” ์˜๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด upthread๋Š” ์‹ค์ œ๋กœ JS/ECMAScript/์ผ๋ฐ˜ ์›น ๊ธฐ๋Šฅ(๊ฐ์ฒด ํ™•์‚ฐ, ๊ตฌ์กฐํ™”, ๊ฐ์ฒด/ํ•ด์‹œ๋งต์˜ ํ˜ธํ™˜์„ฑ, ๋งค์šฐ ์œ ์‚ฌํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ–๋Š” ๋ชจ๋“  DOM* ๋…ธ๋“œ, HTML์˜ ์œ ์—ฐ์„ฑ ์ผ๋ฐ˜ ๋“ฑ) JSX ๊ธฐ๋Šฅ์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ด์ „ IMO๋Š” JSX๋ฅผ ์“ฐ๊ธฐ ์ข‹๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋“ค์ด ์—†์œผ๋ฉด XML์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋ฟ์ด๋ฉฐ ์‹ค์ œ๋กœ ์„ ํƒ๊ถŒ์ด ์žˆ๋Š” ๋‚ด๊ฐ€ ์•„๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ XML ์ž‘์„ฑ์„ ์ข‹์•„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

*์ด ๋ชจ๋“  ๊ฒƒ๋ณด๋‹ค ์ด๊ฒƒ์ด Flutter๋ฅผ XML๋กœ ๊ฐœ์กฐํ•˜๋ ค๋Š” ์‹œ๋„์— ๋Œ€ํ•œ ๋‚˜์˜ ์ฃผ์š” ๋ฐ˜๋Œ€์ž„์„ ์–ธ๊ธ‰ํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. JSX/React๊ฐ€ ์›น์— ๊นŠ์€ ๋ฟŒ๋ฆฌ๋ฅผ ๋‘๊ณ  ์žˆ๊ณ  DOM ์š”์†Œ๊ฐ€ _attributes_ ๋ฐ _children_์„ ๊ฐ–๋Š” ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•œ ์˜ค๋žœ ํ‘œ์ค€์„ ๊ฐ–๊ณ  ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ถ€์ •ํ•˜๋ ค๋Š” ์ง„์ •ํ•œ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— Flutter๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋‹ค๋ฅธ ์œ„์ ฏ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ์œ„์ ฏ์˜ ์Šฌ๋กฏ ์ด๋ฆ„์„ children ๋˜๋Š” child ๋กœ ์ง€์ •ํ•˜๋„๋ก ๋ฐ”์ธ๋”ฉํ•˜์ง€ ์•Š์œผ๋ฉฐ ๊ทธ๋ ‡๊ฒŒ ์‹œ์ž‘ํ•ด์•ผ ํ•  ์ด์œ ๊ฐ€ ์ „ํ˜€ ์—†์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ JSX ์Šค๋ ˆ๋“œ๊ฐ€ ์ž ๊ธด ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. JSX๊ฐ€ Flutter์— ๋„์›€์ด ๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด GitHub ์ฃผ์„์—์„œ ๋‚ด ๊ธฐ์ˆ /๊ฒฝํ—˜์„ ๋ณ€ํ˜ธํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. "Flutter์— ๋Œ€ํ•œ ์˜๊ฒฌ์„ ๊ฐ€์งˆ ๋งŒํผ Flutter์— ๋Œ€ํ•œ ๊ฒฝํ—˜์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."๋ผ๊ณ  ์‰ฝ๊ฒŒ ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ถ„์ด ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ‚ค๋ณด๋“œ ์›Œ๋ฆฌ์–ด ๋ถ€์กฑ์„ ์ฆ๊ฒจ๋ณด์„ธ์š”.

์œ„์ ฏ์ด child ์™€ children ๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ์–ป์Šต๋‹ˆ๊นŒ?

์œ„์ ฏ์— child ์™€ children ๊ฐ€ ๋ชจ๋‘ ์žˆ์–ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ด๊ฑฐ๋‚˜ ์ €๊ฒƒ์ž…๋‹ˆ๋‹คใ€‚
๋˜ ๋‹ค๋ฅธ ์ฃผ์ œ๏ผŒFlutter์˜ ์ผ๋ถ€ ์œ„์ ฏ์€ children ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค๋ฅธ ์œ„์ ฏ์€ $ child ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„๋ฌด๋„ ์ด๊ฒƒ์ด ๋ณต์žกํ•˜๊ณ  ํ˜ผ๋™ํ•˜๊ธฐ ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? children ์—๋Š” child $๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. child ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์žˆ๋“  ์ƒ๊ด€์—†์ด, ํ•˜๋‚˜ ๋˜๋Š” ๊ทธ ์ด์ƒ, children ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…์„ ์™„๋ฃŒํ•˜์‹ญ์‹œ์˜ค.

@rrousselGit

JSX๋Š” ์†์œผ๋กœ ์“ฐ๊ธฐ์— ๋”์ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฒฌ๋”œ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด ๋งŽ์€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๊ณ ,

์ „์ฒด React ์„ธ๊ณ„๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ „์ฒด HTML ์„ธ๊ณ„์™€ XML ์„ธ๊ณ„๋„ ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Flutter๋Š” ๊ด„ํ˜ธ๋ฅผ ๋” ์‰ฝ๊ฒŒ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋งŽ์€ ๋ฆฌํŒฉํ† ๋ง ์˜ต์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ Flutter๋„ '๋งŽ์€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค'๋ผ๊ณ  ๋งํ•˜์ง€๋งŒ ํŽธํ–ฅ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์ชฝ์„ ํ๊ธฐํ•ด์•ผ ํ•  ํ•„์š”์„ฑ์„ ๋Š๋‚๋‹ˆ๋‹ค. ์ฐธ๊ณ : ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ผ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•œ ๊ฐ€์ง€ ์ด์ƒ์ด๊ณ  ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์„ ํ˜ธํ•  ๊ฒƒ์ด๋ผ๋Š” ์ ์„ ๋ฐ›์•„๋“ค์ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋“ค์€ ์‹ค์ œ๋กœํ•ฉ๋‹ˆ๋‹ค! IDE์—์„œ ์ฝ”๋“œ ๊ฒ€ํ† ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ์˜จ๋ผ์ธ ์ฝ”๋“œ ๊ฒ€ํ†  ๋„๊ตฌ์˜ ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋„๊ตฌ๋Š” ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์กฐ์ž‘ํ•˜๋ฉฐ ์†Œ์Šค ์ฝ”๋“œ์— ์—†์œผ๋ฉด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

JSX๋Š” Flutter ๋ชจ๋ธ์— ๋Œ€ํ•ด ์ž˜ ๋ฒˆ์—ญ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ๋‹น์‹ ์˜ ๋‚˜์œ ์ƒ๊ฐ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋‚˜ DSX๊ฐ€ Flutter์™€ ์™„๋ฒฝํ•˜๊ฒŒ ๋งž๋Š” JSX์— ํ–ฅ์ƒ๋œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://spark-heroku-dsx.herokuapp.com/index.html

๊ทธ๋ž˜์„œ Flutter๋Š” '๋งŽ์€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค'๋ผ๊ณ  ๋งํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋‹ˆ, '์ฐธ์„ ์ˆ˜ ์žˆ๋‹ค'๊ฐ€ ์•„๋‹ˆ๋ผ '๋” ์‰ฝ๊ฒŒ'๋ผ๊ณ  ๋งํ–ˆ๋‹ค.

๋‚˜๋Š” ์šฐ์—ฐํžˆ StackOverflow/Slack์— ์ž์ฃผ, ๋•Œ๋กœ๋Š” ์‹ฌ์ง€์–ด ๋‚ด ์ „ํ™”๋กœ ๋Œ€๋‹ตํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  html ๊ด€๋ จ ์งˆ๋ฌธ์— ๋‹ตํ•  ๋•Œ ๋ถ„๋ช…ํžˆ ์ข‹์ง€ ์•Š์€ ์‹œ๊ฐ„์„ ๋ณด๋ƒˆ์ง€๋งŒ Flutter๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ผ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•œ ๊ฐ€์ง€ ์ด์ƒ์ด๊ณ  ์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์„ ์„ ํ˜ธํ•  ๊ฒƒ์ด๋ผ๋Š” ์‚ฌ์‹ค์„ ๋ฐ›์•„๋“ค์ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ ๋ฐ˜๋Œ€์˜ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ JSX์˜ 100% ํŒฌ์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์„ ๋ถ„๋ช…ํžˆ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ์™€ ์ด์ „ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋ฐ˜๋Œ€ ํˆฌํ‘œ ์ˆ˜๊ฐ€ ์ด๋ฅผ ์ฆ๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ๋‹น์‹ ์˜ ๋‚˜์œ ์ƒ๊ฐ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋‚˜ DSX๊ฐ€ Flutter์™€ ์™„๋ฒฝํ•˜๊ฒŒ ๋งž๋Š” JSX์— ํ–ฅ์ƒ๋œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋™์˜ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ตฌ๋ฌธ์—๋Š” ๋งŽ์€ ํ‚ค๋ณด๋“œ ๋ ˆ์ด์•„์›ƒ์—์„œ ์•ก์„ธ์Šคํ•˜๊ธฐ ์–ด๋ ค์šด ๋ณต์žกํ•œ ๋ฌธ์ž๊ฐ€ ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๊ฒƒ์€ ๋„ˆ๋ฌด ๋งŽ์€ ๋ฐ˜๋ณต์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.


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

JSX๊ฐ€ Flutter์—์„œ ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด JSX์— ๊ฐ€์ž…ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ค‘์ฒฉ ์ง€์˜ฅ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ์ด์•ผ๊ธฐ๋Š” ๋‹คํŠธ ์–ธ์–ด์˜ ์„ธ๋ฏธ์ฝœ๋ก ์ž…๋‹ˆ๋‹ค. ์ •๋ง ์งœ์ฆ๋‚˜๋„ค์š”.

๋˜ ๋‹ค๋ฅธ ์ด์•ผ๊ธฐ๋Š” ๋‹คํŠธ ์–ธ์–ด์˜ ์„ธ๋ฏธ์ฝœ๋ก ์ž…๋‹ˆ๋‹ค. ์ •๋ง ์งœ์ฆ๋‚˜๋„ค์š”.

dart-lang/language์— ๋Œ€ํ•œ ์š”์ฒญ์ด ์žˆ์Šต๋‹ˆ๋‹ค: https://github.com/dart-lang/language/issues/69
๊ฐ€์„ธ์š” ๐Ÿ‘

์ด ๊ธด ํ† ๋ก ์€ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

<A property="a">
  <B/>
  <C/>
</A>

๋Œ€์‹ :

A(property: a, children: [
   B(), 
   C()
])

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

์ƒˆ๋กœ์šด ์–ธ์–ด๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์—, ์ €๋Š” ์˜คํžˆ๋ ค ์ด์ƒ์ ์ด์ง€ ์•Š๊ณ  ํŒจํ„ด ์ผ์น˜ , ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค , ADT , ๊ตฌ์กฐํ™” , ์ ์ ˆํ•œ ์„ ํƒ ์‚ฌํ•ญ ๋“ฑ๊ณผ ๊ฐ™์€ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ด ๋ˆ„๋ฝ๋œ Dart ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ PR ์ค‘ ์ผ๋ถ€๋Š” ์ด๋ฏธ 5+ ์—ด๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฐ๋ น. ์ด๊ฒƒ์€ ์œ„์ ฏ์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์™ธ๊ด€์ƒ ๋ถˆํ•„์š”ํ•œ ๋งˆํฌ์—… ๋ ˆ์ด์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๊ณผ๋Š” ๋Œ€์กฐ์ ์œผ๋กœ ์•„ํ‚คํ…์ฒ˜, ์•ˆ์ „ ๋ฐ ์ „์ฒด ์ฝ”๋“œ ํ’ˆ์งˆ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด "์ปค๋ฎค๋‹ˆํ‹ฐ ์ฃผ๋„"๋ผ๊ณ  ํ• ์ง€๋ผ๋„ ์ปค๋ฎค๋‹ˆํ‹ฐ๊ฐ€ ์˜๋ฏธ ์žˆ๋Š” ์ผ์„ ํ•˜๋Š” ๋ฐ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฌผ๋ก  ๋ชจ๋“  ์‚ฌ๋žŒ์€ ์ž์‹ ์ด ์›ํ•˜๋Š” ์‹œ๊ฐ„์— ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Flutter ํŒ€์— ์ด ๋ถˆ๊ท ํ˜•์ ์ธ ์••๋ ฅ์„ ๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ์ค‘๋‹จํ•˜์‹ญ์‹œ์˜ค.

์ด๋ด, i-Schuetz.
๋‹ต๋ณ€ ์„น์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

image

์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์ด ๊ธด ํฌ์ŠคํŠธ์—์„œ ๋งํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. JSX๋Š” "HTML๊ณผ XML์˜ ์ŠคํŒŒ๊ฒŒํ‹ฐ ๋ฌธ์ œ"(์ฝ์„ ์ˆ˜ ์—†๊ณ  ๋ณต์žกํ•œ UI ์ฝ”๋“œ)๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ”Œ๋Ÿฌํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ ํ›„ ๊ฐœ์ธ์ ์ธ ์ƒ๊ฐ์œผ๋กœ๋Š” JSX๋ณด๋‹ค ๋” ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ์ตœ์•…์ž…๋‹ˆ๋‹ค.

๋ช‡ ๋…„ ๋™์•ˆ ๋‚˜๋Š” Flutter๊ฐ€ React์˜ ์žฅ์  ์ค‘ ์ผ๋ถ€๋ฅผ ํฌ์ฐฉํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ๋งํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ๋ณด์•„์™”์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ชจ๋“  ๊ฒƒ์˜ ์ง„์ •ํ•œ ๊ฐœ๋…์€ ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ํŒ”๋กœ์šฐํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ•์กฐ ํ‘œ์‹œ๋œ ํ…์ŠคํŠธ์—์„œ ์‚ฌ์šฉ์ž๋Š” HTML์— ์ต์ˆ™ํ•˜๊ณ  ์œ ์‚ฌํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— JSX๋ฅผ ๋” ์‰ฝ๊ฒŒ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ JSX์˜ ์กด์žฌ๋ฅผ ์ •๋‹นํ™”ํ•˜๊ณ  Flutter์— ๋Œ€ํ•œ ๋ชจ๋ฐฉ์€ ์–ด๋–ค ์‹์œผ๋กœ๋“  ์ •๋‹นํ™”ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

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

@JonathanSum ์€ JSX๋ณด๋‹ค Flutter๊ฐ€ ๋” ๋ณต์žกํ•ฉ๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด Flutter๊ฐ€ _React_์™€ ๋‹ฌ๋ผ์„œ ๋งˆ์ฐฐ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๊นŒ? ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ๋” ์žฅํ™ฉํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ, IDE์—์„œ ๊ฐ€์ƒ ๋‹ซ๊ธฐ ํƒœ๊ทธ ์—†์ด๋Š” ๊ฑฐ์˜ ํ‹€๋ฆผ์—†์ด ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€์ง€๋งŒ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด XML๊ณผ ์œ ์‚ฌํ•œ DSL์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค _๋ณต์žกํ•œ_ ๋ฐฉ๋ฒ•์ด ํ™•์‹คํ•˜์ง€ ์•Š์œผ๋ฉฐ ์—ฌ์ „ํžˆ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ ๊ทธ๋ ‡๊ฒŒ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด XML๊ณผ ๊ฐ™์€ DSL์ด Flutter ์‚ฌ์šฉ์„ _์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ_ ๋งŒ๋“ค์–ด์ค„ ์€์ด์•Œ์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํŠนํžˆ Flutter๊ฐ€ React/JSX๊ฐ€ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์„ฑ๋œ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ด์ „ ์ด๋ ฅ์ด ์—†๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•˜๋ฉด - React๋Š” DOM ์กฐ์ž‘์„ ๋” ์‰ฝ๊ณ  ๊น”๋”ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋„ ์ข‹์ง€๋งŒ Flutter์™€ ์ •ํ™•ํžˆ ๋ฌด์Šจ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋ช‡ ๋…„ ๋™์•ˆ ๋‚˜๋Š” Flutter๊ฐ€ React์˜ ์žฅ์  ์ค‘ ์ผ๋ถ€๋ฅผ ํฌ์ฐฉํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ๋งํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ๋ณด์•„์™”์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ชจ๋“  ๊ฒƒ์˜ ์ง„์ •ํ•œ ๊ฐœ๋…์€ ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

React๋Š” Flutter์— ์—†๋Š” ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ "์ง„์ •ํ•œ" ์•„์ด๋””์–ด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ๊ฐœ๋…์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  Flutter/Dart ๋””์ž์ธ์—๋Š” React/JS๊ฐ€ ์บก์ฒ˜ํ•  ์ˆ˜ ์—†๋Š” ๋ช‡ ๊ฐ€์ง€ ์žฅ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ๊ดœ์ฐฎ์€ UI SDK/ํ”„๋ ˆ์ž„์›Œํฌ/๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ๋™์ผํ•˜๊ฒŒ(๋˜๋Š” ๊ทธ ๋ฐ˜๋Œ€๋กœ) ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋†€๋ž๊ฒŒ๋„ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ๋Š” ์‹ค์ œ๋กœ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ํ•œ ํ”„๋กœ์ ํŠธ์— ์˜ค๋Š” ์‚ฌ๋žŒ๋“ค์ด [๊ณผ๊ฑฐ์— ์‚ฌ์šฉํ•œ ํ”„๋กœ์ ํŠธ ์‚ฝ์ž…]์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š๊ณ  ์‹œ์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋” ๋‚˜์€ ์„œ๋น„์Šค๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๐Ÿ™‚

๋ช‡ ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/munificent/ui-as-code

์•„๋งˆ๋„ ์ƒ๋‹นํžˆ ํš๊ธฐ์ ์ธ ๋ณ€๊ฒฝ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ž์œ  ์ œ์•ˆ์€ Dart์— ์˜ˆ๋ฅผ ๋“ค์–ด Crystal์˜ ๋ฉ”์†Œ๋“œ ์ธ์ˆ˜ spec ์ด ์žˆ๋‹ค๋ฉด ๋นŒ๋“œ ๋ฉ”์†Œ๋“œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋” ๊ฐ„๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ƒ๊ฐํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  Crystal์˜ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฏผ๋‹ฌํŒฝ์ด์™€ ๊ฑฐ๋ถ์ด์™€์˜ ๊ฒฝ์Ÿ์—์„œ ๊ผด์ฐŒ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด์ œ JSX๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ  ํ”Œ๋Ÿฌํ„ฐ์— ์ถ”๊ฐ€ ์••๋ ฅ์„ ๊ฐ€ํ•˜์ง€ ์•Š๊ธฐ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‹คํŠธ์— ๊ด€ํ•œ ํ•œ JS ๋˜๋Š” TS๋ณด๋‹ค ํ›จ์”ฌ ๋œ ์šฐ์•„ํ•ฉ๋‹ˆ๋‹ค. ๋ฌด๋ ฅ๊ฐ์„ ๋Š๋‚€๋‹ค

์˜ˆ๋ฅผ ๋“ค์–ด, Microsoft UI ๊ธฐ์ˆ ์˜ ๊ฐœ๋ฐœ ๊ฒฝ๋กœ๋Š” WinForm์—์„œ WPF๋กœ๏ผŒํ˜„์žฌ Flutter์—์„œ๋Š”๏ผŒWPF๋ฅผ ๋ฒ„๋ฆฌ๊ณ  ๋Œ€์‹  WinForm์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹คใ€‚๊ฐœ๋ฐœ์ž์˜ ๋ถˆ๋งŒ์— ์‘๋‹ตํ•˜์—ฌ Flutter ํŒ€์€ WinForm์˜ ์‹œ๊ฐ์  ์ฐฝ ๋ฐ ์†์„ฑ ํŽธ์ง‘๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์—ด์‹ฌํžˆ ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค.ใ€‚

Flutter์˜ ์ดˆ๋ณด์ž๋กœ์„œ ์ €๋Š” ์ด๊ฒƒ์ด ๋กœ๋“œ๋งต์— ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. jsx๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์œ„์ ฏ์„ ๋ฐฐ์น˜ํ•˜๋Š” ๋” ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ˆœ๊ฐ„์— ๋ฐ˜์‘ ํด๋ž˜์Šค์˜ ๋ Œ๋”๋ง ๊ธฐ๋Šฅ๊ณผ ๋ Œ๋”๋ง๋œ ํด๋ž˜์Šค์™€ ์—ฐ๊ด€์˜ ์ด๋ฏธ์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹คํŠธ ํŒŒ์ผ๊ณผ ๋ Œ๋”๋ง๋œ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ž‘๋™ ๋ฐฉ์‹์„ ํŒŒ์•…ํ•˜๋Š” ๋ฐ 5-6๋ถ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค...

์ง๊ด€์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜ ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ์—์„œ ๋ฐ˜๋ณต์žกํ•œ ๋ฐ˜์‘ ํด๋ž˜์Šค๋ฅผ 5๋ถ„ ๋งŒ์— ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํ”Œ๋Ÿฌํ„ฐ์—์„œ ๊ทธ๊ฒƒ์„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์ด ์—†์œผ๋ฉด ๊ฐœ๋ฐœ์ž ์ž๊ฒฉ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ฌด์–ธ๊ฐ€๋ฅผ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•ด ํ™•์žฅ์— ์˜์กดํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค -.-

ํ•˜์ง€๋งŒ. ๋‹คํŠธ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด "๋ฌธ์ œ"๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€ ํฅ๋ฏธ๋กœ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. dart 2์—์„œ๋Š” ๋” ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. dart 3 -4 -5 ์˜ ๊ฐ€๋…์„ฑ์„ ์–ด๋–ป๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ตฌ์„ฑ ์š”์†Œ ๋นŒ๋“œ ๊ธฐ๋Šฅ์˜ ๋ฆฌํŒฉํ† ๋ง์ด ์กฐ๋งŒ๊ฐ„ ํ•„์š”ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘ํ•˜๋‹ค:
์‹ ๊ฒฝ ์“ฐ์ง€ ๋งˆ์„ธ์š”. ๋ฐฉ๊ธˆ React Native๋ฅผ ๋‹ค์‹œ ์‹œ๋„ํ–ˆ๋Š”๋ฐ jsx, props ์‹œ์Šคํ…œ์ด ์‹ซ์–ด์„œ ๋ชจ๋“  ๊ฒƒ์ด ๋™์ ์ด๋ผ๋Š” ์‚ฌ์‹ค์ด ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ •๋ง ๋ฌด์„œ์šด ๊ฐœ๋…์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋•Œ ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ๊ฐœ์ธ์ ์ธ ์˜๊ฒฌ์ผ ๋ฟ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํŽ„๋Ÿญ์ด๋Š”๋Œ€๋กœ ๋†”๋‘์„ธ์š”....

๊ทธ๋“ค์€ JSX๋ฅผ ์‚ฌ๋ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ DSX๋ฅผ ์š”์ฒญํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ Flutter๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ๊ณผ ์ง€์›์„ ์œ„ํ•ด UI ์„ ์–ธ์€ ์ฝ”๋“œ์—์„œ ์‹œ๊ฐ์ ์œผ๋กœ ๋ถ„๋ฆฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ํ›„๋ฐฐ/๋ฏธ๋“ค์ด ๋งŽ์€ ๋Œ€๊ทœ๋ชจ ํŒ€์—์„œ. Adobe Flex์—์„œ ๋‚˜์˜จ Flutter์˜ UI ์„ ์–ธ์„ ์ฝ์œผ๋ฉด ์ƒ์‚ฐ์„ฑ์ด ํฌ๊ฒŒ ์ €ํ•˜๋œ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
DSX(๊ต‰์žฅํ•œ IMO๊ฐ€ ๋  ์ˆ˜ ์žˆ์Œ)๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ์ ์–ด๋„ IDE ์ˆ˜์ค€์—์„œ๋Š” ํ˜„์žฌ ์ƒํ™ฉ์—์„œ ๋ฌด์–ธ๊ฐ€๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด์ „์˜ ๋ชจ๋“  UI ๊ฐœ๋ฐœ ํ”„๋ ˆ์ž„์›Œํฌ์—๋Š” ์ด ๊ธฐ๋Šฅ์ด ์žˆ์—ˆ๊ณ  ์šฐ๋ฆฌ๋„ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ๊ณผ ์ง€์›์„ ์œ„ํ•ด UI ์„ ์–ธ์€ ์ฝ”๋“œ์—์„œ ์‹œ๊ฐ์ ์œผ๋กœ ๋ถ„๋ฆฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด 'gui builder'์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋„๊ตฌ์™€์˜ ๋” ๋‚˜์€ ํ†ตํ•ฉ์„ ์œ„ํ•ด.

Adobe Flex์—์„œ ๋‚˜์˜จ Flutter์˜ UI ์„ ์–ธ์„ ์ฝ์œผ๋ฉด ์ƒ์‚ฐ์„ฑ์ด ํฌ๊ฒŒ ์ €ํ•˜๋œ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Flutters ๊ธฐ๋Šฅ์ด ์žˆ๋Š” MXML๊ณผ ๊ฐ™์€ UI ์„ ์–ธ์„ ์ƒ์ƒํ•ด ๋ณด์„ธ์š”! ๊ฟˆ๋งŒ ๊ฟ€ ์ˆ˜ ์žˆ์–ด!

์ด์ œ ์šฐ๋ฆฌ๋Š” codegen ์ง€์›์„ ๋ฐ›์•˜๊ณ , ์ด์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ œํ’ˆ์— ๋„ฃ๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ๊ทธ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ๊ฒƒ์ด ์—„์ฒญ๋‚˜๊ฒŒ ์ธ๊ธฐ๊ฐ€ ์žˆ์Œ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@Hixie codegen์— ๋Œ€ํ•œ ๋ฌธ์„œ์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด์ œ ์šฐ๋ฆฌ๋Š” codegen ์ง€์›์„ ๋ฐ›์•˜๊ณ , ์ด์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ œํ’ˆ์— ๋„ฃ๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ๊ทธ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ๊ฒƒ์ด ์—„์ฒญ๋‚˜๊ฒŒ ์ธ๊ธฐ๊ฐ€ ์žˆ์Œ์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ณด๊ธฐ์— codegen์€ .dart -> .dart๋ฅผ ์œ„ํ•œ ๊ฒƒ์ด๋ฏ€๋กœ ์ž…๋ ฅ ํŒŒ์ผ์€ ์œ ํšจํ•œ .dart ํŒŒ์ผ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹คํŠธ์˜ ์ƒ์œ„ ์ง‘ํ•ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— .dsx ํŒŒ์ผ์—๋Š” ๊ทธ๋‹ค์ง€ ์œ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋””๋ฒ„๊น… ๋“ฑ์˜ ๊ธฐ๋Šฅ๊ณผ ๊ฐ™์€ ์†Œ์Šค ๋งต์„ ์‚ฌ์šฉํ•˜์—ฌ .dart๋กœ ํฌ๋กœ์Šค ์ปดํŒŒ์ผํ•˜๋Š” ๋ฐ ๋Œ€ํ•œ ์ง€์›์ด ์—ฌ์ „ํžˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์–ด์ œ ๊ณต๊ฐœ๋œ SwiftUI๋ฅผ ํ•œ๋ฒˆ ๋ด์ฃผ์„ธ์š”. ์ด๊ฒƒ์€ React์™€ ๊ฐ™์€ ๋งˆํฌ์—… ๋Œ€์‹  Flutter๊ฐ€ ๋ชฉํ‘œ๋กœ ์‚ผ์•„์•ผ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Swift์˜ ์•”์‹œ์  ๋ฉค๋ฒ„ ํ‘œํ˜„๋งŒ์œผ๋กœ๋„ ๋„ˆ๋ฌด ํ›Œ๋ฅญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” SwiftUI ๊ตฌ๋ฌธ์— ๋Œ€ํ•ด ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ํ™•์‹คํžˆ ๊ฐ€๋ณ์ง€๋งŒ ์ผ๋ถ€ ์ธก๋ฉด์€ ๋งˆ๋ฒ•์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๊ธฐ์ˆ ์ ์œผ๋กœ ์ด๋ฏธ ๋น„๊ต์  ์œ ์‚ฌํ•œ ๊ฒƒ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Column(mainAxisSize: MainAxisSize.min)([
  if (foo) Text('foo'),
  Text('bar'),
]);

Column ๊ฐ€ _still_ ํด๋ž˜์Šค์ธ ์œ ํšจํ•œ ๋‹คํŠธ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ์ด๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์ƒํƒœ ๋น„์ €์žฅ ์œ„์ ฏ์ž…๋‹ˆ๋‹ค.

class Foo extends StatelessWidget {
  const Foo({Key key}) : this._(key: key);
  const Foo._({Key key, this.children}) : super(key: key);

  final List<Widget> children;

  <strong i="12">@override</strong>
  Widget build(BuildContext context) {
    return Column(children: children);
  }

  Foo call(List<Widget> children) {
    return Foo._(key: key, children: children);
  }
}

๊ทธ๊ฒƒ์€ ์ƒ์šฉ๊ตฌ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์ฝ”๋“œ ์ƒ์„ฑ๊ธฐ๋Š” ํŠนํžˆ ๋‹ค๊ฐ€์˜ค๋Š” ํ™•์žฅ ๋ฉค๋ฒ„์™€ ํ•จ๊ป˜ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ด ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์œ ์ผํ•œ ๋ฌธ์ œ๋Š” const ์ƒ์„ฑ์ž๋ฅผ ์žƒ๊ณ (์ž์‹์„ ์ง€์ •ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—) ์œ„์ ฏ ํด๋ž˜์Šค _twice_๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•ด๋‹น ๊ตฌ๋ฌธ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ call ๋ฉ”์„œ๋“œ ๋Œ€์‹  ์ด์ƒ์ ์œผ๋กœ๋Š” ์ƒ์„ฑ์ž ์ปค๋ง์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@rrousselGit ๋‚˜๋Š” SwiftUI์˜ ์–ด๋–ค ์ธก๋ฉด์ด ๋‹น์‹ ์—๊ฒŒ ๋งˆ๋ฒ•์ฒ˜๋Ÿผ ๋ณด์ด๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ Swift ๊ตฌ๋ฌธ์˜ ๋งค์šฐ ๊ฐ„๋‹จํ•œ ํ™•์žฅ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ์˜ ์ฝ”๋“œ ์˜ˆ์ œ์—์„œ :

  • Content ๋Š” ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ? Mobx/Vue ์Šคํ† ์–ด๊ฐ€ ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค๋Š” ๋œป์ธ๊ฐ€์š”?
  • @State ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
  • body ๊ฐ€ ๋ณ€์ˆ˜์ธ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ฒŒํ„ฐ์ธ๊ฐ€์š”? ๊ทธ๋ ‡๋‹ค๋ฉด getter๋Š” ์–ธ์ œ ๋‹ค์‹œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๊นŒ?
  • body ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ผ๋ถ€์ž…๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด Content ๋‚ด๋ถ€์˜ ๋งŽ์€ ์œ ์‚ฌํ•œ ๋ณ€์ˆ˜์ž…๋‹ˆ๊นŒ?
  • ๊ทธ item in _์ •ํ™•ํžˆ_ ํ•˜๋Š” ์ผ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? in ์˜ ์˜ค๋ฅธ์ชฝ ํ”ผ์—ฐ์‚ฐ์ž๊ฐ€ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ "๊ฒฐ๊ณผ"์ธ ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
  • HStack ๊ฐ€ ์—†๋Š”๋ฐ ์™œ Image ๊ฐ€ ์ œ๋ชฉ/๋ถ€์ œ๋ชฉ ์™ผ์ชฝ์— ๋งž์ถฐ์ ธ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ™•์‹คํžˆ ๊ธฐ์–ต์€ ์•ˆ๋‚˜์ง€๋งŒ Flutter๋ฅผ ์„ ํƒํ•  ๋•Œ ๊ทธ๋Ÿฐ ์งˆ๋ฌธ์€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

@rrousselGit ๊ทธ๊ฒƒ์€ Flutter ๊ตฌ๋ฌธ์ด๋‚˜ ์˜๋ฏธ๊ฐ€ ๋ณธ์งˆ์ ์œผ๋กœ ๋ถ„๋ช…ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด ์•„๋‹ˆ๋ผ ๊ท€ํ•˜์˜ ๋ฐฐ๊ฒฝ ๋•Œ๋ฌธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๋‹นํžˆ ๋‚œ์ฒ˜ํ•œ ์‚ฌ๋žŒ๋“ค์„ ๋งŽ์ด ๋งŒ๋‚ฌ์Šต๋‹ˆ๋‹ค). ๊ทธ๋ฆฌ๊ณ  ๋‹น์‹ ์ด ์ œ๊ธฐํ•œ ์š”์ ์€ 14์ค„ ์ฝ”๋“œ ์กฐ๊ฐ์„ ์˜ค๋ฅ˜์— ๋Œ€ํ•ด ๊ณผ๋„ํ•˜๊ฒŒ ๋ถ„์„ํ•˜๋ฉด์„œ ์‹ค์ œ๋กœ ์ž‘์„ฑ๋œ ์–ธ์–ด๋ฅผ ์•Œ์ง€ ๋ชปํ•˜๋Š” ์ด์ƒํ•œ ์ ‘ํ•ฉ์ ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

  • ๊ทธ๋Ÿฌ๋‚˜ (Dart ๋˜๋Š” JS ์˜๋ฏธ์—์„œ) ์‹ค์ œ๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ๊ตฌ์กฐ์ฒด์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ MobX/Vue ์Šคํƒ€์ผ ์Šคํ† ์–ด(์˜ˆ: ์ƒ๋‹นํžˆ ์ œํ•œ๋œ ์–ธ์–ด ์ง€์›์— ๋Œ€ํ•œ ํŽ˜์ดํผ๋ง)๊ฐ€ ๋ณ€๊ฒฝ์„ฑ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹™๋‹ˆ๋‹ค.

  • @State ๋Š” ์†์„ฑ์œผ๋กœ, ์ผ๋ถ€ ์–ธ์–ด(์˜ˆ: Dart)์—์„œ๋Š” ์ฃผ์„์œผ๋กœ ์•Œ๋ ค์ ธ ์žˆ๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด Swift ์ฝ”๋“œ์—์„œ ๋งค์šฐ ์ผ๋ฐ˜์ ์ธ ๊ฒƒ์œผ๋กœ ์•Œ๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ดํ•˜๋Š” ์ผ์„ ์˜๋ฏธํ•œ๋‹ค๋ฉด ๋ฌธ์„œ๋ฅผ ๋ณด์ง€ ์•Š์•„๋„ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ ๋  ์ƒํƒœ๋กœ ์†์„ฑ์„ ํ‘œ์‹œ ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.

  • body ๋Š” ๊ณ„์‚ฐ๋œ ์†์„ฑ์œผ๋กœ Swift ๊ฐœ๋ฐœ์ž์—๊ฒŒ ์‰ฝ๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ๊ณ„์‚ฐ๋  ๋•Œ Widget build(BuildContext context) ๋„ ๋ณธ์งˆ์ ์œผ๋กœ ์–ธ์ œ ๋‹ค์‹œ ํ˜ธ์ถœ๋˜๋Š”์ง€ ์•Œ๋ ค์ค๋‹ˆ๊นŒ?

  • Content (Swift ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋งค์šฐ ๋ช…ํ™•ํ•˜๊ฒŒ) ํ™•์žฅ/๊ตฌํ˜„ View , ์—ฌ๊ธฐ์—์„œ ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋‹ต๋ณ€์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์‹ค์ œ๋กœ ๋งค์šฐ ์ข‹์€ API ์ฐธ์กฐ ํŽ˜์ด์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค).

  • ์ด๊ฒƒ์€ "์™œ ์ด ์–ธ์–ด์˜ ํ‚ค์›Œ๋“œ๊ฐ€ ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด์˜ ํ‚ค์›Œ๋“œ์™€ ๊ฐ™์ง€ ์•Š์€๊ฐ€"์ด๋ฉฐ, ํŠน๋ณ„ํžˆ "๋งˆ๋ฒ• ๊ฐ™์€" ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ in ํ‚ค์›Œ๋“œ๋Š” for...in ๊ตฌ์กฐ์™€ ๋™์ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํด๋กœ์ €์˜ ๋ณธ๋ฌธ์ด ์‹œ์ž‘๋  ๊ฒƒ์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. { item in ... } ๋Š” List ์ƒ์„ฑ์ž์— ์ „๋‹ฌ๋œ ํ•จ์ˆ˜ ๋ธ”๋ก์ž…๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ ListView ์˜ itemBuilder ์ž…๋‹ˆ๋‹ค.

  • ๋ณด๊ธฐ์— ์ž์ฒด ์บก์Šํ™”๋œ ๋ ˆ์ด์•„์›ƒ ๊ทœ์น™์ด ์žˆ๋Š” ์ด์œ ๋ฅผ ์ •๋‹นํ•˜๊ฒŒ ๋ฌป๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

SwiftUI์—์„œ:

1-์ธก๋ฉด ๋ถ€์†๋ฌผ์ด ์•„๋‹Œ View์—์„œ ์„ ์–ธ๋œ ์ƒํƒœ๋ฅผ ๋ณด๋‹ˆ ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค.

2-์ƒ์„ฑ์ž์— ๋ชจ๋“  ๊ฒƒ์„ ์ „๋‹ฌํ•˜๋Š” ๋Œ€์‹  ํ•ญ๋ชฉ์„ ์„ค์ •ํ•˜๋Š” ์ข‹์€ ๊ฐœ๋ณ„ ๋ฉ”์„œ๋“œ(๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋งŒ ์ „๋‹ฌํ•˜๋Š” ๋Œ€์‹  ์ž‘์—…์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).

3-(๊ณผ๊ฑฐ์— ์œ„์ ฏ๊ณผ ๊ฐ™์€ ์„ ์–ธ์  SVG๋กœ ์ œ์•ˆํ•œ ๊ฒƒ์ฒ˜๋Ÿผ) ์„ ์–ธ์  ๋ฒกํ„ฐ ๊ทธ๋ž˜ํ”ฝ์ด ์„ ์–ธ์ ์ธ ๋‹ค๋ฅธ ๋ชจ๋“  ๊ฒƒ๊ณผ ํ˜ผํ•ฉ๋œ ๊ฒƒ์„ ๋ณด๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ข‹์Šต๋‹ˆ๋‹ค. !!!
https://developer.apple.com/tutorials/swiftui/drawing-paths-and-shapes

4-๋งค์šฐ ๊ฐ„๋‹จํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฐ ์ „ํ™˜ ๊ตฌ์„ฑ
https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions

์–‘๋ฐฉํ–ฅ์œผ๋กœ ์ฝ”๋“œ ํŽธ์ง‘๊ธฐ์™€ ๋™๊ธฐํ™”๋˜๋Š” 5-Drag&Drop ๋””์ž์ธ ๋„๊ตฌ.

๋‹ค๋ฅธ ๋ชจ๋“  ๊ฒƒ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์‚ฌ๋งˆ๊ท€๊ฐ€ ์žˆ์ง€๋งŒ ๋‚˜๋Š” ์˜คํžˆ๋ ค ๊ทธ๋“ค์ด ์•„์ฃผ ๋ฉ‹์ง€๊ฒŒ ํ•œ ์ผ์— ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ "์งˆ๋ฌธ"์€ ์ž ์žฌ์ ์œผ๋กœ ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ์ ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ _์‹ค์ œ ์งˆ๋ฌธ_์ด ์•„๋‹™๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋‹น์‹ ์˜ ๋ฐฐ๊ฒฝ ๋•Œ๋ฌธ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•  ๊ฒƒ ๊ฐ™์€. ๊ทธ๋“ค์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋‚˜์˜๋‹ค๊ฑฐ๋‚˜ ๊ทธ๋Ÿฐ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. Flutter๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์ฒ˜๋Ÿผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋Š๊ปด์ง€์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
Flutter ์œ„์ ฏ์€ "๋ฉ‹์ง„ ์–ธ์–ด ๊ธฐ๋Šฅ"์„ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ ๊ฑฐ์˜ โ€‹โ€‹๋ชจ๋“  ์–ธ์–ด์—์„œ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ตœ๊ทผ if/for for ์ปฌ๋ ‰์…˜์ด ๋ณ€๊ฒฝ๋˜์—ˆ์ง€๋งŒ).
SwiftUI์˜ ์‡ผ์ผ€์ด์Šค๋Š” Swift ํŠน์ • ๊ธฐ๋Šฅ์„ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์‹œ ๊ณ„์‚ฐ๋  ๋•Œ ์œ„์ ฏ ๋นŒ๋“œ(BuildContext ์ปจํ…์ŠคํŠธ)๋„ ๋ณธ์งˆ์ ์œผ๋กœ ์–ธ์ œ ๋‹ค์‹œ ํ˜ธ์ถœ๋˜๋Š”์ง€ ์•Œ๋ ค์ค๋‹ˆ๊นŒ?

์—ฌ๊ธฐ์„œ ๋‚ด ์š”์ ์€ State ์™€ body ๋ฅผ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋Š” ํ–‰์œ„ ์‚ฌ์ด์— ๊ด€๊ณ„๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
React์™€ Flutter๋Š” setState๋ผ๋Š” ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋งค์šฐ ๋ช…์‹œ์ ์ž…๋‹ˆ๋‹ค.
Vue/Mobx๋Š” ๋™์ผํ•œ @State ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” "๋งˆ๋ฒ•"์ž…๋‹ˆ๋‹ค.

๋‹ค ์ข‹์€๋ฐ ํŒจํ„ด์ด ๋‹ค๋ฅด๋„ค์š”.

๋ณด๊ธฐ์— ์ž์ฒด ์บก์Šํ™”๋œ ๋ ˆ์ด์•„์›ƒ ๊ทœ์น™์ด ์žˆ๋Š” ์ด์œ ๋ฅผ ์ •๋‹นํ•˜๊ฒŒ ๋ฌป๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์•„๋‹ˆ์š”, "๋ช…์‹œ์ " ๋Œ€ "์•”์‹œ์ "์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.
๋กœ์ง์˜ ์ผ๋ถ€๋ฅผ ์ˆจ๊ธฐ๋”๋ผ๋„(์ด ๊ฒฝ์šฐ ltr vs rtl ๋กœ์ง) "๊ฐ€๋Šฅํ•œ ํ•œ ์ ์€ ์ฝ”๋“œ๋กœ ์ตœ๋Œ€ํ•œ ๋งŽ์ด ํ•˜๋Š” ๊ฒƒ"์— ์ •๋ง๋กœ ์ง‘์ค‘ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Flutter๋Š” Row ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์š”์ฒญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Flutter๋Š” ๋งŽ์€ "๋ฉ‹์ง„ ์–ธ์–ด ๊ธฐ๋Šฅ"์„ ์‚ฌ์šฉํ•˜๊ณ  ์˜์กดํ•ฉ๋‹ˆ๋‹ค(์ฝ๋Š” ์‚ฌ๋žŒ์ด ๋ˆ„๊ตฌ์—๊ฒŒ๋‚˜ ์ต์ˆ™ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋™์˜ํ•˜์ง€ ์•Š๋Š” ์–ธ์–ด ๊ธฐ๋Šฅ). ๋‚ด ๋จธ๋ฆฌ ๊ผญ๋Œ€๊ธฐ์—์„œ ์ƒ์ˆ˜ ์ƒ์„ฑ์ž(์ผ๋ฐ˜์ ์œผ๋กœ Dart์˜ ๋ช…๋ช… ์ƒ์„ฑ์ž ์Šคํƒ€์ผ), ์—ฐ์‚ฐ์ž ์˜ค๋ฒ„๋กœ๋”ฉ, ์•”์‹œ์  ์ธํ„ฐํŽ˜์ด์Šค์ธ ํด๋ž˜์Šค, @covariant ๋ฐ ๋ฏน์Šค์ธ์€ ํ˜ผ๋ž€์—์„œ ์™„์ „ํ•œ ๋ ˆ์ด๋ธ” ์ง€์ •์— ๋Œ€ํ•œ ๋ฐ˜์‘์„ ์ด๋Œ์–ด๋‚ด๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž์˜ ๋ฐฐ๊ฒฝ์— ๋”ฐ๋ผ ์ฝ”๋“œ ๋ƒ„์ƒˆ. ํ•œ ์‹œ๊ฐ„ ์ •๋„ ์ƒ๊ฐํ•˜๋ฉด ๋” ๊ธด ๋ชฉ๋ก์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฑด ๋” ์ด์ƒ Flutter๋ฅผ ๊ณ ๋ฐœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ SwiftUI๋ฅผ ๊ณ ๋ฐœํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠน์ • ์–ธ์–ด๋กœ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ๋ชจ๋“  ์–ธ์–ด์—์„œ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์™œ ๋ฏธ๋•์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์–ธ์–ด์˜ ์ฐจ์ด์ ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๊ฐ€์žฅํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์–ธ์–ด์˜ ์š”์ ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

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

Flutter๋Š” Row ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์š”์ฒญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ListTile ๋ฅผ ์‚ฌ์šฉํ•œ ์ ์ด ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋™์ž‘์ด ์žˆ์ง€๋งŒ ๋ช…๋ช…๋œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜ํ•œ ์š”์ฒญํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ Scaffold ๊ฐ€ "๋งˆ๋ฒ•์ฒ˜๋Ÿผ" ์•ฑ๋ฐ” ์™ผ์ชฝ์— ๋ฉ”๋‰ด ๋ฒ„ํŠผ์„ ๋‘๋Š” ์ด์œ ๋„ ๋ฌผ์–ด๋ด์•ผ ํ• ๊นŒ์š”?

์ฐจ์ด์ ์€ Dart์˜ ํ˜„์žฌ ์ƒํƒœ์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ์ฃผ๋ฅ˜ ์–ธ์–ด์™€ ๋งค์šฐ ์œ ์‚ฌํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
"Dart๋ฅผ ๋ฐฐ์›Œ์•ผ ํ•˜๋‚˜์š”, ์•„๋‹ˆ๋ฉด Flutter๋ฅผ ๋ฐฐ์šฐ๊ธฐ ์‹œ์ž‘ํ•ด์•ผ ํ•˜๋‚˜์š”?"๋ผ๋Š” ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฝค ์ž์ฃผ ๋‚˜์˜ต๋‹ˆ๋‹ค.
ํ˜„์žฌ ์ •๋‹ต์€ "Flutter๋ฅผ ๋ฐฐ์šฐ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค. ํ•˜๋ฃจ ๋งŒ์— ํšจ๊ณผ์ ์ธ ๋‹คํŠธ๋ฅผ ์“ธ ์ˆ˜ ์žˆ๋‹ค"์ด๋‹ค.
์ด๊ฒƒ์ด ์˜์›ํžˆ ์œ ์ง€๋œ๋‹ค๋Š” ๋ณด์žฅ์€ ์—†์ง€๋งŒ ์ด๊ฒƒ์ด Flutter์˜ ๊ฐ•์  ์ค‘ ํ•˜๋‚˜๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋จธ์ง€ ํ† ๋ก ์€ ์ฃผ์ œ์—์„œ ์•ฝ๊ฐ„ ๋ฒ—์–ด๋‚œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฉ”์ผ๋กœ ํ•ด๋‹น ๋ถ€๋ถ„์„ ๊ณ„์†ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋‚ด github ๋ฉ”์ผ์ด ์ž‘๋™ํ•จ).

์ด๊ฒŒ ์™œ ์•ˆ ์ž ๊ฒจ์š”? ์ด๊ฒƒ์€ ์ด๋ฏธ ์‹ฌํ•˜๊ฒŒ ๊ท€์†๋˜๊ณ  ์žˆ์œผ๋ฉฐ ์ด์ „์— ์ž ๊ธด ๋ฌธ์ œ์™€ ์ •ํ™•ํžˆ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์—ฌ๊ธฐ์— ๊ฐ„๋‹จํ•œ ๊ฒƒ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
https://github.com/danialdezfouli/flutterjsx
https://www.npmjs.com/package/flutterjsx
https://www.youtube.com/watch?v=Oj1JMSurphA

์ด ์Šค๋ ˆ๋“œ๋Š” ๋‹ซํžŒ ํ›„ ์ตœ๊ทผ ํ™œ๋™์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์œผ๋กœ ์ž ๊ฒผ์Šต๋‹ˆ๋‹ค. ๋น„์Šทํ•œ ๋ฌธ์ œ๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ•˜๋ฉด flutter doctor -v ์˜ ์ถœ๋ ฅ๊ณผ ๋ฌธ์ œ์˜ ์ตœ์†Œํ•œ์˜ ์žฌํ˜„์„ ํฌํ•จํ•˜์—ฌ ์ƒˆ ๋ฒ„๊ทธ๋ฅผ ์—ฌ์‹ญ์‹œ์˜ค.

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