diff --git a/May/article/React Compiler.md b/May/article/React Compiler.md new file mode 100644 index 0000000..b971bc8 --- /dev/null +++ b/May/article/React Compiler.md @@ -0,0 +1,523 @@ +## ๐Ÿ”— [React Compiler](https://react.dev/learn/react-compiler) + +### ๐Ÿ—“๏ธ ๋ฒˆ์—ญ ๋‚ ์งœ: 2024.06.01 + +### ๐Ÿงš ๋ฒˆ์—ญํ•œ ํฌ๋ฃจ: ๋ฒ„๊ฑด๋””(์ „ํƒœํ—Œ) + +--- + +# ๋ฆฌ์•กํŠธ ์ปดํŒŒ์ผ๋Ÿฌ + +This page will give you an introduction to the new experimental React Compiler and how to try it out successfully. + +์ด ํŽ˜์ด์ง€๋Š” ์ƒˆ๋กญ์ง€๋งŒ ์•„์ง์€ ์‹คํ—˜์ ์ธ ๋ฆฌ์•กํŠธ ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์‹œ๋„ํ•ด๋ณผ์ˆ˜ ์žˆ์„์ง€ ์„ค๋ช… ํ•ฉ๋‹ˆ๋‹ค. + +> ์ด ๋ฌธ์„œ๋Š” ์•„์ง ์ž‘์—… ์ค‘์ž…๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ๋ฌธ์„œ๋Š” [React Compiler Working Group](https://github.com/reactwg/react-compiler/discussions) ์ €์žฅ์†Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฌธ์„œ๊ฐ€ ๋” ์•ˆ์ •ํ™”๋˜๋ฉด ์ด ๋ฌธ์„œ๋กœ ์—…์ŠคํŠธ๋ฆผ๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. + +## ์ด๋Ÿฐ๊ฑธ ๋ฐฐ์šฐ์‹œ๊ฒŒ ๋ ๊ฑฐ์—์š” + +1. ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์–ด๋–ป๊ฒŒ ์‹œ์ž‘ํ•˜๋Š”์ง€ +2. ์ปดํŒŒ์ผ๋Ÿฌ์™€ eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๋Š” ๋ฒ• +3. ๋ฌธ์ œ ํ•ด๊ฒฐ + +### ์ฃผ์˜ ์‚ฌํ•ญ + +React Compiler๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์˜คํ”ˆ ์†Œ์Šคํ™”๋œ ์ƒˆ๋กœ์šด ์‹คํ—˜์  ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. ์•„์ง ์™„๋ฒฝํ•˜์ง€ ์•Š์œผ๋ฉฐ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์‚ฌ์šฉํ•˜๊ธฐ์— ์ค€๋น„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. + +React Compiler๋Š” React 19 RC๋ฅผ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. + +๋งŒ์•ฝ React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์—†๋‹ค๋ฉด, [Working Group](<(https://github.com/reactwg/react-compiler/discussions/6)>)์—์„œ ์„ค๋ช…๋œ ์บ์‹œ ํ•จ์ˆ˜์˜ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ๊ตฌํ˜„์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +React Compiler๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ๋ถ€ํ„ฐ ์ดˆ๊ธฐ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์˜คํ”ˆ ์†Œ์Šคํ™”๋œ ์ƒˆ๋กœ์šด ์‹คํ—˜์  ์ปดํŒŒ์ผ๋Ÿฌ์ž…๋‹ˆ๋‹ค. + +์ด๋Š” ๋นŒ๋“œ ํƒ€์ž„ ์ „์šฉ ๋„๊ตฌ๋กœ, React ์•ฑ์„ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ˆœ์ˆ˜ JavaScript์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋ฉฐ, [React์˜ ๊ทœ์น™](https://react.dev/reference/rules)์„ ์ดํ•ดํ•˜๋ฏ€๋กœ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. + +์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋˜ํ•œ ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ์—๋””ํ„ฐ ๋‚ด์—์„œ ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” [eslint ํ”Œ๋Ÿฌ๊ทธ์ธ](https://react.dev/learn/react-compiler#installing-eslint-plugin-react-compiler)์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉฐ, ์•ฑ์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๋ชจ๋“  React ๊ฐœ๋ฐœ์ž๋“ค์ด ์ด eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ํ’ˆ์งˆ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” ๊ถŒ์žฅ๋˜์ง€ ์•Š์œผ๋ฉฐ ๊ฐ€๋Šฅํ•  ๋•Œ React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. + +## ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฌด์—‡์„ ํ•˜๋‚˜์š”? + +์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด React Compiler๋Š” ์ž๋™์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization)ํ•ฉ๋‹ˆ๋‹ค. + +์˜ค๋Š˜๋‚  `useMemo`, `useCallback`, `React.memo`์™€ ๊ฐ™์€ API๋ฅผ ํ†ตํ•ด ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ‘ํ•ด๋ณด์…จ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +์ด๋Ÿฌํ•œ API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž…๋ ฅ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์„ ๋•Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํŠน์ • ๋ถ€๋ถ„์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๊ณ  React์— ์•Œ๋ฆด ์ˆ˜ ์žˆ์–ด ์—…๋ฐ์ดํŠธ ์ž‘์—…์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +ํ•˜์ง€๋งŒ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์ž„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์„ ์žŠ๊ฑฐ๋‚˜ ์ž˜๋ชป ์ ์šฉํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. + +์ด๋กœ ์ธํ•ด React๊ฐ€ ์˜๋ฏธ ์žˆ๋Š” ๋ณ€๊ฒฝ์ด ์—†๋Š” UI ๋ถ€๋ถ„์„ ํ™•์ธํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋น„ํšจ์œจ์ ์ธ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +React Compiler๋Š” JavaScript์™€ React์˜ ๊ทœ์น™์— ๋Œ€ํ•œ ์ง€์‹์„ ํ™œ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ์™€ ํ›… ๋‚ด์˜ ๊ฐ’์ด๋‚˜ ๊ฐ’ ๊ทธ๋ฃน์„ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค. + +๊ทœ์น™ ์œ„๋ฐ˜์ด ๊ฐ์ง€๋˜๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…๋งŒ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ๊ณ„์† ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. + +์ด๋ฏธ ์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ ์ž˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋˜์–ด ์žˆ๋‹ค๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ํฐ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +ํ•˜์ง€๋งŒ ์‹ค์งˆ์ ์œผ๋กœ๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š” ์ •ํ™•ํ•œ ์ข…์†์„ฑ์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜๋Š” ๊ฒƒ์ด ์†์œผ๋กœ ํ•˜๊ธฐ์—๋Š” ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค. + +## - ๋ฆฌ์•กํŠธ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฌด์Šจ ์ข…๋ฅ˜์˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ํ•˜๋‚˜์š” ? + +React ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ดˆ๊ธฐ ๋ฒ„์ „์€ ์—…๋ฐ์ดํŠธ ์„ฑ๋Šฅ(๊ธฐ์กด ์ปดํฌ๋„ŒํŠธ์˜ ๋‹ค์‹œ ๋ Œ๋”๋ง)์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋ž˜์„œ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ง‘์ค‘ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค: + +1. **๊ณ„๋‹จ์‹์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋‹ค์‹œ ๋ Œ๋”๋ง ๊ฑด๋„ˆ๋›ฐ๊ธฐ** + +`` ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ๋•Œ, ์‹ค์ œ๋กœ๋Š” ``๋งŒ ๋ณ€๊ฒฝ๋˜์—ˆ์ง€๋งŒ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์˜ ๋งŽ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ์ƒํ™ฉ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. + +2. **React ์™ธ๋ถ€์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ ๊ฑด๋„ˆ๋›ฐ๊ธฐ** + +์˜ˆ๋ฅผ ๋“ค์–ด, ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›… ๋‚ด๋ถ€์—์„œ `expensivelyProcessAReallyLargeArrayOfObjects()`์™€ ๊ฐ™์€ ๋Œ€์šฉ๋Ÿ‰ ๋ฐฐ์—ด ๊ฐ์ฒด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. + +### ๋ฆฌ๋ Œ๋”๋ง ์ตœ์ ํ™” + +React๋Š” ํ˜„์žฌ ์ƒํƒœ(๊ตฌ์ฒด์ ์œผ๋กœ๋Š” props, state, ๊ทธ๋ฆฌ๊ณ  context)์— ๋”ฐ๋ผ UI๋ฅผ ํ•จ์ˆ˜๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. + +ํ˜„์žฌ ๊ตฌํ˜„ ๋ฐฉ์‹์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ React๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์™€ ๊ทธ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจ๋‘ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. + +๋‹จ, useMemo(), useCallback(), ๋˜๋Š” React.memo()์™€ ๊ฐ™์€ ์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์šฉํ•œ ๊ฒฝ์šฐ๋Š” ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค. + +์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ์˜ˆ์ œ์—์„œ ``์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ``์ด ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. + +```tsx +function FriendList({ friends }) { + const onlineCount = useFriendOnlineCount(); + if (friends.length === 0) { + return ; + } + return ( +
+ {onlineCount} online + {friends.map((friend) => ( + + ))} + +
+ ); +} +``` + +[๋ฆฌ์•กํŠธ ์ปดํŒŒ์ผ๋Ÿฌ ์˜ˆ์ œ ์‚ฌ์ดํŠธ์—์„œ ํ™•์ธํ•ด๋ณด์„ธ์š”](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAMygOzgFwJYSYAEAYjHgpgCYAyeYOAFMEWuZVWEQL4CURwADrEicQgyKEANnkwIAwtEw4iAXiJQwCMhWoB5TDLmKsTXgG5hRInjRFGbXZwB0UygHMcACzWr1ABn4hEWsYBBxYYgAeADkIHQ4uAHoAPksRbisiMIiYYkYs6yiqPAA3FMLrIiiwAAcAQ0wU4GlZBSUcbklDNqikusaKkKrgR0TnAFt62sYHdmp+VRT7SqrqhOo6Bnl6mCoiAGsEAE9VUfmqZzwqLrHqM7ubolTVol5eTOGigFkEMDB6u4EAAhKA4HCEZ5DNZ9ErlLIWYTcEDcIA) + +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ˆ˜๋™ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๊ณผ ๋™๋“ฑํ•œ ์ž‘์—…์„ ์ž๋™์œผ๋กœ ์ ์šฉํ•˜์—ฌ ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ์•ฑ์˜ ๊ด€๋ จ ๋ถ€๋ถ„๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. + +์ด๋ฅผ ๋•Œ๋กœ๋Š”`์„ธ๋ฐ€ํ•œ ๋ฐ˜์‘์„ฑ(fine-grained reactivity)`์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. + +์œ„์˜ ์˜ˆ์—์„œ React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” friends๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ``์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ์„ ํŒ๋‹จํ•˜๊ณ , ์ด JSX๋ฅผ ๋‹ค์‹œ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ count๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ``์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. + +### ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ๋„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋ฉ๋‹ˆ๋‹ค. + +์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ Œ๋”๋ง ์ค‘์— ์‚ฌ์šฉ๋˜๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ์— ๋Œ€ํ•ด์„œ๋„ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```tsx +// ์ด๊ฒƒ์€ ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ์•กํŠธ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. +function expensivelyProcessAReallyLargeArrayOfObjects() { + /* ... */ +} + +// ์ด๊ฒƒ์€ ์ปดํฌ๋„ŒํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ์•กํŠธ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•ฉ๋‹ˆ๋‹ค. +function TableContainer({ items }) { + // ์ด ํ•จ์ˆ˜๋Š” ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋ฉ๋‹ˆ๋‹ค. + const data = expensivelyProcessAReallyLargeArrayOfObjects(items); + // ... +} +``` + +[๋ฆฌ์•กํŠธ ์ปดํŒŒ์ผ๋Ÿฌ ์˜ˆ์ œ ์‚ฌ์ดํŠธ์—์„œ ํ™•์ธํ•ด๋ณด์„ธ์š”](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAejQAgFTYHIQAuumAtgqRAJYBeCAJpgEYCemASggIZyGYDCEUgAcqAGwQwANJjBUAdokyEAFlTCZ1meUUxdMcIcIjyE8vhBiYVECAGsAOvIBmURYSonMCAB7CzcgBuCGIsAAowEIhgYACCnFxioQAyXDAA5gixMDBcLADyzvlMAFYIvGAAFACUmMCYaNiYAHStOFgAvk5OGJgAshTUdIysHNy8AkbikrIKSqpaWvqGIiZmhE6u7p7ymAAqXEwSguZcCpKV9VSEFBodtcBOmAYmYHz0XIT6ALzefgFUYKhCJRBAxeLcJIsVIZLI5PKFYplCqVa63aoAbm6u0wMAQhFguwAPPRAQA+YAfL4dIloUmBMlODogDpAA) + +๊ทธ๋Ÿฌ๋‚˜ `expensivelyProcessAReallyLargeArrayOfObjects`๊ฐ€ ์ •๋ง๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ํ•จ์ˆ˜๋ผ๋ฉด, React ์™ธ๋ถ€์—์„œ ์ž์ฒด์ ์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š”: + +- React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React ์ปดํฌ๋„ŒํŠธ์™€ ํ›…๋งŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜๋ฉฐ, ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +- React ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…์—์„œ ๊ณต์œ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ `expensivelyProcessAReallyLargeArrayOfObjects`๊ฐ€ ์—ฌ๋Ÿฌ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด, ๋™์ผํ•œ ํ•ญ๋ชฉ์ด ์ „๋‹ฌ๋˜๋”๋ผ๋„ ๊ทธ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๊ณ„์‚ฐ์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +์ฝ”๋“œ๊ฐ€ ๋” ๋ณต์žกํ•ด์ง€๊ธฐ ์ „์— ๋จผ์ € [ํ”„๋กœํŒŒ์ผ๋ง](https://react.dev/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive)์„ ํ†ตํ•ด ์‹ค์ œ๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. + +## ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฌด์—‡์„ ๊ฐ€์ •ํ• ๊นŒ์š” ? + +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌํ•ญ์„ ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค: + +1. ์œ ํšจํ•˜๊ณ  ์˜๋ฏธ๋ก ์ ์ธ JavaScript ์ฝ”๋“œ: + +2. ์ฝ”๋“œ๊ฐ€ ์œ ํšจํ•˜๊ณ  ์˜๋ฏธ๋ก ์ ์ธ JavaScript๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + ๋„ ๊ฐ€๋Šฅ/์˜ต์…˜ ๊ฐ’ ๋ฐ ์†์„ฑ์˜ ์ •์˜ ์—ฌ๋ถ€๋ฅผ ํ…Œ์ŠคํŠธ: + +๋„ ๊ฐ€๋Šฅ(nullable)ํ•˜๊ฑฐ๋‚˜ ์˜ต์…˜(optional)์ธ ๊ฐ’๊ณผ ์†์„ฑ์„ ์ ‘๊ทผํ•˜๊ธฐ ์ „์— ์ •์˜๋˜์–ด ์žˆ๋Š”์ง€ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค. + +์˜ˆ๋ฅผ ๋“ค์–ด, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ [strictNullChecks](https://www.typescriptlang.org/tsconfig/#strictNullChecks)๋ฅผ ํ™œ์„ฑํ™”ํ•˜์—ฌ if `(object.nullableProperty) { object.nullableProperty.foo }` ๋˜๋Š” ์˜ต์…”๋„ ์ฒด์ด๋‹์„ ์‚ฌ์šฉํ•˜์—ฌ `object.nullableProperty?.foo`์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +3. [React์˜ ๊ทœ์น™](https://react.dev/reference/rules)์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. + +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” React์˜ ๊ทœ์น™์„ ์ •์ ์œผ๋กœ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์˜ค๋ฅ˜๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์•ˆ์ „ํ•˜๊ฒŒ ์ปดํŒŒ์ผ์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. + +์˜ค๋ฅ˜๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด [eslint-plugin-react-compiler](https://www.npmjs.com/package/eslint-plugin-react-compiler)๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. + +## ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ๋„ํ•ด๋ด์•ผ ํ• ๊นŒ์š”? + +์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์•„์ง ์‹คํ—˜์ ์ธ ๋‹จ๊ณ„์— ์žˆ์œผ๋ฉฐ, ๋งŽ์€ ๋ถ€๋ถ„์ด ๋ฏธ์™„์„ฑ ์ƒํƒœ์ž„์„ ์œ ์˜ํ•˜์„ธ์š”. + +Meta์™€ ๊ฐ™์€ ํšŒ์‚ฌ์—์„œ ํ”„๋กœ๋•์…˜์— ์‚ฌ์šฉ๋˜์—ˆ์ง€๋งŒ, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์—ฌ๋Ÿฌ๋ถ„์˜ ์•ฑ ํ”„๋กœ๋•์…˜์— ๋„์ž…ํ• ์ง€๋Š” ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ์ƒํƒœ์™€ [React์˜ ๊ทœ์น™](https://react.dev/reference/rules)์„ ์–ผ๋งˆ๋‚˜ ์ž˜ ์ค€์ˆ˜ํ–ˆ๋Š”์ง€์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. + +**์ง€๊ธˆ ๋‹น์žฅ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.** + +**์•ˆ์ •๋œ ๋ฆด๋ฆฌ์Šค๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋„์ž…ํ•ด๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.** + +ํ•˜์ง€๋งŒ, ์•ฑ์—์„œ ์ž‘์€ ์‹คํ—˜์„ ํ†ตํ•ด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ๋„ํ•ด๋ณด๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•ด ์ฃผ์‹œ๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋”์šฑ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. + +## ์‹œ์ž‘ํ•˜๊ธฐ + +์ด ๋ฌธ์„œ๋“ค ์™ธ์—๋„, React ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด์™€ ๋…ผ์˜๋ฅผ ์œ„ํ•ด [React Compiler Working Group](https://github.com/reactwg/react-compiler)์„ ํ™•์ธํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค. + +## ํ˜ธํ™˜์„ฑ ํ™•์ธ + +์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์„ค์น˜ํ•˜๊ธฐ ์ „์—, ๋จผ์ € ์ฝ”๋“œ๋ฒ ์ด์Šค๊ฐ€ ํ˜ธํ™˜๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: + +``` +npx react-compiler-healthcheck@latest +``` + +์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค: + +- ์ตœ์ ํ™”์— ์„ฑ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ˆ˜๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค: ์ˆซ์ž๊ฐ€ ํด์ˆ˜๋ก ์ข‹์Šต๋‹ˆ๋‹ค. + +- `` ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค: ์ด๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ  ๋”ฐ๋ฅด๋Š” ๊ฒฝ์šฐ [React์˜ ๊ทœ์น™](https://react.dev/reference/rules)์„ ๋”ฐ๋ฅผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์ง‘๋‹ˆ๋‹ค. + +- ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค: ์ปดํŒŒ์ผ๋Ÿฌ์™€ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ์•Œ๋ ค์ง„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค. + +``` +Successfully compiled 8 out of 9 components. +StrictMode usage not found. +Found no usage of incompatible libraries. +``` + +## eslint-plugin-react-compiler ์„ค์น˜ + +React ์ปดํŒŒ์ผ๋Ÿฌ๋Š” eslint ํ”Œ๋Ÿฌ๊ทธ์ธ๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. + +์ด eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +``` +npm install eslint-plugin-react-compiler +``` + +๊ทธ๋ฆฌ๊ณ , eslint config์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”. + +```ts +module.exports = { + plugins: ["eslint-plugin-react-compiler"], + rules: { + "react-compiler/react-compiler": "error", + }, +}; +``` + +eslint ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์—๋””ํ„ฐ์—์„œ React์˜ ๊ทœ์น™ ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. + +์ด ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…์˜ ์ตœ์ ํ™”๋ฅผ ๊ฑด๋„ˆ๋›ด๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. + +์ด๋Š” ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ๋ณต๊ตฌํ•˜๊ณ  ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +**๋ชจ๋“  eslint ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ์ˆ˜์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.** + +์ตœ์ ํ™”๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ ํ›…์˜ ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๊ธฐ ์œ„ํ•ด ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ด๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ๊ฒƒ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. + +## ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ฝ”๋“œ๋ฒ ์ด์Šค์— ๋„์ž…ํ•˜๊ธฐ + +### ๊ธฐ์กด ํ”„๋กœ์ ํŠธ + +์ปดํŒŒ์ผ๋Ÿฌ๋Š” [React์˜ ๊ทœ์น™](https://react.dev/reference/rules)์„ ๋”ฐ๋ฅด๋Š” ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์™€ ํ›…์„ ์ปดํŒŒ์ผํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. + +๋˜ํ•œ, ํ•ด๋‹น ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…์„ ๊ฑด๋„ˆ๋›ฐ๋„๋ก ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ JavaScript์˜ ์œ ์—ฐํ•œ ํŠน์„ฑ ๋•Œ๋ฌธ์—, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ชจ๋“  ์œ„๋ฐ˜์„ ์žก์•„๋‚ด์ง€๋Š” ๋ชปํ•˜๋ฉฐ, ์ž˜๋ชป๋œ ๊ธ์ •(false negative)์œผ๋กœ ์ธํ•ด ๊ทœ์น™์„ ์œ„๋ฐ˜ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…์„ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด๋Š” ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด๋Ÿฌํ•œ ์ด์œ ๋กœ, ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์—์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋„์ž…ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ œํ’ˆ ์ฝ”๋“œ์˜ ์ž‘์€ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๋จผ์ € ์‹คํ–‰ํ•ด๋ณด๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. + +์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํŠน์ • ๋””๋ ‰ํ† ๋ฆฌ ์ง‘ํ•ฉ์—์„œ๋งŒ ์‹คํ–‰ํ•˜๋„๋ก ์„ค์ •ํ•˜์—ฌ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: + +```ts +const ReactCompilerConfig = { + sources: (filename) => { + return filename.indexOf("src/path/to/dir") !== -1; + }, +}; +``` + +๋“œ๋ฌธ ๊ฒฝ์šฐ์ด์ง€๋งŒ, `compilationMode: "annotation"` ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ "์˜ตํŠธ์ธ" ๋ชจ๋“œ๋กœ ์‹คํ–‰ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด `"use memo"` ์ง€์‹œ์–ด๊ฐ€ ์ฃผ์„๋œ ์ปดํฌ๋„ŒํŠธ์™€ ํ›…๋งŒ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. + +์ฃผ์„ ๋ชจ๋“œ๋Š” ์ดˆ๊ธฐ ๋„์ž…์ž๋ฅผ ๋•๊ธฐ ์œ„ํ•œ ์ž„์‹œ์ ์ธ ๊ฒƒ์ด๋ฉฐ, "use memo" ์ง€์‹œ์–ด๊ฐ€ ์žฅ๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ๋ฅผ ์˜๋„ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. + +```ts +const ReactCompilerConfig = { + compilationMode: "annotation", +}; + +// src/app.jsx +export default function App() { + "use memo"; + // ... +} +``` + +์ปดํŒŒ์ผ๋Ÿฌ ๋„์ž…์— ๋Œ€ํ•œ ํ™•์‹ ์ด ์ƒ๊ธฐ๋ฉด, ๋‹ค๋ฅธ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ํ™•์žฅํ•˜์—ฌ ์ ์ฐจ ์ „์ฒด ์•ฑ์œผ๋กœ ๋ฒ”์œ„๋ฅผ ๋„“ํž ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +### ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ + +์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ „์ฒด ์ฝ”๋“œ๋ฒ ์ด์Šค์— ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ๊ธฐ๋ณธ ๋™์ž‘์ž…๋‹ˆ๋‹ค. + +### ์‚ฌ์šฉ๋ฒ• + +### Babel + +``` +npm install babel-plugin-react-compiler +``` + +์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋นŒ๋“œ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +์„ค์น˜ ํ›„, Babel ์„ค์ •์— ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ **๊ฐ€์žฅ ๋จผ์ €** ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค: + +```ts +// babel.config.js +const ReactCompilerConfig = { + /* ... */ +}; + +module.exports = function () { + return { + plugins: [ + ["babel-plugin-react-compiler", ReactCompilerConfig], // ๊ฐ€์žฅ ๋จผ์ € ์‹คํ–‰ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค! + // ... + ], + }; +}; +``` + +`babel-plugin-react-compiler`๋Š” ๋‹ค๋ฅธ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ •ํ™•ํ•œ ๋ถ„์„์„ ์œ„ํ•ด ์ž…๋ ฅ ์†Œ์Šค ์ •๋ณด๋ฅผ ํ•„์š”๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. + +## Vite + +๋งŒ์•ฝ Vite๋ฅผ ์‚ฌ์šฉํ•˜์‹ ๋‹ค๋ฉด, ์„ค์ • ํŒŒ์ผ์— ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋„ฃ์œผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```ts +// vite.config.js +const ReactCompilerConfig = { + /* ... */ +}; + +export default defineConfig(() => { + return { + plugins: [ + react({ + babel: { + plugins: [["babel-plugin-react-compiler", ReactCompilerConfig]], + }, + }), + ], + // ... + }; +}); +``` + +## Next.js + +Next.js๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•œ ์‹คํ—˜์  ์„ค์ •์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ์„ค์ •์€ `babel-plugin-react-compiler`๊ฐ€ ์ž๋™์œผ๋กœ ์„ค์ •๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. + +- Next.js canary๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”. ์ด๋Š” React 19 Release Candidate๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. + +- `babel-plugin-react-compiler`๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”. + +``` +npm install next@canary babel-plugin-react-compiler +``` + +๊ทธ ํ›„์—, `next.config.js`์—์„œ ์‹คํ—˜์ ์ธ ์˜ต์…˜์„ ์„ค์ •ํ•ด์ฃผ์„ธ์š”. + +```ts +// next.config.js +/** @type {import('next').NextConfig} */ +const nextConfig = { + experimental: { + reactCompiler: true, + }, +}; + +module.exports = nextConfig; +``` + +์‹คํ—˜์  ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ์—์„œ React ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ์ง€์›์ด ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค: + +- ์•ฑ ๋ผ์šฐํ„ฐ(App Router) + +- ํŽ˜์ด์ง€ ๋ผ์šฐํ„ฐ(Pages Router) + +- ์›นํŒฉ(Webpack) (๊ธฐ๋ณธ ์„ค์ •) + +- ํ„ฐ๋ณดํŒฉ(Turbopack) (์˜ต์…˜์œผ๋กœ --turbo๋ฅผ ํ†ตํ•ด ํ™œ์„ฑํ™”) + +## - Remix + +`vite-plugin-babel`์„ ์„ค์น˜ํ•˜์‹œ๊ณ , ํ•ด๋‹น ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”. + +``` +npm install vite-plugin-babel +``` + +```ts +// vite.config.js +import babel from "vite-plugin-babel"; + +const ReactCompilerConfig = { + /* ... */ +}; + +export default defineConfig({ + plugins: [ + remix({ + /* ... */ + }), + babel({ + filter: /\.[jt]sx?$/, + babelConfig: { + presets: ["@babel/preset-typescript"], // if you use TypeScript + plugins: [["babel-plugin-react-compiler", ReactCompilerConfig]], + }, + }), + ], +}); +``` + +## Webpack + +์ด ์ฒ˜๋Ÿผ ๋ณธ์ธ๋งŒ์˜ React Compiler๋ฅผ ์œ„ํ•œ ๋กœ๋”๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +```ts +const ReactCompilerConfig = { /* ... */ }; +const BabelPluginReactCompiler = require('babel-plugin-react-compiler'); + +function reactCompilerLoader(sourceCode, sourceMap) { + // ... + const result = transformSync(sourceCode, { + // ... + plugins: [ + [BabelPluginReactCompiler, ReactCompilerConfig], + ], + // ... + }); + + if (result === null) { + this.callback( + Error( + `Failed to transform "${options.filename}"` + ) + ); + return; + } + + this.callback( + null, + result.code + result.map === null ? undefined : result.map + ); +} + +module.exports = reactCompilerLoader; +``` + +## Expo + +Expo๋Š” Metro๋ฅผ ํ†ตํ•ด Babel์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ์„ค์น˜ ์ง€์นจ์€ [Babel ์‚ฌ์šฉ ์„น์…˜](https://react.dev/learn/react-compiler#usage-with-babel)์„ ์ฐธ์กฐํ•˜์„ธ์š”. + +## Metro (React Native) + +React Native๋Š” Metro๋ฅผ ํ†ตํ•ด Babel์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ์„ค์น˜ ์ง€์นจ์€ [Babel ์‚ฌ์šฉ ์„น์…˜](https://react.dev/learn/react-compiler#usage-with-babel)์„ ์ฐธ์กฐํ•˜์„ธ์š”. + +## ๋ฌธ์ œ ํ•ด๊ฒฐ + +์ด์Šˆ๋ฅผ ๋ณด๊ณ ํ•˜๋ ค๋ฉด ๋จผ์ € [React Compiler Playground](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAejQAgFTYHIQAuumAtgqRAJYBeCAJpgEYCemASggIZyGYDCEUgAcqAGwQwANJjBUAdokyEAFlTCZ1meUUxdMcIcIjyE8vhBiYVECAGsAOvIBmURYSonMCAB7CzcgBuCGIsAAowEIhgYACCnFxioQAyXDAA5gixMDBcLADyzvlMAFYIvGAAFACUmMCYaNiYAHStOFgAvk5OGJgAshTUdIysHNy8AkbikrIKSqpaWvqGIiZmhE6u7p7ymAAqXEwSguZcCpKV9VSEFBodtcBOmAYmYHz0XIT6ALzefgFUYKhCJRBAxeLcJIsVIZLI5PKFYplCqVa63aoAbm6u0wMAQhFguwAPPRAQA+YAfL4dIloUmBMlODogDpAA)์—์„œ ์ตœ์†Œ ์žฌํ˜„ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ์— ํฌํ•จํ•˜์„ธ์š”. + +์ด์Šˆ๋Š” [facebook/react ์ €์žฅ์†Œ](https://github.com/facebook/react/issues)์— ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +React Compiler Working Group์— ๊ฐ€์ž…ํ•˜์—ฌ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. + +[๊ฐ€์ž…์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ README๋ฅผ ์ฐธ์กฐ](https://github.com/reactwg/react-compiler)ํ•˜์„ธ์š”. + +## (0 , \_c) is not a function ์˜ค๋ฅ˜ + +์ด ์˜ค๋ฅ˜๋Š” React 19 RC ์ด์ƒ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. + +์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ์•ฑ์„ [React 19 RC๋กœ ์—…๊ทธ๋ ˆ์ด๋“œ](https://react.dev/blog/2024/04/25/react-19-upgrade-guide)ํ•˜์„ธ์š”. + +React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, [Working Group](https://github.com/reactwg/react-compiler/discussions/6)์—์„œ ์„ค๋ช…ํ•œ ์บ์‹œ ํ•จ์ˆ˜์˜ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ๊ตฌํ˜„์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” ๊ถŒ์žฅ๋˜์ง€ ์•Š์œผ๋ฉฐ ๊ฐ€๋Šฅํ•œ ํ•œ ๋นจ๋ฆฌ React 19๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +## ๋‚ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ตœ์ ํ™”๋˜์—ˆ๋Š”์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ๋‚˜์š”? + +[React Devtools(v5.0+)](https://react.dev/learn/react-developer-tools)๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ์— ๋Œ€ํ•œ ๋‚ด์žฅ ์ง€์›์„ ์ œ๊ณตํ•˜๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ตœ์ ํ™”๋œ ์ปดํฌ๋„ŒํŠธ ์˜†์— "Memo โœจ" ๋ฐฐ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. + +## ์ปดํŒŒ์ผ ํ›„ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ + +eslint-plugin-react-compiler๋ฅผ ์„ค์น˜ํ•œ ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์—๋””ํ„ฐ์—์„œ React ๊ทœ์น™ ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. + +์ด ๊ฒฝ์šฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…์˜ ์ตœ์ ํ™”๋ฅผ ๊ฑด๋„ˆ๋›ฐ์—ˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. + +์ด๋Š” ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋ฉฐ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด๋ฅผ ๋ณต๊ตฌํ•˜๊ณ  ์ฝ”๋“œ๋ฒ ์ด์Šค์˜ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ณ„์†ํ•ด์„œ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๋ชจ๋“  eslint ์œ„๋ฐ˜ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ์ˆ˜์ •ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. + +์ตœ์ ํ™”๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ ํ›…์˜ ์ˆ˜๋ฅผ ๋Š˜๋ฆฌ๊ธฐ ์œ„ํ•ด ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ด๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ JavaScript์˜ ์œ ์—ฐํ•˜๊ณ  ๋™์ ์ธ ํŠน์„ฑ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ํฌ๊ด„์ ์œผ๋กœ ๊ฐ์ง€ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. + +์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ์— ๋ฌดํ•œ ๋ฃจํ”„์™€ ๊ฐ™์€ ๋ฒ„๊ทธ๋‚˜ ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ปดํŒŒ์ผ ํ›„ ์•ฑ์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๊ณ  eslint ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž˜๋ชป ์ปดํŒŒ์ผํ–ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ๊ด€๋ จ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…์„ `"use no memo"` ์ง€์‹œ์–ด๋ฅผ ํ†ตํ•ด ๊ฐ•์ œ๋กœ ์˜ตํŠธ์•„์›ƒํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์„ธ์š”. + +```ts +function SuspiciousComponent() { + "use no memo"; // ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ React ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋„๋ก ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค. + // ... +} +``` + +## ์•Œ์•„๋‘์–ด์•ผ ํ•  ์  + +> "use no memo" + +`"use no memo"`๋Š” React ์ปดํŒŒ์ผ๋Ÿฌ์— ์˜ํ•ด ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋„๋ก ์ปดํฌ๋„ŒํŠธ์™€ ํ›…์„ ๋ฐฐ์ œํ•  ์ˆ˜ ์žˆ๋Š” ์ž„์‹œ ํƒˆ์ถœ๊ตฌ์ž…๋‹ˆ๋‹ค. + +์ด ์ง€์‹œ์–ด๋Š” "use client"์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์žฅ๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. + +์ด ์ง€์‹œ์–ด๋Š” ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +์ผ๋‹จ ์ปดํฌ๋„ŒํŠธ๋‚˜ ํ›…์„ ๋ฐฐ์ œํ•˜๋ฉด, ์ง€์‹œ์–ด๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์˜๊ตฌ์ ์œผ๋กœ ๋ฐฐ์ œ๋œ ์ƒํƒœ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. + +์ฆ‰, ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋”๋ผ๋„ ์ง€์‹œ์–ด๋ฅผ ์ œ๊ฑฐํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์—ฌ์ „ํžˆ ์ปดํŒŒ์ผ์„ ๊ฑด๋„ˆ๋›ฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. + +์˜ค๋ฅ˜๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด, ์˜ตํŠธ์•„์›ƒ ์ง€์‹œ์–ด๋ฅผ ์ œ๊ฑฐํ–ˆ์„ ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋‹ค์‹œ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. + +๊ทธ๋Ÿฐ ๋‹ค์Œ [React Compiler Playground](https://playground.react.dev/#N4Igzg9grgTgxgUxALhAejQAgFTYHIQAuumAtgqRAJYBeCAJpgEYCemASggIZyGYDCEUgAcqAGwQwANJjBUAdokyEAFlTCZ1meUUxdMcIcIjyE8vhBiYVECAGsAOvIBmURYSonMCAB7CzcgBuCGIsAAowEIhgYACCnFxioQAyXDAA5gixMDBcLADyzvlMAFYIvGAAFACUmMCYaNiYAHStOFgAvk5OGJgAshTUdIysHNy8AkbikrIKSqpaWvqGIiZmhE6u7p7ymAAqXEwSguZcCpKV9VSEFBodtcBOmAYmYHz0XIT6ALzefgFUYKhCJRBAxeLcJIsVIZLI5PKFYplCqVa63aoAbm6u0wMAQhFguwAPPRAQA+YAfL4dIloUmBMlODogDpAA)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”. + +๋ฌธ์ œ๋ฅผ ์ž‘์€ ์žฌํ˜„ ์˜ˆ์ œ๋กœ ์ค„์ด๊ฑฐ๋‚˜, ์˜คํ”ˆ ์†Œ์Šค ์ฝ”๋“œ์ธ ๊ฒฝ์šฐ ์ „์ฒด ์†Œ์Šค๋ฅผ ๋ถ™์—ฌ๋„ฃ์–ด๋„ ๋ฉ๋‹ˆ๋‹ค. + +์ด๋ฅผ ํ†ตํ•ด ๋ฌธ์ œ๋ฅผ ์‹๋ณ„ํ•˜๊ณ  ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. + +## ๋‹ค๋ฅธ ์ด์Šˆ๋“ค + +[์ด ๊ณณ](https://github.com/reactwg/react-compiler/discussions/7)์— ์ ‘์†ํ•ด์ฃผ์„ธ์š”.