Fable: ์ธ์ˆ˜๋ฅผ JS ๊ฐ์ฒด๋กœ ์ปดํŒŒ์ผํ•˜๋Š” ์†์„ฑ

์— ๋งŒ๋“  2018๋…„ 10์›” 30์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: fable-compiler/Fable

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

FableConf์—์„œ @vbfox ๋Š” ์†์„ฑ์ด ์ธ์ˆ˜๋ฅผ JS ๊ฐœ์ฒด๋กœ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ์•ˆํ–ˆ์œผ๋ฏ€๋กœ props๋กœ ํ•จ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ •์˜ํ•  ๋•Œ๋งˆ๋‹ค ๋ ˆ์ฝ”๋“œ๋ฅผ ์„ ์–ธํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ ๋Œ€์‹ :

type MyProps = { key: string; value1: int; value2: float[] }

let MyComponent (props: MyProps) =
    div [] [...]

// Use
ofFunction MyComponent { key = "foo"; value1 = 5; value2 = [] } []

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

let [<MagicAttribute>] MyComponent (key: string) (value1: int) (value2: float[]) () =
    div [] [...]

// Use?
ofFunction2 (MyComponent "foo" 5 []) []

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

์›์น™์ ์œผ๋กœ F#์˜ ๋งˆ๋ฒ• ์†์„ฑ์€ ์ตœ๋Œ€ํ•œ ํ”ผํ•˜๊ณ  ์‹ถ์—ˆ์ง€๋งŒ ์ด ๊ฒฝ์šฐ์—๋Š” ์ •๋‹นํ™”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์•ˆ์€ ์ต๋ช… ๋ ˆ์ฝ”๋“œ๊ฐ€ F#์— ๋“ค์–ด์˜ฌ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ด ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ณ  ์šฐ๋ฆฌ๋Š” ํ‘œ์ค€ F#์— ๋งž์ถœ ๊ฒƒ์ด๋ฉฐ F# ๋ฏธ๋ฆฌ ๋ณด๊ธฐ์—์„œ ์ดˆ๊ธฐ์— ์žˆ์„ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค .

discussion

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

์ต๋ช… ๋ ˆ์ฝ”๋“œ๋Š” ์—ฌ์ „ํžˆ ๋งค์šฐ ์žฅํ™ฉํ•ฉ๋‹ˆ๋‹ค.

// Declaration
let userView = namedMemo "User" (fun ({| UserId: string; Name: string |}) ->
    a [Href (sprintf "/%s/" props.UserId)] [str props.Name])

// Usage
ofElementType userView { UserId = "vbfox"; Name = "Julien Roncaglia" } []

์ •์ƒ ๊ธฐ๋ก:

// Declaration
type UserViewProps = { UserId: string; Name: string }
let userView = namedMemo "User" (fun props ->
    a [Href (sprintf "/%s/" props.UserId)] [str props.Name])

// Usage
ofElementType userView { UserId = "vbfox"; Name = "Julien Roncaglia" } []

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

@alfonsogarciacaro ์ด

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

๋Œ€์•ˆ์€ ์ต๋ช… ๋ ˆ์ฝ”๋“œ๊ฐ€ F#์— ๋“ค์–ด์˜ฌ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

์ต๋ช…์˜ F# ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์— ์ฐฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ต๋ช… ๋ ˆ์ฝ”๋“œ๋Š” ์—ฌ์ „ํžˆ ๋งค์šฐ ์žฅํ™ฉํ•ฉ๋‹ˆ๋‹ค.

// Declaration
let userView = namedMemo "User" (fun ({| UserId: string; Name: string |}) ->
    a [Href (sprintf "/%s/" props.UserId)] [str props.Name])

// Usage
ofElementType userView { UserId = "vbfox"; Name = "Julien Roncaglia" } []

์ •์ƒ ๊ธฐ๋ก:

// Declaration
type UserViewProps = { UserId: string; Name: string }
let userView = namedMemo "User" (fun props ->
    a [Href (sprintf "/%s/" props.UserId)] [str props.Name])

// Usage
ofElementType userView { UserId = "vbfox"; Name = "Julien Roncaglia" } []

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

@alfonsogarciacaro ์ด

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

๊ด€๋ จ ๋ฌธ์ œ

jwosty picture jwosty  ยท  3์ฝ”๋ฉ˜ํŠธ

et1975 picture et1975  ยท  3์ฝ”๋ฉ˜ํŠธ

MangelMaxime picture MangelMaxime  ยท  3์ฝ”๋ฉ˜ํŠธ

ncave picture ncave  ยท  3์ฝ”๋ฉ˜ํŠธ

nozzlegear picture nozzlegear  ยท  3์ฝ”๋ฉ˜ํŠธ