React: ์ตœ์ƒ์œ„ ES ์ˆ˜์ถœ ๊ณต์‹ํ™”

์— ๋งŒ๋“  2017๋…„ 11์›” 09์ผ  ยท  104์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: facebook/react

ํ˜„์žฌ ๋ชจ๋“  ํŒจํ‚ค์ง€์˜ CommonJS ๋ฒ„์ „๋งŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ–ฅํ›„ ESM์œผ๋กœ ๋ฐฐ์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(https://github.com/facebook/react/issues/10021).

๊ฐ ํŒจํ‚ค์ง€์—์„œ ์ตœ์ƒ์œ„ ES ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ์‹ค์ œ๋กœ ๊ฒฐ์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ž‘์—…์„ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด react ์—๋Š” ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ๋งŽ์ด ์žˆ์ง€๋งŒ React ๋ผ๋Š” ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๋„ ์žˆ์Šต๋‹ˆ๊นŒ? ๋” ๋‚˜์€ ๋‚˜๋ฌด ํ”๋“ค๊ธฐ๋ฅผ ์œ„ํ•ด ์‚ฌ๋žŒ๋“ค์—๊ฒŒ import * ๋ฅผ ๊ถŒ์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ํ˜„์žฌ ํด๋ž˜์Šค๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” react-test-renderer/shallow ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ(๋”ฐ๋ผ์„œ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๋กœ ๋ณ€ํ™˜๋œ ๊ฒฝ์šฐ Node์—์„œ ์‹คํŒจํ•˜๊ธฐ ์‹œ์ž‘ํ•จ)?

Build Infrastructure React Core Team Breaking Change Discussion

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

์ด์ œ ๊ฑฐ์˜ 2020๋…„์ธ๋ฐ ๊ณต์‹ FB ํŒ€์—์„œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. React v17์—์„œ ์ด์™€ ๊ด€๋ จ๋œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

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

Imho import * ๋Š” ๊ฐˆ ๊ธธ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๋„ ๋ฐ˜๋Œ€ํ•˜์ง€ ์•Š์ง€๋งŒ ์ด ์˜ˆ์™€ ๊ฐ™์ด ๋‹ค๋ฅธ ํ•ญ๋ชฉ์„ ๋‹ค์‹œ ๋‚ด๋ณด๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

export const Component = ...
export default React
React.Component = Component

๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์Œ ์˜ˆ์™€ ๊ฐ™์ด ๋‹ค๋ฅธ ํ•ญ๋ชฉ์„ ๋‹ค์‹œ ๋‚ด๋ณด๋‚ด๋Š” ๋ฐ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

๊ธฐ์ˆ ์ ์ธ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? (๊ฐ™์€ ์ผ์„ ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ์™ธํ•˜๊ณ .)

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

๊ทธ ์งˆ๋ฌธ์€ @lukastaegert๊ฐ€ ๊ฐ€์žฅ ์ž˜ ๋‹ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/facebook/react/issues/10021#issuecomment -335128611 ์ดํ›„๋กœ ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ Rollup์ด ์œ ์ผํ•œ ํŠธ๋ฆฌ ์…ฐ์ด์ปค๋Š” ์•„๋‹ˆ๋ฉฐ webpack์˜ ํŠธ๋ฆฌ ์…ฐ์ดํ‚น ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋กค์—…์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋ณด๋‹ค ๋‚˜์˜์ง€๋งŒ ์‚ฌ์šฉ๋ฅ ์€ ์•„๋งˆ๋„ ๋กค์—…๋ณด๋‹ค ํ›จ์”ฌ ๋†’์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค(๋‘ ๋„๊ตฌ ๋ชจ๋‘ ์šฐ์ˆ˜ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ๋ˆ„๊ตฐ๊ฐ€์˜ ๊ธฐ๋ถ„์„ ์ƒํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค) , ์‚ฌ์‹ค๋งŒ ์–ธ๊ธ‰) ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด (์ปค๋ฎค๋‹ˆํ‹ฐ๋กœ์„œ) ๋‘ ๋„๊ตฌ๋ฅผ ๋™์‹œ์— ๋„์šธ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ๊ทธ๋ ‡๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ฒƒ์ด ๋‹จ์ผ ํ”Œ๋žซ ๋ฒˆ๋“ค๋กœ ์‚ฌ์ „ ์ฒ˜๋ฆฌ๋œ๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ํŠธ๋ฆฌ ํ”๋“ค๊ธฐ๊ฐ€ React์˜ ๊ฒฝ์šฐ ๋ฌด์—‡์ด๋“  _do_ ํ•ฉ๋‹ˆ๊นŒ? React์˜ ๊ธฐ๋ณธ ๊ฐ€์ ธ์˜ค๊ธฐ ์Šคํƒ€์ผ์ด ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ React.Component , React.Children ์™€ ๊ฐ™์ด ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์ง€๋งŒ ๊ฐ€๋” cloneElement ๋ช…๋ช…๋œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

@gaearon์€ ์ด๋ฏธ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ๋ฐ˜์‘ ์‹œ ํฌ๊ธฐ ๊ฐœ์„ ์€ ์ตœ์†Œํ™”๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • React.Children์€ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ์ œ๊ฑฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๊ทธ๋ž˜์„œ ๐Ÿ˜‰)
  • React ์ž์ฒด๋Š” ์ด๊ฒƒ์„ ์ง€์›ํ•˜๋Š” ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ์— ์˜ํ•ด ์ตœ์ƒ์œ„ ๋ฒ”์œ„๋กœ ํ˜ธ์ด์ŠคํŠธ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹ค์‹œ ๊ฝค ๋งŽ์€ ๋ฐ”์ดํŠธ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๊ณ  ์•ฝ๊ฐ„์˜ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์ œ๊ณตํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฃผ์š” ๊ฐœ์„  ์‚ฌํ•ญ์€ ๋ชจ๋“  ๋ชจ๋“ˆ์— ๋Œ€ํ•ด React.Component ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๊ณ  ๋ชจ๋“  ๊ณณ์—์„œ ๊ณต์œ ๋˜๋Š” ๋ณ€์ˆ˜๋งŒ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์— ์žˆ์Šต๋‹ˆ๋‹ค(์ด๊ฒƒ์ด ์ผ๋ฐ˜์ ์œผ๋กœ ๋กค์—…์ด ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค). ๋˜ํ•œ ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ์ถ”์ธกํ•œ ๊ฒƒ์ผ ๋ฟ ์›นํŒฉ์˜ ModuleConcatenationPlugin์ด ๋น ์ ธ๋‚˜๊ฐˆ ๊ฐ€๋Šฅ์„ฑ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐ˜์‘์— ๋Œ€ํ•œ ์ •์  ๋ถ„์„์€ ๋ชจ๋“ˆ ๋ฒˆ๋“ค๋Ÿฌ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ IDE ๋ฐ ๊ธฐํƒ€ ๋„๊ตฌ์—์„œ๋„ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋งŽ์€ ๋„๊ตฌ๋Š” ์ด๋ฏธ CJS ๋ชจ๋“ˆ์— ๋Œ€ํ•ด ํ•ฉ๋ฆฌ์ ์ธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ ๊ฒฐ๊ตญ์—๋Š” ๋งŽ์€ ์ถ”์ธก์ด ๊ด€๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ES6 ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ถ„์„์ด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

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

  • PRO: ๊ธฐ์กด ES6 ์ฝ”๋“œ ๋ฒ ์ด์Šค๋ฅผ ์œ„ํ•œ ์†์‰ฌ์šด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜(์˜ˆ:
  • CON: ๋ชจ๋“  ๊ฒƒ์ด ๊ณตํ†ต ๊ฐœ์ฒด์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ฐœ์ฒด๊ฐ€ ํฌํ•จ๋˜๋ฉด ๋ชจ๋“  ํ‚ค๊ฐ€ ํ•œ ๋ฒˆ์— ํฌํ•จ๋˜์–ด ํŠธ๋ฆฌ ํ”๋“ค๊ธฐ ์‹œ๋„๋ฅผ ๋‹ค์‹œ ๋ฌด๋ ฅํ™”ํ•ฉ๋‹ˆ๋‹ค. GCC์กฐ์ฐจ๋„ ์—ฌ๊ธฐ์—์„œ ์–ด๋ ค์›€์„ ๊ฒช์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

์ด๊ฒƒ์€ ํฅ๋ฏธ๋กœ์šด ์‚ฌ๋ก€์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค: https://github.com/facebook/react/issues/11526. ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๋ชฝํ‚คํŒจ์นญ์€ ๋‹ค์†Œ ์• ๋งคํ•˜์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ๊นจ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์˜์‹ํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค(๋˜๋Š” ์ด์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Œ).

์ด Twitter ๋Œ€ํ™” ๋ฅผ ํ†ตํ•ด ์—ฌ๊ธฐ์— ์™”์Šต๋‹ˆ๋‹ค. ์ €์—๊ฒŒ๋Š” ์ด ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ์ •๋‹ต์ด ์žˆ์Šต๋‹ˆ๋‹ค. React์™€ ReactDOM์€ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ ๋งŒ ๋‚ด๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒํƒœ๋ฅผ ํฌํ•จํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐœ์ฒด๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค(#11526์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ ) โ€” ์กด์žฌํ•˜๋Š” ์œ ์ผํ•œ ์ด์œ ๋Š” Component , createElement '๋„ฃ๋Š”' ์žฅ์†Œ์ž…๋‹ˆ๋‹ค

(๊ทธ๊ฒƒ์€ ๋˜ํ•œ ๋ฒˆ๋“ค๋Ÿฌ์˜ ์‚ถ์„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด ์ฃผ์ง€๋งŒ ๊ทธ๊ฒƒ์€ ์—ฌ๊ธฐ๋„ ์ €๊ธฐ๋„ ์•„๋‹™๋‹ˆ๋‹ค.)

๋ฌผ๋ก  ์ด๋Š” ํ˜„์žฌ ๊ธฐ๋ณธ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ํŠธ๋žœ์ŠคํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. @lukastaegert ๋Š” ์ ‘๊ทผ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์› ์ค‘๋‹จ ๊ฒฝ๊ณ ๋ฅผ ์ธ์‡„ํ•˜๋Š” ์˜ฌ๋ฐ”๋ฅธ ์ƒ๊ฐ์„ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฒ„์ „ 17์—์„œ ์ œ๊ฑฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ•˜์ง€๋งŒ #11526์— ๋Œ€ํ•œ ๊ธฐ์„ฑํ’ˆ ์ œ์•ˆ์ด ์—†์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ESM์„ ๋ฐฐ์†กํ•˜๋Š” ๊ฒƒ์€ ์–ด์จŒ๋“  ๊ทธ๋Ÿฐ ์ด์œ ๋กœ v17์„ ๊ธฐ๋‹ค๋ ธ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์‚ฌ์šฉ ์ค‘๋‹จ ๊ฒฝ๊ณ ์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์‚ฌ๋žŒ๋“ค์ด ์ •๋ง ์ข‹์•„ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

import React, { Component } from 'react'

๊ทธ๋ž˜์„œ ํฌ๊ธฐํ•˜๋„๋ก ์„ค๋“ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ฝ๊ฐ„ ์ด์ƒํ•˜๋”๋ผ๋„ ์ด๊ฒƒ์ด ๋„ˆ๋ฌด ๋‚˜์˜์ง€๋Š” ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

import * as React from 'react';
import { Component } from 'react';

๋ช…ํ™•ํžˆ ํ•˜์ž๋ฉด JSX๊ฐ€ React.createElement() ๋ณ€ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์— React ๊ฐ€ ๋ฒ”์œ„ ๋‚ด์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ด ๊ฒฝ์šฐ์—๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ). JSX๋ฅผ ๊นจ๊ณ  ๋Œ€์‹  ์ „์—ญ jsx() ํ•จ์ˆ˜์— ์˜์กดํ•œ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

import {jsx, Component} from 'react';

๊ดœ์ฐฎ์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ํฐ ๋ณ€ํ™”์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋˜ํ•œ React UMD ๋นŒ๋“œ๊ฐ€ ์ด์ œ window.jsx ๋„ ์„ค์ •ํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์™œ ๋‚ด๊ฐ€ ์ œ์•ˆํ•˜๊ณ  jsx ๋Œ€์‹  createElement ? ๊ธ€์Ž„, createElement ๋Š” ์ด๋ฏธ ์˜ค๋ฒ„๋กœ๋“œ( document.createElement )๋˜์—ˆ์œผ๋ฉฐ React. ํ•œ์ •์ž๋กœ๋Š” ๊ดœ์ฐฎ์ง€๋งŒ ์ „์—ญ์—์„œ ์ฃผ์žฅํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค. Tbh ์ €๋Š” ์ด๋Ÿฌํ•œ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜์— ๋Œ€ํ•ด ๊ทธ๋‹ค์ง€ ํฅ๋ถ„ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ด๊ฒƒ์ด ์•„๋งˆ๋„ ๊ฐ€์žฅ ์ข‹์€ ์ค‘๊ฐ„ ์ง€์ ์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

import * as React from 'react';
import { Component } from 'react';

๊ธฐ๋ณธ์ ์œผ๋กœ JSX๋ฅผ React.createElement ๋กœ ๊ณ„์† ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ณ ๋ฐฑ: ์ €๋Š” JSX๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ช…์‹œ์ ์œผ๋กœ React ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์ด ํ•ญ์ƒ ์•ฝ๊ฐ„ ์ด์ƒํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ๋น„๋ก ์‹ค์ œ๋กœ ๊ทธ ์‹๋ณ„์ž๋ฅผ ์–ด๋””์—๋„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ์š”. ์•„๋งˆ๋„ ๋ฏธ๋ž˜์—๋Š” ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๊ฐ€ JSX๋ฅผ ๋งŒ๋‚  ๋•Œ import * as React from 'react' (Preact ๋“ฑ์„ ์œ„ํ•ด ๊ตฌ์„ฑ ๊ฐ€๋Šฅ)๋ฅผ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์•„์ง ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ)? ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค๋งŒ...

import { Component } from 'react';

... ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

๋จผ ๋ฏธ๋ž˜์—, ์•„๋งˆ๋„. ์ง€๊ธˆ์€ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋‹ค๋ฅธ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ(CommonJS ๋˜๋Š” ์ „์—ญ)๊ณผ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ์žฅ์• ๋ฌผ์ด๋ฉฐ ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋”์šฑ ๋ถ„์—ด์‹œํ‚ต๋‹ˆ๋‹ค.

@Rich-Harris๊ฐ€ ์ œ์•ˆํ•œ ๊ฒƒ(jsx๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํŠน์ • ๊ฐ€์ ธ์˜ค๊ธฐ ์‚ฝ์ž…)์€ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” babel-plugin-transform-react-jsx ๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๊ธฐ์กด ์„ค์ •๋„ ํŒŒ์ผ์— import * as React from 'react'; ๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก  ๋‹ค๋ฅธ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ๋„ ์ƒ๊ฐํ•ด๋ณผ ํ•„์š”๋Š” ์žˆ์ง€๋งŒ ํ’€๊ธฐ ์–ด๋ ค์šด ๋ฌธ์ œ๋Š” ์•„๋‹Œ ๊ฒƒ ๊ฐ™๋‹ค. ์—ผ๋‘์— ๋‘๊ณ  ์žˆ๋Š” ํŠน์ • ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ฌผ๋ก  ๋‹ค๋ฅธ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ๋„ ์ƒ๊ฐํ•ด๋ณผ ํ•„์š”๋Š” ์žˆ์ง€๋งŒ ํ’€๊ธฐ ์–ด๋ ค์šด ๋ฌธ์ œ๋Š” ์•„๋‹Œ ๊ฒƒ ๊ฐ™๋‹ค. ์—ผ๋‘์— ๋‘๊ณ  ์žˆ๋Š” ํŠน์ • ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ตฌ์ฒด์ ์ธ ์ œ์•ˆ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? Babel JSX ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ๊ธฐ๋ณธ๊ฐ’์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์‚ฌ๋žŒ๋“ค์ด ์ •๋ง ์ข‹์•„ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

import React, { Component } from 'react'

์–ด๋–ค ์‚ฌ๋žŒ๋“ค? ๋‚ด๊ฐ€ ์กฐ๋กฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‚˜์˜ค์‹ญ์‹œ์˜ค.

๋งŽ์ด ํ–ˆ์–ด์š” ๐Ÿ™‚ ํ™•์‹คํžˆ ๋‹ค๋ฅธ ๊ณณ์—์„œ๋„ ๋ณธ ์ ์ด ์žˆ์–ด์š”.

๊ธฐ๋ณธ๊ฐ’์€ ํ˜„์žฌ React.createElement ์ด๋ฉฐ ๊ฑฐ์˜ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ์œ ์ผํ•œ ๋ฌธ์ œ๋Š” ํ˜„์žฌ(๋˜๋Š” ์ด๋ฏธ ๋ฒ”์œ„์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ) ์ „์—ญ์œผ๋กœ ๊ฐ€์ •ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

es ๋ชจ๋“ˆ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“ˆ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ‘œ์ค€ ๋ฐฉ์‹(์•„์ง ๋ชจ๋‘ ์ฑ„ํƒ๋˜์ง€๋Š” ์•Š์•˜์ง€๋งŒ)์ด๋ฏ€๋กœ ๋Œ€๋‹ค์ˆ˜๊ฐ€ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค. ๋Œ€๋‹ค์ˆ˜๋Š” ์ด๋ฏธ ๋‹ค์–‘ํ•œ ๋นŒ๋“œ ๋‹จ๊ณ„ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒˆ๋“ค์„ ์ƒ์„ฑ ํ•ฉ๋‹ˆ๋‹ค . React.createElement ๋ฅผ ๋ฒ”์œ„์— ์ž๋™ ์‚ฝ์ž…ํ•˜๋„๋ก jsx ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์€ ํ•ฉ๋ฆฌ์ ์ธ ์ผ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” babel@7 ์ด ๊ณง ์ œ๊ณต๋ (-ish) ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ์„ ์œ„ํ•œ ์™„๋ฒฝํ•œ ์‹œ๊ฐ„์— ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ babel-helper-module-imports ์ถ”๊ฐ€๋กœ ์˜ฌ๋ฐ”๋ฅธ ์œ ํ˜•์˜ ๊ฐ€์ ธ์˜ค๊ธฐ(es/cjs)๋ฅผ ํŒŒ์ผ์— ์‚ฝ์ž…ํ•˜๋Š” ๊ฒƒ์ด ๊ทธ ์–ด๋Š ๋•Œ๋ณด๋‹ค ์‰ฌ์›Œ์กŒ์Šต๋‹ˆ๋‹ค.

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

๋” ๋‚˜์€ ๋‚˜๋ฌด ํ”๋“ค๊ธฐ๋ฅผ ์œ„ํ•ด ์‚ฌ๋žŒ๋“ค์ด *๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ๊ถŒ์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

@alexlamsl ๋•๋ถ„์— uglify-es ๋Š” ์ผ๋ฐ˜์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ export default ํŒจ๋„ํ‹ฐ๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค.

$ cat mod.js 
export default {
    foo: 1,
    bar: 2,
    square: (x) => x * x,
    cube: (x) => x * x * x,
};
$ cat main.js 
import mod from './mod.js'
console.log(mod.foo, mod.cube(mod.bar));



md5-d6d4ede42fc8d7f66e23b62d7795acb9



$ uglifyjs -V
uglify-es 3.2.1

```js
$ cat bundle.js | uglifyjs --toplevel -bc
var mod_foo = 1, mod_bar = 2, mod_cube = x => x * x * x;

console.log(mod_foo, mod_cube(mod_bar));
$ cat bundle.js | uglifyjs --toplevel -mc passes=3
console.log(1,8);

์™€์šฐ, ์ƒˆ๋กญ๋„ค์š” ๐Ÿ‘ ์ง€๊ธˆ uglify-es ๊ฐ€ ์•ˆ์ •์ ์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜๋‚˜์š”? ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์•„์ง ๊ฑฐ๊ธฐ์— ์•„์ง ์—†๋‹ค๊ณ  ๋ช‡ ๋‹ฌ ์ „์— ์–ธ๊ธ‰ํ–ˆ๋˜ ๊ฒƒ์„ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ž˜๋ชป ๊ธฐ์–ตํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์–ด์จŒ๋“  - ๋กค์—… ์„ธ๊ณ„์—์„œ๋Š” ๊ทธ๊ฒŒ ์ „๋ถ€์ด๊ณ  ํ›Œ๋ฅญํ•˜์ง€๋งŒ React ๊ฐ€ ๋Œ€๋ถ€๋ถ„ ์•ฑ์— ๋ฒˆ๋“ค๋˜์–ด ์žˆ๊ณ  ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฒ”์œ„ ํ˜ธ์ด์ŠคํŒ…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” ๋Œ€๋ถ€๋ถ„ webpack ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•˜๋ฉด ์—ฌ์ „ํžˆ ๊ทธ๋ ‡๊ฒŒ ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. uglisy-es + rollup ์ด์™ธ์˜ ๋‹ค๋ฅธ ๋„๊ตฌ๊ฐ€ ๋” ์ž‘์€ ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋„๋ก ๊ฐœ์ฒด๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์„ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‚˜์—๊ฒŒ๋Š” ์ด๊ฒƒ์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์˜๋ฏธ์ ์œผ๋กœ ๋” ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹ค์ œ๋กœ ํ•˜๋Š” ์ผ์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ import * as Namespace from 'namespace' ์‚ฌ์šฉํ•  ๋•Œ ๋” ์ž˜ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค.

uglify-es๋Š” ์ด์ œ ์•ˆ์ •์ ์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๊นŒ?

JS ์ƒํƒœ๊ณ„์˜ ๋‹ค๋ฅธ ๋ฌด์—‡๋ณด๋‹ค ์•ˆ์ •์ ์ž…๋‹ˆ๋‹ค. ๋งค์ฃผ 500K ์ด์ƒ์˜ ๋‹ค์šด๋กœ๋“œ.

๋กค์—… ์„ธ๊ณ„์—์„œ๋Š” ๊ทธ๊ฒŒ ์ „๋ถ€์ด๊ณ  ํ›Œ๋ฅญํ•˜์ง€๋งŒ React๊ฐ€ ์ฃผ๋กœ ์•ฑ์— ๋ฒˆ๋“ค๋˜์–ด ์žˆ๊ณ  ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฒ”์œ„ ํ˜ธ์ด์ŠคํŒ…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” ๋Œ€๋ถ€๋ถ„์˜ webpack์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๋ฉด

์–ด์จŒ๋“  ์˜ต์…˜์ž…๋‹ˆ๋‹ค. ์–ด์จŒ๋“  Webpack ๊ธฐ๋ณธ๊ฐ’์€ ์ด์ƒ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„์‹œ๋‹ค์‹œํ”ผ ModuleConcatenationPlugin ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ๋ช‡ ์„ผํŠธ ์ถ”๊ฐ€:

  • ์˜๋ฏธ์ƒ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ์„ ํƒ์ด๋ผ๋Š” @Rich-Harris์˜ ๋ง์— ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.
  • JSX ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์œ ๋กœ import React from 'react' ๋˜๋Š” import * as React from 'react' ์ •๋ง ์ข‹์•„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด ๋ˆˆ์— ์ด ๋””์ž์ธ์€ createElement ๋ถ€๋ถ„์„ โ€‹โ€‹์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋“  React๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ๊ฐ•์ œํ•œ๋‹ค๋Š” ์ ์—์„œ ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›์น™์„ ๋ถ„๋ช…ํžˆ ์œ„๋ฐ˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ•„์š”ํ•œ ์ˆ˜์ถœ์„ ๋‹ค์‹œ ์ œ๊ฑฐํ•˜์‹ญ์‹œ์˜ค)

๋”ฐ๋ผ์„œ ํš๊ธฐ์ ์ธ ๊ฒฐ์ •์„ ๋‚ด๋ฆด ์ˆ˜ ์žˆ๋Š” ์‹œ์ ์— ์žˆ๋Š” ๊ฒฝ์šฐ JSX๊ฐ€ ๋‹จ์ผ(์ „์—ญ ๋˜๋Š” ๊ฐ€์ ธ์˜จ) ๊ธฐ๋Šฅ์— ์ข…์†๋˜๋„๋ก ์ด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ createJSXElement() ๋ผ๊ณ  ๋ถˆ๋ €์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ œ ์ƒ๊ฐ์—๋Š” createElement() ๋ณด๋‹ค ๋” ์ž˜ ์„ค๋ช…ํ•˜๊ณ  ๋” ์ด์ƒ ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” React ์ปจํ…์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ๋ฐ”์ดํŠธ๊ฐ€ ์ค‘์š”ํ•œ ์„ธ์ƒ์—์„œ๋Š” jsx() ๋„ ๊ดœ์ฐฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

๊ฐœ์ธ์ ์œผ๋กœ babel ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ๊ธฐ๋ณธ IMHO๊ฐ€ react ํŒจํ‚ค์ง€์—์„œ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋ฏ€๋กœ jsx ๋„์šฐ๋ฏธ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๋ฐ ๋งŽ์€ ์ด์ ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์ œ ๋„์šฐ๋ฏธ์˜ ์ด๋ฆ„์€ ์‹ค์ œ๋กœ ๋ฌธ์ œ - ๋‚˜๋จธ์ง€๋Š” ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์•„๋งˆ๋„ ์ฃผ์š” ๋…ผ์˜์™€ ์•ฝ๊ฐ„ ์ ‘ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ES ๋ชจ๋“ˆ์ด dev/prod ๋ฒˆ๋“ค์„ ์กฐ๊ฑด๋ถ€๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ ์œ„ํ•ด process.env.NODE_ENV ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐ ์–ผ๋งˆ๋‚˜ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด,

https://github.com/facebook/react/blob/d9c1dbd61772f8f8ab0cdf389e70463d704c480b/packages/react/npm/index.js#L3 -L7

์—ฌ๊ธฐ์— ๋ถ„๋ช…ํ•œ ๊ฒƒ์„ ๋†“์ณค์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ด ํŒจํ„ด์„ ES ๋ชจ๋“ˆ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด๊ธฐ ์œ„ํ•ด ๊ณ ๊ตฐ๋ถ„ํˆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

@NMinhNguyen ES ๋ชจ๋“ˆ์—์„œ๋Š” ์กฐ๊ฑด๋ถ€ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

process.env.NODE_ENV ๊ฒ€์‚ฌ๋Š” ๋” ์„ธ๋ถ„ํ™”๋œ(์ฝ”๋“œ) ์ˆ˜์ค€์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ ์ ˆํ•œ ๊ฐ’์„ ๊ฐ€์ง„ ๋ฒˆ๋“ค๋Ÿฌ๋กœ ๊ต์ฒดํ•  ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

@Andarist @milesj ์ œ ์˜์‹ฌ์„ ํ™•์ธํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค :)

process.env.NODE_ENV ๊ฒ€์‚ฌ๋Š” ๋” ์„ธ๋ถ„ํ™”๋œ(์ฝ”๋“œ) ์ˆ˜์ค€์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ ์ ˆํ•œ ๊ฐ’์„ ๊ฐ€์ง„ ๋ฒˆ๋“ค๋Ÿฌ๋กœ ๊ต์ฒดํ•  ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

React 16 ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ์—์„œ process.env.NODE_ENV ์ˆ˜ํ‘œ๊ฐ€ ์˜๋„์ ์œผ๋กœ ๋งจ ์œ„๋กœ ๋ฝ‘ํ˜”๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ), Node.js์˜ ์„ฑ๋Šฅ์„ ๋•๊ธฐ ์œ„ํ•ด?

๋” ๋‚˜์€ ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง

React 16์—๋Š” ์™„์ „ํžˆ ์žฌ์ž‘์„ฑ๋œ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ •๋ง ๋น ๋ฅด๋„ค์š”. ์ŠคํŠธ๋ฆฌ๋ฐ์„ ์ง€์›ํ•˜๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ์— ๋ฐ”์ดํŠธ ์ „์†ก์„ ๋” ๋น ๋ฅด๊ฒŒ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  process.env ๊ฒ€์‚ฌ๋ฅผ ์ปดํŒŒ์ผํ•˜๋Š” ์ƒˆ๋กœ์šด ํŒจํ‚ค์ง• ์ „๋žต ๋•๋ถ„์—(๋ฏฟ๊ฑฐ๋‚˜ ๋ง๊ฑฐ๋‚˜, Node์—์„œ process.env ๋ฅผ ์ฝ๋Š” ๊ฒƒ์€ ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค!), ๋” ์ด์ƒ ์ข‹์€ ์„œ๋ฒ„๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด React๋ฅผ ๋ฒˆ๋“ค๋กœ ๋ฌถ์„ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋ Œ๋”๋ง ์„ฑ๋Šฅ.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋‚ด๊ฐ€ ํ•˜๋‚˜๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์–ด์š” module ํ•„๋“œ package.json ES๋ฅผ ์œ ์ง€ํ•˜๋Š” ํ‰๋ฉด ๋ฒˆ๋“ค ๋ฐ ์˜ํ–ฅ์„์ฃผ์ง€ ์•Š์œผ๋ฉด ์„œ ESM์— ๋Œ€ํ•œ dev์— / ์ž๊ทน ์‚ฌ์ด์˜ ์ฐจ๋ณ„ํ™”๋ฅผ Node.js๋ฅผ ๋ฐ˜ํ™˜ ํ•œ

์˜ˆ๋ฅผ ๋“ค์–ด package.json์˜ ๋ชจ๋“ˆ ํ•„๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ES ๋ฒˆ๋“ค์„ ํ”Œ๋žซํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ณ  Node.js ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์œผ๋ฉด์„œ ESM์šฉ dev/prod๋ฅผ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

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

ํ•™๊ธ‰์„ ์œ„ํ•ด:

import Component from 'react/Component'

class MyButton extends Component{
  constructor(){
    this.state = {}
  }

  render() {
    return <button> Button <Button>
  }
}

์—ฌ๊ธฐ์„œ ๋ณ€ํ™˜์€ super.createElement()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ jsx๋กœ ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜ ์ •์  Component.createElement()๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ƒํƒœ ๋น„์ €์žฅ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ:

import jsx from 'react/jsx'

const MyButton = () => jsx`<button> Button <Button>`;

ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋œ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋…ธ๋“œ๊ฐ€ ์ด PR์„ ์ˆ˜๋ฝํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. https://github.com/nodejs/node/pull/18392

@Rich-Harris์˜ ์˜๊ฒฌ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ ๊ตฌ์ฒด์ ์œผ๋กœ ์–ธ๊ธ‰๋˜์ง€ ์•Š์€ ์ด ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์˜๊ฒฌ์„ ๋‚จ๊ธฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ธŒ๋ผ์šฐ์ €( <script type="module" src="..."> )๋ฅผ ํ†ตํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜์‘ ๋ฐ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋Š” ์ƒํ™ฉ์— ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰,

import React from โ€œhttps://unpkg.com/[email protected]/umd/react.development.jsโ€;
import ReactDOM from โ€œhttps://unpkg.com/[email protected]/umd/react-dom.development.jsโ€;
ReactDOM.render(
  React.createElement(...),
  document.getElementById('root')
);

๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ์ด๊ฒƒ์€ ์˜ค๋Š˜๋‚  ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  CDN์˜ <script> ํƒœ๊ทธ๋ฅผ ํ†ตํ•ด react์˜ UMD ๋ฒ„์ „์„ ํฌํ•จํ•ด์•ผ ํ•˜๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚ด๊ฐ€ ์ž‘์„ฑํ•˜๋Š” <script type="module"> ๋ชจ๋“ˆ์˜ ์ฐฝ์— ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// myPage.html
<div id="myComponentRoot"></div>
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script type="module" src="/assets/scripts/components/MyComponent.js"></script>

// MyComponent.js
import AnotherComponent from "/assets/scripts/components/AnotherComponent.js";
window.ReactDOM.render(
  window.React.createElement(AnotherComponent),
  document.getElementById('root')
);

// AnotherComponent.js
export default class AnotherComponent extends window.React.Component {...}

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

// /assets/scripts/entry.js
import React from โ€œhttps://unpkg.com/[email protected]/umd/react.development.jsโ€;
import React from โ€œhttps://unpkg.com/[email protected]/umd/react-dom.development.jsโ€;
import RelatedPosts from "/assets/scripts/components/RelatedPosts.js";
ReactDOM.render(
  React.createElement(RelatedPosts),
  document.getElementById('root')
);

// /assets/scripts/components/RelatedPosts.js
import React from โ€œhttps://unpkg.com/[email protected]/umd/react.development.jsโ€;
import ListItem from "/assets/scripts/components/ListItem.js"
export default class MyComponent extends React.Component {
  componentDidMount() { /* fetch some data */ }
  render() { 
    return React.createElement(
      'ul',
      {},
      this.state.items.map(item => React.createElement(ListItem, { item: item })
    )
  }
}

// /assets/scripts/components/ListItem.js
import React from โ€œhttps://unpkg.com/[email protected]/umd/react.development.jsโ€;
export default function ListItem(props) {
  return React.createElement('li', null, ...)
}

์–ด๋–ค ์‚ฌ๋žŒ๋“ค์€ CDN URL์„ ํ•ญ์ƒ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ์ด ๋ฌธ์ œ(์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์€ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ํ•˜๋Š” ๋ฌธ์ œ)๋ผ๊ณ  ์ฃผ์žฅํ•˜์ง€๋งŒ ์ €์—๊ฒŒ๋Š” ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น URL์„ ๋ณ€๊ฒฝ/์—…๋ฐ์ดํŠธ๋Š” ๊ฐ„๋‹จํ•œ ์ฐพ๊ธฐ/๋ฐ”๊พธ๊ธฐ์ž…๋‹ˆ๋‹ค. ๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ๊ฒฝ์šฐ ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์„ค์ •ํ•˜๋Š” ์ˆ˜๊ณ ๋ฅผ ๋Šฅ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

React๊ฐ€ ์ด์™€ ๊ฐ™์€ ๊ฒƒ์„ ์ง€์›ํ–ˆ๋‹ค๋ฉด ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์•˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ €๋Š” ๊ทธ๋ƒฅ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๊ฐ€์ •ํ•˜๊ณ  ํŽ˜์ด์ง€์—์„œ ์ ์ง„์ ์ธ ํ–ฅ์ƒ์œผ๋กœ ๋ฐ˜์‘ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ์—์„œ ์ด์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ํ™˜์ƒ์ ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ 12๊ฐœ์›” ๋งŒ์— ์ฝ”๋“œ ๋ฒ ์ด์Šค๋กœ ๋Œ์•„์™”์„ ๋•Œ ๋งŽ์€ ๋„๊ตฌ API๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ NPM์„ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋กœ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ €๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ API๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์„ ๋ฟ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.

FWIW๋Š” : / ๋ฐ˜์ž‘์šฉ ํ•  ๋•Œ์ด ๊ฐ™์€ ์ง€์›์œผ๋กœ ๋ฐฐ๋ฅผ ์•Š๋Š” ๊ฒฝ์šฐ, ๋‹น์‹  ๋ฐ˜์‘ ํ™œ์šฉ์„ ํ†ตํ•ด ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ทธ ๊ตฌ์„ฑ ๋ชจ๋ธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐ€๋ฅด์นจ, ๋‹น์‹ ์ด ๋ฌธ์„œ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ˜์ž‘์šฉ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ ๋งค์šฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐ์˜ ์ž์‹ ์˜ ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ <script type="module"> ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  CDN(๋˜๋Š” ์ž์ฒด ๋กœ์ปฌ ๋ณต์‚ฌ๋ณธ)์—์„œ React๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค!โ€

์ด์ œ ๋ชจ๋ฐ”์ผ ๋ฒ„์ „์„ ํฌํ•จํ•œ ๋ชจ๋“  ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ESM์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ESM์€ ๋” ์ด์ƒ ๋ฏธ๋ž˜์˜ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์ด ์•„๋‹ˆ๋ผ ํ˜„์žฌ์˜ ์‚ฌ์‹ค์ƒ์˜ ํ‘œ์ค€์ž…๋‹ˆ๋‹ค.

ํ‘œ์ค€ํ™”๋œ ๋ชจ๋“ˆ์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ํŠนํžˆ ์‚ฌ์‹ค์ƒ์˜ ํ‘œ์ค€ ์›น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฒฝ์šฐ ์ค‘์š”ํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

import * as React from 'react';
import * as ReactDOM from 'react-dom';

์ด๊ฒƒ์€ React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ ์šฉํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์ฝ”๋“œ์ด๋ฉฐ ์‹ค์ œ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—†๋Š” ๋Œ€์‹  ํƒ€์‚ฌ ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ์™€ ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ๊ฐ€์ ธ์˜ค๊ธฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์—๋ฎฌ๋ ˆ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

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

๋‚˜๋Š”์ด ์ž‘์—…์„ ์‹œ์ž‘ ์—ฌ๊ธฐ ์™€ ์—ฌ๊ธฐ์—

@TrySound ๊ธฐ์—ฌํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
ESM ๋นŒ๋“œ๋ฅผ ๊ฐ€์ ธ์™€ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

react-is ํŒจํ‚ค์ง€์—๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@TrySound
์ข‹์•„, https://github.com/TrySound/react/tree/react-is-esm ์ง€์ ์„ ์ฐพ์•˜๊ณ  ๊ตฌ์ถ•ํ–ˆ์œผ๋ฉฐ ์ด์ œ ๋‹น์‹ ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋ฅผ ์••๋‹ˆ๋‹ค. react-dom ๋„ ๊ธฐ๋Œ€๋ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” React ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ํ•œ๋™์•ˆ ์ถฉ๋ถ„ํžˆ ๋…ผ์˜ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
https://discuss.reactjs.org/t/es6-import-as-react-vs-import-react/360/

๊ณต์‹ ES6 ๋ชจ๋“ˆ ์‚ฌ์–‘์„ ๊ฒฐ์ •ํ•˜๊ณ  ๊ณง ๊ฒŒ์‹œํ•˜์‹ญ์‹œ์˜ค.

@kenokabe ๊ฐ€๋Š” ์ค‘์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋ฅผ ๊ฐ•์š”ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๊ทธ๋ ‡๊ฒŒ ์‰ฌ์šด ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค.

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

๋‹ค๋ฅธ ํŒจํ‚ค์ง€์˜ ๊ฒฝ์šฐ ๋‹ค์–‘ํ•œ ๋„๊ตฌ์™€ ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ์™€ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@TrySound ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.
์ด ์ฃผ์ œ์˜ ํ—ค๋“œ ๋ฉ˜์…˜์ด

๊ฐ ํŒจํ‚ค์ง€์—์„œ ์ตœ์ƒ์œ„ ES ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ์‹ค์ œ๋กœ ๊ฒฐ์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ž‘์—…์„ ์‰ฝ๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, react์—๋Š” ์ด๋ฆ„์ด ์ง€์ •๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ๋งŽ์ด ์žˆ์ง€๋งŒ React๋ผ๋Š” ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๋„ ์žˆ์Šต๋‹ˆ๊นŒ? ๋” ๋‚˜์€ ๋‚˜๋ฌด ํ”๋“ค๊ธฐ๋ฅผ ์œ„ํ•ด ์‚ฌ๋žŒ๋“ค์ด *๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ๊ถŒ์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๊ทธ๋ฆฌ๊ณ , ์–ธ๊ธ‰๋œ ๋‚ ์€ ์–ผ๋งˆ ์ „์ด๊ณ , React ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋…ผ์˜๋œ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ์ •์ด ๋ช…ํ™•ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ œ์•ˆํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

์ด๊ฒƒ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ ์›ํ•˜์‹ญ๋‹ˆ๊นŒ...

์ €๋Š” ์šฐ๋ฆฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฒˆ๋“ค๋งํ•˜๊ธฐ ์œ„ํ•ด webpack v4๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ์ œ IDE ์ธํ…”๋ฆฌ์„ผ์Šค(WebStorm)์—์„œ๋Š” import * as React from 'react'; ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ์ œ์•ˆํ•˜๊ณ  ๋™๋ฃŒ๋Š” ์ฝ”๋“œ ๊ฒ€ํ† ์—์„œ import React from 'react'; ๋ฅผ ๋ณ€๊ฒฝํ•˜๋„๋ก ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ์ž˜ ์ž‘๋™ํ•˜๋ฏ€๋กœ ๊ทธ๊ฐ€ ๋ง๋„ ์•ˆ ๋˜๋Š” ๋ง์„ ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ๊ทธ๋ฅผ ๊ธฐ์˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์–ด์จŒ๋“  ๋ณ€๊ฒฝํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

๊ถ๊ธˆํ•ด์„œ ์ตœ์ข… ๋นŒ๋“œ ํฌ๊ธฐ์˜ ์ฐจ์ด์ ์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค(React 16.8.1 ์‚ฌ์šฉ).

import * as React from 'react'; : 6,618,723๋ฐ”์ดํŠธ
import React from 'react'; : 6,619,077๋ฐ”์ดํŠธ

๊ทธ๋ž˜์„œ ๋ถ„๋ช…ํžˆ ์•ฝ๊ฐ„์˜ ์ฐจ์ด๊ฐ€ ์žˆ์—ˆ์ง€๋งŒ ๋ฏธ๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค. (์ฐธ๊ณ . ๋‚˜๋Š” propTypes ์™€ ๋™์ผํ•˜๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค)

์ด ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ๋‚ด ์ดํ•ด๊ฐ€ ์ •ํ™•ํ•˜๋‹ค๋ฉด import * as React from 'react'; ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์œ ๋ฆฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ? (1) ์˜ˆ, ์•ฝ๊ฐ„์˜ ํฌ๊ธฐ๋ฅผ ์ ˆ์•ฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. (2) ESM์€ ํ‘œ์ค€ํ™”๋œ ๋ฐฉ์‹์ด๋ฏ€๋กœ ๋” ์ด์ƒ CJS๊ฐ€ ๋‚จ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์˜ค๋Š˜ ์ด๊ฒƒ์„ ๋ณ€๊ฒฝํ•˜๊ณ  ๋‚ด IDE์— ๋งž์ถ”๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@leoyli ์žฅ๊ธฐ์ ์œผ๋กœ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋จผ์ € ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ์†์ƒ์‹œํ‚ค์ง€ ์•Š๋„๋ก ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ์™€ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ๋‘˜ ๋‹ค ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‚ด ํ”„๋กœ์ ํŠธ์—์„œ ๋” ์ด์ƒ ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์—ฌ์ „ํžˆ ๋ฐ˜์‘์„ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์›ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์—์„œ ์ง์ ‘ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค(Vue, Hyperapp ๋“ฑ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ unpkg.com์—์„œ ์ง์ ‘). . ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•ด ๋‚ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฉ‹์ง„ ๊ฒƒ์€ ์•„๋‹ˆ๋ฉฐ ์†์œผ๋กœ ํŽธ์ง‘ ํ•œ umd์ž…๋‹ˆ๋‹ค.

https://github.com/lukejacksonn/es-react

React ๋ฐ ReactDOM ์˜ ์ตœ์‹  ๋ฒ„์ „์„ ๋…ธ์ถœํ•˜๋Š” ES6 ๋ชจ๋“ˆ

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

import { React, ReactDOM } from 'https://unpkg.com/es-react'

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

@lukejacksonn ์šฐ๋ฆฌ๋Š” ํ”„๋กœ๋•์…˜์—์„œ๋„ ์ด๋Ÿฌํ•œ ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์—์„œ UMD ๋ฒ„์ „์˜ React ๋ฐ ReactDOM์— ๋Œ€ํ•œ ๋ณ€ํ™˜๊ธฐ ์Šคํฌ๋ฆฝํŠธ๋ผ๋Š” ์ ์—์„œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ํŒŒ์ผ์„ ๊ฐœ๋ณ„์ ์œผ๋กœ ์ถœ๋ ฅํ•˜๋ฏ€๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์ฝ”๋“œ์— ๋Œ€ํ•ด ๊ต์ฒด์šฉ ๋“œ๋กญ์ธ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. https://github.com/wearespindle/react-ecmascript์— ๊ด€์‹ฌ์ด ์žˆ๊ณ  unpkg https://unpkg.com/react-ecmascript/ ์—์„œ ๋กœ๋“œํ•  ์ˆ˜๋„

@ PM5544 ์˜ค ์™€์šฐ.. ์ด๊ฒƒ์€ ๋‚ด ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ํฌ๊ด„์  ์ธ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค! ์ž˜ํ–ˆ์–ด ๐Ÿ’ฏ

๋ฉ‹์ง„ ๋ฌผ๊ฑด @ PM5544. ์–ธ์  ๊ฐ€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋” ๋“ฃ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. Xebia์— ๋‹ค์‹œ ๊ฒŒ์ŠคํŠธ๋กœ ์ถœ์—ฐํ• ๊นŒ์š”?
์ €๋Š” ์ตœ๊ทผ์— UNPKG๋ฅผ ์ง€์›ํ•˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ํŒจํ‚ค์ง€๋ฅผ ๋ฌถ๊ธฐ ์œ„ํ•ด ํŒฉ ์„ ์ฑ„ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.
๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  UNPKG์—์„œ ์ง์ ‘ ์ข…์†์„ฑ์„ ๋กœ๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ข‹์€ ๊ธฐ์‚ฌ๋ฅผ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ €๋Š” ํ˜„์žฌ ํ•˜๋‚˜๋ฅผ ์ž‘์„ฑ ์ค‘์ด๋ฉฐ 6์›”์—๋„ React ๋…ธ๋ฅด์›จ์ด์—์„œ ๊ฐ•์—ฐ์œผ๋กœ ์ œ๊ณตํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค!

@TrySound 2์›” ์ดํ›„์— ์ด์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ? ์ด ๋ฌธ์ œ๋ฅผ ์˜ฎ๊ธฐ๊ธฐ ์œ„ํ•ด ๋‚จ์€ ๊ฒƒ์€ ๋ฌด์—‡์ด๋ฉฐ ์ผ๋ถ€ ์ฝ”๋”ฉ ์ž‘์—…์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ €๋Š” ์ด๋ฏธ CA์— ์„œ๋ช…ํ–ˆ์œผ๋ฉฐ ์˜ค๋Š˜ ์ž‘์—…ํ•  ์‹œ๊ฐ„์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋จผ์ € ๋ณ‘ํ•ฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค https://github.com/facebook/react/pull/15037

@TrySound ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์ง€์› ์ œ์•ˆ์„ ์ „๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ React ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋‹ค์Œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// react/index.js
import * as React from "./react";
export { React as default }
export * from "./react";

// react/react.js
export function createElement() {}
...

์ด๊ฒƒ์€ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์›นํŒฉ 5 ๋ฐ ๋กค์—…์—์„œ ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ์— ๋Œ€ํ•ด ํŠธ๋ฆฌ ํ”๋“ค๋ฆผ์„ ํ—ˆ์šฉํ•˜๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๊ฐ์ฒด๋ผ๋Š” ๊ฒƒ์„ ์ •์ ์œผ๋กœ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

import React from "react";

React.createElement(); // <- only `createElement` export is used

๋‚˜๋Š” 1.5 ๋…„ ๋™์•ˆ ๋กค์—… gitter chat์— ์žˆ์—ˆ๊ณ  ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๋ฌธ์ œ๋Š” 2 ์ฃผ ์ •๋„๋งˆ๋‹ค ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค ...

BTW, @lukejacksonn ์€ es-react ํฌํฌ์—์„œ ์—„์ฒญ๋‚œ ์ผ์„ ํ–ˆ์œผ๋ฉฐ ๊ฐ•๋ ฅํžˆ ์ถ”์ฒœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

BTW, @lukejacksonn ์€ es-react ํฌํฌ์—์„œ ์—„์ฒญ๋‚œ ์ผ์„ ํ–ˆ์œผ๋ฉฐ ๊ฐ•๋ ฅํžˆ ์ถ”์ฒœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณต์‹ FB ํŒ€์ด ์™œ ์ด๊ฒƒ์— ๋Œ€ํ•ด ์•„๋ฌด๊ฒƒ๋„ํ•˜์ง€ ์•Š๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ ์ด๊ฒƒ์ด ์•ž์œผ๋กœ ๋‚˜์•„๊ฐ€๋Š” ๋ฐ ์•ฝ๊ฐ„์˜ ์••๋ ฅ์„ ๊ฐ€ํ•˜๊ธฐ๋ฅผ ๋ฐ” ๋ž๊ณ  @lukejacksonn ์ž์‹ ๋„

์ด๊ฒƒ๋„ ์ฐธ์œผ๋กœ ๋ฐ”๋ž๋‹ค. ์‚ฌ์‹ค ์ €๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์—์„œ react ํŒ€์˜ ์ง€์›์„ ๊ฑฐ์˜ ๋ฐ›์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค(@threepointone์˜ ๊ฒฉ๋ ค์˜ ๋ง ์™ธ์—). ์ตœ๊ทผ์— ์—ฌ๊ธฐ Formidable์˜ ๋™๋ฃŒ๊ฐ€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ํŒจํ‚ค์ง€๋ฅผ ๋นŒ๋“œํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ƒˆ๋กœ์šด ๋ฒ„์ „์˜ react๊ฐ€ ๋ฆด๋ฆฌ์Šค๋  ๋•Œ๋งˆ๋‹ค ์ˆ˜๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๊ฐœ์„ ๋˜์—ˆ์ง€๋งŒ ๋„คํŠธ์›Œํฌ ํƒญ์—์„œ ํ›จ์”ฌ ๋œ ๊นจ๋—ํ•œ ์ถœ๋ ฅ์„ ๊ฐ€์ ธ์˜ค๋ฏ€๋กœ ๊ทธ๋ ‡๊ฒŒ ๋ ์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์•„์ง ์ด๋Œ€๋กœ ์žˆ์–ด. ์šฐ๋ฆฌ๋Š” ๋ณด๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค!

์ด์ œ ๊ฑฐ์˜ 2020๋…„์ธ๋ฐ ๊ณต์‹ FB ํŒ€์—์„œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. React v17์—์„œ ์ด์™€ ๊ด€๋ จ๋œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์—…๋ฐ์ดํŠธ๋œ ES ๋ชจ๋“ˆ React NOW๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ด๋ฏธ v16.13.x์— ์žˆ๋Š” @pica/react ๋ฅผ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค.
https://www.npmjs.com/package/@pika/react
https://www.npmjs.com/package/@pika/react -dom
https://github.com/pikapkg/react

๋จผ ๋ฏธ๋ž˜์—, ์•„๋งˆ๋„.

์ข‹์•„, ์ด๋ฏธ ๋ฏธ๋ž˜์—. ์ง€๊ธˆ์€ ๊ฐ€๊นŒ์šด ๋ฏธ๋ž˜์ธ๊ฐ€์š”?

@gaearon ๋‚ด๋ณด๋‚ด๊ธฐ(๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ ๋Œ€ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ)๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•œ ์ฐจ๋‹จ๊ธฐ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ด ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๋Š” ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋ถ„๋ช…ํžˆ ๊ทธ ๊ฒฐ์ •์€ ์ด๋ฏธ ์–ผ๋งˆ ์ „์— ๋‚ด๋ ค์ง„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค: #18102. ์ด ๋ฌธ์ œ๋Š” ์ง€๊ธˆ ๋‹ซ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•ด ์•ฝ๊ฐ„์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ ์—†์Œ

์šฐ๋ฆฌ์˜ ์ตœ์ข… ๊ณ„ํš์€ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ์—์„œ ์™„์ „ํžˆ ๋ฒ—์–ด๋‚˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

import { useState } from 'react';

๊ทธ ์„ธ๊ณ„์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘๋™ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค .

import React from 'react'; // no

์•ฝ๊ฐ„ ์‹œ๋„๋Ÿฝ์ง€๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

import * as React from 'react';

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์— ํ‚ค์ปค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ React ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ด์œ ๊ฐ€ ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

JSX ์ž๋™ ๊ฐ€์ ธ์˜ค๊ธฐ

์˜ค๋Š˜๋‚  ์‚ฌ๋žŒ๋“ค์ด React ์ˆ˜์ž…ํ•˜๋Š” ์ด์œ ๋Š” ๋Œ€๋ถ€๋ถ„ JSX ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ @lunaruan ์€ ์ƒˆ๋กœ์šด JSX ๋ณ€ํ™˜ ๋ฐ ๊ด€๋ จ codemod์— ๋Œ€ํ•œ ์ž‘์—…์„ ๋งˆ๋ฌด๋ฆฌ ์ค‘์ด๋ฏ€๋กœ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‹น์‹ ์€ ์ด๊ฒƒ์—์„œ ๊ฐˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค :

import React from 'react';
import { useState } from 'react';

function Button() {
  const [pressed, setPressed] = useState(false)
  return <button />
}

์ด์—:

import { useState } from 'react';

function Button() {
  const [pressed, setPressed] = useState(false)
  return <button />
}

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

ES ๋ชจ๋“ˆ

์ „๋ฐ˜์ ์œผ๋กœ ์†Œ์ˆ˜์˜ ์• ํ˜ธ๊ฐ€๋ฅผ ๋„˜์–ด ESM์„ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ค์šด ์ผ์ž…๋‹ˆ๋‹ค. ๊ด‘๋ฒ”์œ„ํ•œ ์ƒํƒœ๊ณ„๋Š” ์‹ค์ œ๋กœ ์ค€๋น„๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ๋‹ค์–‘ํ•œ ๋„๊ตฌ ์กฐํ•ฉ์œผ๋กœ ์ธํ•ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. CJS์™€ ESM์ด ์ƒํ˜ธ ์ž‘์šฉํ•˜๋Š” ๋ฐฉ์‹์€ ๋งค์šฐ ๋ณต์žกํ•˜๋ฉฐ ํ•ด๋‹น ์ƒํ˜ธ ์šด์šฉ์„ฑ(๋ฐ ์‹คํŒจ ๋ฐฉ์‹)์ด ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์˜ ๋Œ€๋ถ€๋ถ„์˜ ์›์ธ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ์˜ ํ˜„์žฌ ์ƒ๊ฐ์€ ์šฐ๋ฆฌ๊ฐ€ ESM์„ ํ•  ๋•Œ ESM์„ ๋๊นŒ์ง€ ์‹œ๋„ํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. CJS๊ฐ€ ์ „ํ˜€ ์—†๊ฑฐ๋‚˜ ํ˜ธํ™˜๋˜๋Š” ๋ ˆ๊ฑฐ์‹œ ํŒจํ‚ค์ง€๋กœ ๋ถ„๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ React 17์—์„œ๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉฐ 18์—์„œ๋Š” ๊ฐ€๋Šฅ์„ฑ์ด ๋‚ฎ์ง€๋งŒ React 19์—์„œ ์‹œ๋„ํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋Ÿด๋“ฏํ•ฉ๋‹ˆ๋‹ค.

@pika/react ์˜ ESM ๋นŒ๋“œ์— ๋Œ€ํ•œ ๋Œ€์•ˆ์„ ์ฐพ๋Š” ์‚ฌ๋žŒ์€ https://github.com/esm-bundle/react ๋ฐ https://github.com/esm-bundle/react-dom์„ ํ™•์ธ import React from 'react'; ๋Š” ์ „์ฒด CDN URL์—์„œ React๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ์ฐจ์ด์ ์€ ์ˆ˜๋™ ๋‹จ๊ณ„ ์—†์ด ์ƒˆ ๋ฐ˜์‘ ๋ฒ„์ „์ด ๊ฒŒ์‹œ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ ๋ฒ„์ „์ด ์ž๋™ ๊ฒŒ์‹œ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฝ”๋“œ ์ƒŒ๋“œ๋ฐ•์Šค ์‹œ์—ฐ: https://codesandbox.io/s/gifted-roentgen-qcqoj?file=/index.html

๋ช‡๋ช‡ ์‚ฌ๋žŒ๋“ค์€ ์ƒํƒœ๊ณ„๊ฐ€ ์ค€๋น„๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฐœ๋…์— ์ด์˜๋ฅผ ์ œ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ „์ฒด ๋งฅ๋ฝ์€ ์—†์ง€๋งŒ ์ง€๊ธˆ์ด ๋ณ€๊ฒฝ์„ ์‹œ์ž‘ํ•˜๊ธฐ์— ์ข‹์€ ์‹œ๊ธฐ๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด https://github.com/reactjs/rfcs/pull/38์„ ์‚ดํŽด๋ณด๊ณ  ๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ์šฐ๋ ค. ๋Œ€๋žต์ ์œผ๋กœ ์—ผ๋‘์— ๋‘์—ˆ์Šต๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๊นŒ?

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์— ํ‚ค์ปค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ React๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ด์œ ๋Š” ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์•ž์œผ๋กœ๋„ ๊ทธ๋Ÿด ๊ฒƒ์ž…๋‹ˆ๋‹ค. TS๊ฐ€ babel์˜ ์ด ์ƒˆ๋กœ์šด ๋งˆ์ˆ  ๋™์ž‘์— ๋Œ€ํ•ด ๋ฐฐ์šธ ๋•Œ๊นŒ์ง€ ๊ฐœ๋ฐœ์ž๋Š” ๊ณ„์†ํ•ด์„œ ๋ช…์‹œ์ ์œผ๋กœ React๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•˜๊ณ  ์˜ฌ๋ฐ”๋ฅธ import ๋ฌธ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

JSX๋Š” ํ›„๋“œ ์•„๋ž˜์— ์˜ฌ๋ฐ”๋ฅธ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์ž๋™์œผ๋กœ ์‚ฝ์ž…ํ•˜๋ฏ€๋กœ ๋ฒ”์œ„์— React๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

s/JSX/์ƒˆ๋กœ์šด babel react jsx ๋ณ€ํ™˜ ํ”Œ๋Ÿฌ๊ทธ์ธ/. JSX๋Š” JavaScript์— ๋Œ€ํ•œ ๊ตฌ๋ฌธ ํ™•์žฅ์ด๋ฉฐ ์ž์ฒด์ ์œผ๋กœ๋Š” ์•„๋ฌด ๊ฒƒ๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์•ž์œผ๋กœ๋„ ๊ทธ๋Ÿด ๊ฒƒ์ž…๋‹ˆ๋‹ค. TS๊ฐ€ babel์˜ ์ด ์ƒˆ๋กœ์šด ๋งˆ์ˆ  ๋™์ž‘์— ๋Œ€ํ•ด ๋ฐฐ์šธ ๋•Œ๊นŒ์ง€ ๊ฐœ๋ฐœ์ž๋Š” ๊ณ„์†ํ•ด์„œ ๋ช…์‹œ์ ์œผ๋กœ React๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•˜๊ณ  ์˜ฌ๋ฐ”๋ฅธ import ๋ฌธ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

TypeScript ํŒ€์€ ์ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ https://github.com/microsoft/TypeScript/issues/34547 ์—์„œ ์ถ”์  ์ค‘

s/JSX/์ƒˆ๋กœ์šด babel react jsx ๋ณ€ํ™˜ ํ”Œ๋Ÿฌ๊ทธ์ธ/

์˜ˆ, ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์˜๋ฏธํ–ˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

reactjs/rfcs#38์„ ์‚ดํŽด๋ณด๊ณ  ์ด์— ๋Œ€ํ•œ ์šฐ๋ ค ์‚ฌํ•ญ์„ ํ‘œํ˜„ํ•ด ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋Œ€๋žต์ ์œผ๋กœ ์—ผ๋‘์— ๋‘์—ˆ์Šต๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๊นŒ?

RFC์˜ ์›๋ณธ ํ…์ŠคํŠธ ์ค‘ ์ผ๋ถ€๊ฐ€ ์˜ค๋ž˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. NodeJS๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด package.json์— "type" ๋ฅผ ์ง€์ •ํ•  ๋•Œ .mjs ๋Œ€์‹  .js ํŒŒ์ผ์—์„œ ESM์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ( ๋ฌธ์„œ ).

ํŠนํžˆ RFC ์›๋ณธ ํ…์ŠคํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์‹ค์ด ์•„๋‹ˆ๋ผ๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค.

ESM ์ฝ”๋“œ ๋Š” .mjs ํŒŒ์ผ ์•ˆ์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@frehner ์™€ ๋Œ€ํ™”ํ•œ ํ›„ React๊ฐ€ ESM์œผ๋กœ ์ ์ง„์ ์œผ๋กœ ๋ณ€ํ™˜๋  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ESM ๋ฒ„์ „์˜ React๋ฅผ ๊ฒŒ์‹œํ•  ๋•Œ ๋ช…๋ช…๋œ/๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ ๋ฌธ์ œ๋ฅผ ์—ฐ๊ฒฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @gaearon ์€ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ๊ฒฐ๊ตญ ์‚ฌ๋ผ์งˆ ๊ฒƒ์ด๋ผ๊ณ  ๋ฐํ˜”์ง€๋งŒ ์ด๋Š” 4๋‹จ๊ณ„๊นŒ์ง€ ์ œ์•ˆ์„œ์— ๋‚˜์—ด๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

| | 1๋‹จ๊ณ„ | 2๋‹จ๊ณ„ | 3๋‹จ๊ณ„ | 4๋‹จ๊ณ„ |
| - | -------- | -------- | -------- | ------- |
| ESM ๊ฒŒ์‹œ? | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ |
| ํŒจํ‚ค์ง€.json "module" | โŒ | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ |
| ์›นํŒฉ/๋กค์—… ์‚ฌ์šฉ esm 1 , 2 | โŒ | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ |
| ํŒจํ‚ค์ง€.json "exports" | โŒ | โŒ | โœ”๏ธ | โœ”๏ธ |
| ํŒจํ‚ค์ง€.json "type" | โŒ | โŒ | โœ”๏ธ | โœ”๏ธ |
| NodeJS๋Š” esm์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค | โŒ | โŒ | โœ”๏ธ | โœ”๏ธ |
| ํš๊ธฐ์ ์ธ ๋ณ€ํ™”? | โŒ | โŒ | โ“ | โœ”๏ธ |
| ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์‚ฌ๋ผ์กŒ์Šต๋‹ˆ๊นŒ? | โŒ | โŒ | โŒ | โœ”๏ธ |
| ๊ฐ€์ ธ์˜ค๊ธฐ์— ํ•„์š”ํ•œ ํŒŒ์ผ ํ™•์žฅ์ž | โŒ | โŒ | โŒ | โŒ |
| mjs ํŒŒ์ผ ํ™•์žฅ๋ช… | โŒ | โŒ | โŒ | โŒ |

1๋‹จ๊ณ„๋Š” ์‹ค์ œ๋กœ ๋งค๋‹ˆ์•„๋งŒ์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— 1๋‹จ๊ณ„์™€ 2๋‹จ๊ณ„๋ฅผ ํ•จ๊ป˜ ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ํƒ€๋‹นํ•œ ์ฃผ์žฅ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹จ๊ณ„๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด ๋จผ์ € ์–ผ๋ฆฌ ์–ด๋‹ตํ„ฐ์—๊ฒŒ ๋ฌธ์ œ๋ฅผ ๋ณด๊ณ ํ•˜๊ณ  ์ˆ˜์ • ์‚ฌํ•ญ์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ์ฃผ์ง€ ์•Š๊ณ  CRA์™€ ์ „์ฒด ์ƒํƒœ๊ณ„๋ฅผ ์ฆ‰์‹œ ์ค‘๋‹จํ•˜์ง€ ์•Š๋Š” ๋ฐฉ์‹์œผ๋กœ ESM์„ ๋งค์šฐ ์ฒœ์ฒœํžˆ ๋กค์•„์›ƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„ํ• ํ–ˆ์Šต๋‹ˆ๋‹ค. .

@joeldenning ๋‹จ๊ณ„์˜ ๋Œ€๋žต์ ์ธ ํƒ€์ด๋ฐ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜์ž…๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์ƒํƒœ๊ณ„์˜ ์ผ๋ถ€ ์‹œ๊ฐ„ ์ฒดํฌํฌ์ธํŠธ์™€ ๊ด€๋ จ๋œ ๊ฒƒ์ž…๋‹ˆ๊นŒ? require('react') ์ด 3๋‹จ๊ณ„์—์„œ ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

๋‹จ๊ณ„์˜ ๋Œ€๋žต์ ์ธ ํƒ€์ด๋ฐ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜์ž…๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ์ƒํƒœ๊ณ„์˜ ์ผ๋ถ€ ์‹œ๊ฐ„ ์ฒดํฌํฌ์ธํŠธ์™€ ๊ด€๋ จ๋œ ๊ฒƒ์ž…๋‹ˆ๊นŒ?

๋ชจ๋“  ๋‹จ๊ณ„์˜ ํƒ€์ด๋ฐ์€ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ์ž‘์—…๊ณผ React์˜ ๋ฆด๋ฆฌ์Šค ์ผ์ •์— ์˜ํ•ด์„œ๋งŒ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ๋‚ด ์ดํ•ด๋Š” ์ œ์•ˆ๋œ ๋ชจ๋“  ๊ฒƒ์ด ๋ฒˆ๋“ค๋Ÿฌ์™€ nodejs์—์„œ ์ง€์›๋˜๋ฉฐ, ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์ „ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•  ๋•Œ ์ ์ ˆํ•œ ํด๋ฐฑ๊ณผ ํ•จ๊ป˜ ์ง€์›๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

require('react')๊ฐ€ 3๋‹จ๊ณ„์—์„œ ๊ณ„์† ์ž‘๋™ํ• ๊นŒ์š”?

๋‚˜๋Š” ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•œ๋‹ค. https://nodejs.org/api/esm.html#esm_dual_commonjs_es_module_packages ๋ฐ https://nodejs.org/api/esm.html#esm_package_entry_points๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ๋ฌผ๋ก  ๋‚ด๊ฐ€ ๋ชจ๋“  ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ๋ชจ๋“  ์ƒํ™ฉ์„ ์•Œ ์ˆ˜๋Š” ์—†์ง€๋งŒ ๋‚ด๊ฐ€ ์ œ์•ˆํ•œ ์ „ํ™˜ ๊ฒฝ๋กœ๋Š” "์–ด๋””์„œ๋‚˜ ์ž‘๋™ํ•  ๊ฒƒ"์ด๋ผ๊ณ  ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๊ทธ ์œ ๋ช…ํ•œ ๋งˆ์ง€๋ง‰ ๋ง์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค ๐Ÿ˜„

์ถ”๊ฐ€ ์„ค๋ช…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฒŒ์‹œ๋œ tarball์ด React์— ๋Œ€ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

node_modules/react/
  cjs/
    react.development.js
    react.production.min.js
    react.profiling.min.js
  umd/
    react.development.js
    react.production.min.js
    react.profiling.min.js
  esm/
    react.development.js
    react.production.min.js
    react.profiling.min.js
  index.js

๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์— package.json์ด ์–ด๋–ป๊ฒŒ ๋  ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ๊ทผ์‚ฌ์น˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{
  "type": "module",
  "main": "index.js",
  "module": "esm/react.development.js",
  "exports": {
    "import": "./esm/react.development.js",
    "require": "./cjs/react.development.js"
  }
}

^ ์ด๊ฒƒ์€ ์™„์ „ํžˆ ์ƒ๊ฐํ•˜๊ณ  ์™„์„ฑํ•œ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์ œ์•ˆ์— ๋Œ€ํ•œ ๊ตฌ์ฒด์ ์ธ ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ - React๋Š” ์ƒํƒœ ์ €์žฅ(ํ›…)์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด์ค‘ ํŒจํ‚ค์ง€ ์œ„ํ—˜์„ ๊ฒช์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ์ƒํƒœ๋Š” ์‹ ์ค‘ํ•˜๊ฒŒ ๊ฒฉ๋ฆฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. CJS ๋ฐ ESM ํ•ญ๋ชฉ ๋ชจ๋‘์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” ์ž‘์€ CJS ํŒŒ์ผ์— ์žˆ์–ด์•ผ ํ•˜๊ฑฐ๋‚˜ .json ๋กœ๋“œํ•˜๊ณ  ๋‘ ํ•ญ๋ชฉ์—์„œ ํ•ด๋‹น ์ƒํƒœ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ ‘๊ทผ).

๋˜ํ•œ ์ด๋ฏธ 1๋‹จ๊ณ„์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ…Œ์ด๋ธ”์— ๋‚˜์—ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ถ€ ์ฝ”๋„ˆ ์ผ€์ด์Šค๋ฅผ ๋†“์นœ ์ ์ด ์—†๋Š”์ง€ 100% ํ™•์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ์ฃผ์ œ๋Š” ๋งค์šฐ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ๋™์‹œ์— ์ผ์ •์€ ์ƒํƒœ๊ณ„ ์ฒดํฌํฌ์ธํŠธ์™€ ์—ฐ๊ฒฐ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 3๋‹จ๊ณ„๋Š” exports ๋ฒˆ๋“ค๋Ÿฌ์—์„œ ์ถฉ๋ถ„ํ•œ ์ง€์›์ด ์žˆ์–ด์•ผ๋งŒ ๋ฐฐ์†ก๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

React๋Š” ์ƒํƒœ ์ €์žฅ(ํ›„ํฌ)์ด๋ฏ€๋กœ ์ด์ค‘ ํŒจํ‚ค์ง€ ์œ„ํ—˜์ด ์žˆ์œผ๋ฏ€๋กœ ์ด ์ƒํƒœ๋ฅผ ์‹ ์ค‘ํ•˜๊ฒŒ ๊ฒฉ๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ข‹์€ ์ , ๋‚˜๋Š” ์ด๊ฒƒ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค( ์ถ”๊ฐ€ ์ •๋ณด ). ์ด ๊ฒฝ์šฐ CJS/ESM ๋นŒ๋“œ ๊ฐ„์— ๊ณต์œ  ํŒŒ์ผ์„ ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์ด ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ESM ๋ฒ„์ „์ด react์˜ ์ „์ฒด ๋ณต์‚ฌ๋ณธ์ด ์•„๋‹ˆ๋ผ CJS ๋นŒ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ESM ๊ณต๊ฐœ ์ธํ„ฐํŽ˜์ด์Šค์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ด๋ฏธ 1๋‹จ๊ณ„์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ…Œ์ด๋ธ”์— ๋‚˜์—ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์†Œ์Šค ์ฝ”๋“œ์—์„œ ์ด๋ฏธ ํ•ด๋‹น๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ์†Œ์Šค ์ฝ”๋“œ๋Š” ์ด๋ฏธ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋กœ ํ•ญ๋ชฉ์„ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.

https://github.com/facebook/react/blob/ef22aecfc52cdf0d7cedc723c590719c009c2a64/packages/react/index.js#L39

https://github.com/facebook/react/blob/ef22aecfc52cdf0d7cedc723c590719c009c2a64/packages/react/index.js#L39

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

3๋‹จ๊ณ„์— ๋Œ€ํ•ด ๋™์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ธŒ๋ ˆ์ดํ‚น ์ฒด์ธ์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•ด ๋ฌผ์Œํ‘œ๋ฅผ ํ‘œ์‹œํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค. package.json ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์ข…์ข… ์ƒํƒœ๊ณ„์˜ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€์— ๋Œ€ํ•œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ฃผ์ œ๋Š” ํ™•์‹คํžˆ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ํ•œ ๊ฐ€์ง€ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ์ ์€ ์›ํ•˜๋Š” ๊ฒฝ์šฐ 3๋‹จ๊ณ„์™€ 4๋‹จ๊ณ„์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ ๋‹จ๊ณ„๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์€ webpack, ๋กค์—…, nodejs ๋“ฑ์˜ ์—ฌ๋Ÿฌ ๋ฒ„์ „์— ๋Œ€ํ•ด ๋งค์šฐ ์ฒ ์ €ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ์ž‘์—…์ด ์‚ฌ์†Œํ•˜๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์—ฌ๊ธฐ์—์„œ ์ „ํ™˜ ๊ฒฝ๋กœ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค :)

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์†Œ์Šค ์ฝ”๋“œ์—์„œ ์ด๋ฏธ ํ•ด๋‹น๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ์†Œ์Šค ์ฝ”๋“œ๋Š” ์ด๋ฏธ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋กœ ํ•ญ๋ชฉ์„ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.

์•„ - ๋งž์•„์š”, ์ด ๊ฒฝ์šฐ export default ๐Ÿ˜‚๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ ํ…Œ์ด๋ธ” ํ–‰์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ๋Œ€๋ถ€๋ถ„์˜ ๋ฒˆ๋“ค๋Ÿฌ์—์„œ ์ž‘๋™ํ•˜๊ณ  ๋„๋ฆฌ ์‚ฌ์šฉ๋˜์ง€๋งŒ default ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ  ์ง„์ •ํ•œ ESM ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๊ทธ ์‚ฌ์šฉ๋ฒ•์„ ๊นจ์‹ญ์‹œ์˜ค.

์ด ๊ฒฝ์šฐ ๋‚ด๋ณด๋‚ด๊ธฐ ๊ธฐ๋ณธ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ ํ…Œ์ด๋ธ” ํ–‰์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋„ค, ์ข‹์€ ์ง€์ ์ž…๋‹ˆ๋‹ค. ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” PR์€ "๋‚˜์˜๊ฒŒ ๋ณด์ผ ๊ฒƒ"์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ํ˜„์žฌ์˜ ๊ณต๊ฐœ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ๋ฐ›์•„๋“ค์ด๊ณ  ์•ž์œผ๋กœ ๊ฐœ์„ ํ•  ๊ณ„ํš์ด๋ผ๊ณ  ๋ด…๋‹ˆ๋‹ค.

์ผ๋ถ€ ๋ฒ„์ „์ด ๊ฒŒ์‹œ๋˜๋ฉด ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์œผ๋ฉฐ ์˜๋ฏธ๋ก ์  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๊นจ์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์ด์ €๋ฅผ ์ž์ฃผ ๋ฆด๋ฆฌ์Šคํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ๋ณ€๋™์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ/ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ๋ถ„ํ• ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์งˆ๋ฌธ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ React ๋นŒ๋“œ์˜ ์ƒํƒœ ์ €์žฅ ํŠน์„ฑ์€ ๋ณด์กดํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ถ€ ๋ฒ„์ „์ด ๊ฒŒ์‹œ๋˜๋ฉด ๋˜๋Œ๋ฆด ์ˆ˜ ์—†์œผ๋ฉฐ ์˜๋ฏธ๋ก ์  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๊นจ์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์ด์ €๋ฅผ ์ž์ฃผ ๋ฆด๋ฆฌ์Šคํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ๋ณ€๋™์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ข‹์€ ์ . ๋‚ด ์•„์ด๋””์–ด๋Š” React 16์— ๊ฒŒ์‹œ๋œ ESM ๋นŒ๋“œ์— ๋ช…์‹œ์ ์ธ export default React ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. PR์ด ์ผ๋ถ€ ๋ˆˆ์น์„ ์ผ์œผํ‚ค๊ณ  ๋…ผ๋ž€์˜ ์—ฌ์ง€๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ชฉ์ ์ง€๊ฐ€ ๊ฒฐ์ •๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ œ ์ƒ๊ฐ์—๋Š” React 16์—์„œ ESM ๋นŒ๋“œ๋ฅผ ๊ฐ–๊ณ  ๋‹ค์Œ ์ฃผ์š” ๋ฒ„์ „์—์„œ export default ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ import React from 'react'; ๋ฅผ ํ†ตํ•ด ๋ฐ˜์‘์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ผ๋ฐ˜์ ์ด์–ด์„œ ESM ๋นŒ๋“œ์—์„œ ๊ธฐ๋ณธ๊ฐ’์„ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒƒ์€ ๋‹จ์ˆœํžˆ "์šฐ๋ฆฌ๊ฐ€ ์žˆ๋Š” ๊ณณ์„ ์ˆ˜๋ฝ"ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ–ฅํ›„ ์ฃผ์š” ๋ฒ„์ „์—์„œ๋Š” ์ด๋ฅผ ์ œ๊ฑฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

๊ฐœ๋ฐœ/ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ๋ถ„ํ• ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์งˆ๋ฌธ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ๊ฐ„๊ณผ ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฒˆ๋“ค๋Ÿฌ์™€ NodeJS ๋ชจ๋‘์—์„œ ESM์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด์ง€๋งŒ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋ณด๊ธฐ ์œ„ํ•ด ๋ช‡ ๊ฐ€์ง€ ์กฐ์‚ฌ๋ฅผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ์ฃฝ์€ ์ œ์•ˆ์„ ์ฐพ์•˜์ง€๋งŒ ์‚ด์•„์žˆ๋Š”

๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ React ๋นŒ๋“œ์˜ ์ƒํƒœ ์ €์žฅ ํŠน์„ฑ์€ ๋ณด์กดํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๋™์˜. ํ•œ ๊ฐ€์ง€ ์ฃผ์˜ํ•  ์ ์€ React ๋นŒ๋“œ์˜ stateful ํŠน์„ฑ์€ Phase 1๊ณผ 2๊ฐ€ ์•„๋‹ˆ๋ผ Phase 3์—์„œ๋งŒ ํ•ด๊ฒฐํ•˜๋ฉด ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. @Andarist ์™€ ์ œ๊ฐ€ ์ œ์•ˆํ•œ ์˜ต์…˜์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ ๊ฐ€์žฅ ์‰ฌ์šด, ๊ฐ€์žฅ ํ•˜์œ„ ํ˜ธํ™˜์„ฑ ์ ‘๊ทผ๋ผ๋Š” ์ด๋ฆ„์˜ ์ˆ˜์ž…์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฐ„๋‹จํ•œ ESM ๋ž˜ํผ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ React์— ์ถ”๊ฐ€ํ•˜๋Š” PR์„ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. "exports" ํ•„๋“œ์˜ ์ถ”๊ฐ€๊ฐ€ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์•„๋‹˜์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค(์ €๋Š” ์ด๊ฒƒ์„ ์‰ฝ๊ฒŒ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก npx ls-exports ๋„๊ตฌ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค). ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค ์—†์ด ESM์„ ์‚ฌ์šฉํ•˜๋ ค๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š์ง€๋งŒ ๊ฐœ๋ณ„ ํŒจํ‚ค์ง€๊ฐ€ ์–ด์จŒ๋“  ํ•ด๊ฒฐํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

@gaearon ์œ ์šฉํ• ๊นŒ์š”? ๊ทธ๊ฒƒ์€ semver-minor๋กœ React 16์— ์ฐฉ๋ฅ™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CJS ๋นŒ๋“œ๋Š” ์ง€๊ธˆ๊ณผ ๊ฐ™์ด ํ™˜๊ฒฝ ๊ฐ์ง€๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ESM์˜ (์–ด๋ ค์šด, ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€) ๋ฌธ์ œ๋ฅผ ์•„์ง ํŒŒ์•…ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ œ ์ƒ๊ฐ์—๋Š” React 16์—์„œ ESM ๋นŒ๋“œ๋ฅผ ๋งŒ๋“  ๋‹ค์Œ ํ–ฅํ›„ ์ฃผ์š” ๋ฒ„์ „์—์„œ ๋‚ด๋ณด๋‚ด๊ธฐ ๊ธฐ๋ณธ๊ฐ’์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

๊ทธ๋Ÿฌ๋‚˜ ์ œ ์ƒ๊ฐ์—๋Š” React 16์—์„œ ESM ๋นŒ๋“œ๋ฅผ ๋งŒ๋“  ๋‹ค์Œ ํ–ฅํ›„ ์ฃผ์š” ๋ฒ„์ „์—์„œ ๋‚ด๋ณด๋‚ด๊ธฐ ๊ธฐ๋ณธ๊ฐ’์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค๊ฐ€ ์–ผ๋งˆ๋‚˜ ์˜ค๋ž˜ ๋˜๋Š”์ง€์— ๋‹ฌ๋ ค ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์ผ์ฃผ์ผ์˜ ์ฐจ์ด์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•œ๋‹ค๋ฉด ๊ทธ๊ฒƒ์€ ํ•ฉ๋ฆฌ์ ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๊ฐ€ ๋ช‡ ๊ฐœ์›” / ๋ช‡ ๋…„์„ ์ด์•ผ๊ธฐํ•œ๋‹ค๋ฉด ๊ทธ ์‹œ๊ฐ„ ๋™์•ˆ ๊ทธ๊ฒƒ์„ ๊บผ๋‚ด๋Š” ๊ฒƒ์ด ์™œ ๋‚˜์œ์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ์˜ ์šฐ๋ ค๋Š” ๊ทธ๊ฒƒ์ด ๋” ์˜ค๋ž˜ ์กด์žฌํ• ์ˆ˜๋ก ๋” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ํ˜„์žฌ ํ˜•ํƒœ๋กœ ๊ทธ๊ฒƒ์— ์˜์กดํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฑฐ๊ธฐ์— ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋„์ž…ํ•˜๋ฉด React๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ธฐ๊ฐ€ ๋” ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค. ์ด์ œ ํ•˜๋‚˜์˜ ESM ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ์œผ๋ฉฐ ์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์€ ๋„ˆ๋ฌด ์ผ์ฐ ๋›ฐ์–ด๋“ค์–ด ๋‚˜์ค‘์— ๋‹ค๋ฅธ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์œ„ํ•œ ๋ฆฌ์†Œ์Šค๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋’ค์ฒ˜์ง€๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ESM์˜ ๊ฒฝ์šฐ ์ƒํƒœ๊ณ„ ์ „๋ฐ˜์— ๊ฑธ์ณ ํŒŒ๊ธ‰๋ ฅ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

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

๋‚˜๋Š” import React from 'react' ๋ฅผ ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๊ฒƒ์œผ๋กœ ๋ณด์ง€ ์•Š๊ณ  ์˜คํžˆ๋ ค ํ˜„์žฌ์˜ ํ˜„์‹ค์„ ์ˆ˜์šฉํ•œ๋‹ค. ์ด๊ฒƒ์€ ์•„๋งˆ๋„ ์˜๋„ํ•˜์ง€ ์•Š์•˜๊ณ  ์ง€๊ธˆ์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ESM/CJS ์ƒํ˜ธ ์šด์šฉ์„ฑ์˜ ๋ถ€์ž‘์šฉ์ผ ๋ฟ์ด์ง€๋งŒ ์—ฌ์ „ํžˆ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์ˆ˜์ฒœ(๋ฐฑ๋งŒ?) ์ค„์˜ ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์•ˆ(๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋งŒ ๋‚ด๋ณด๋‚ด๊ธฐ)์€ ์‚ฌ์šฉ์ž์—๊ฒŒ "์šฐ๋ฆฌ๋Š” ๋งˆ์ด๋„ˆ ๋ฒ„์ „์œผ๋กœ ESM ๋นŒ๋“œ๋ฅผ ๊ฒŒ์‹œํ–ˆ์ง€๋งŒ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค"๋ผ๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” "์ œ๊ฑฐ๋œ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ"๋ฅผ ๋ณด๋Š” ๊ฒƒ๋ณด๋‹ค ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ์ฃผ์š” ๋ฒ„์ „์˜ ๋ฆด๋ฆฌ์Šค ์ •๋ณด์—์„œ.

๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์žˆ๋Š” ESM์„ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ์ด์ „์— ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค(์˜ˆ: https://github.com/facebook/react/pull/18187 ๋˜ํ•œ ๊ด€๋ จ ๋ฌธ์ œ๋กœ ์—ฐ๊ฒฐ๋จ). ๋ฌธ์ œ๋Š”์™€ ์›นํŒฉ CJS <-> ๋‹น์‹ ์ดํ•˜๊ณ  CJS ์ฝ”๋“œ๊ฐ€์žˆ๋Š” ๊ฒฝ์šฐ ESM์˜ ์ƒํ˜ธ ์šด์šฉ์„ฑ require('react') ์›นํŒฉ์€ ESM์˜ ์กด์žฌ ๋ฐ˜ํ™˜ ๋ฌด์Šจ react ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ์™€ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค default CJS react ๊ด€๊ณ„์—†์ด default ์†์„ฑ(์ด์ œ require('react').default ๊ฐ€ ํ•„์š”ํ•จ์„ ์˜๋ฏธ). ํ•˜์ง€๋งŒ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋„ ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์„๊นŒ์š”? @TrySound ๋Š” ์ด์ „์— ๋‹ค๋ฅธ ํŒจํ‚ค์ง€์—์„œ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ

ํ•˜์ง€๋งŒ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋„ ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์„๊นŒ์š”?

์˜ˆ, ์ด๊ฒƒ์ด ์ œ๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. https://unpkg.com/browse/@esm-bundle/react @16.13.1/esm/react.development.js์˜ ๋งˆ์ง€๋ง‰ 40์ค„์„

ํ•˜์ง€๋งŒ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋„ ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์„๊นŒ์š”?

์˜ˆ, ์ด๊ฒƒ์ด ์ œ๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. https://unpkg.com/browse/@esm-bundle/react @16.13.1/esm/react.development.js์˜ ๋งˆ์ง€๋ง‰ 40์ค„์„

๊ทธ๋Ÿฌ๋‚˜ CJS ์ฝ”๋“œ ๋˜๋Š” ESM์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? CJS <-> ESM interop ๋ฌธ์ œ๊ฐ€ ๋งค์šฐ ๋†€๋ž๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

@gaearon ๋ง‘์Œ; ๋‚ด๊ฐ€ ์ œ์•ˆํ•˜๋Š” ESM ๋ž˜ํผ์— ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์—†๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ESM์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ชจ๋“  ์‚ฌ์šฉ์ž๋Š” ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด import * as React from 'react' ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ์‚ฌ๋žŒ์ด ๊ฐ‘์ž๊ธฐ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์—†๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ง€๊ธˆ ๊ธฐ๋ณธ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด v17๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ CJS ์ฝ”๋“œ ๋˜๋Š” ESM์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? CJS <-> ESM interop ๋ฌธ์ œ๊ฐ€ ๋งค์šฐ ๋†€๋ž๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

CJS ๋ฐ ESM ํŒŒ์ผ ๋ชจ๋‘์—์„œ webpack์œผ๋กœ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค.

๋„ค์ดํ‹ฐ๋ธŒ ESM์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์‚ฌ๋žŒ์€ *๋ฅผ 'react'์—์„œ React๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ์‚ฌ๋žŒ์ด ๊ฐ‘์ž๊ธฐ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ์—†๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ง€๊ธˆ ๊ธฐ๋ณธ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด v17๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋™์˜. ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ๋ณธ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๊ณ ๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์—†์ด 2๋‹จ๊ณ„ ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ React 16์—์„œ Phase 1์„ ์ˆ˜ํ–‰ํ•˜๊ณ  React 17+์—์„œ Phase 2-4๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์ง€๋งŒ Phase 1, 2, ์‹ฌ์ง€์–ด 3๊นŒ์ง€ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค(@ljharb ์˜ ๋‚ด๋ณด๋‚ด๊ธฐ ๊ฒ€์‚ฌ๊ธฐ ๋„๊ตฌ์˜ ๋„์›€์œผ๋กœ) ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊นจ๋œจ๋ฆฌ์ง€ ์•Š๊ณ  React 16์—์„œ. ๊ทธ ์ด์œ ๋Š” 2๋‹จ๊ณ„๊ฐ€ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๊ฐ€ ESM ๋ฒˆ๋“ค์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ํฐ ๋‹จ๊ณ„์ธ ๋ฐ˜๋ฉด, 1๋‹จ๊ณ„๋Š” ๋Œ€๋ถ€๋ถ„ ์–ผ๋ฆฌ ์–ด๋‹ตํ„ฐ/๋งค๋‹ˆ์•„๋ฅผ ์œ„ํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด ์ œ์•ˆ ์—์„œ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ƒํƒœ๋ฅผ ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ ๊ฒฉ๋ฆฌํ•˜์—ฌ ์ด์ค‘ ํŒจํ‚ค์ง€ ์œ„ํ—˜์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์™„์ „ํ•œ CJS ๋ฐ ESM ์†Œ์Šค๊ฐ€ ์žˆ๋Š” ์ด์ค‘ ํŒจํ‚ค์ง€๋กœ์˜ ์ „ํ™˜์— ๋Œ€ํ•œ ์ œ์•ˆ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค( ์ ‘๊ทผ๋ฒ• 2 ). ์ด์ „ RFC( ์ ‘๊ทผ๋ฒ• 1 )์™€ ๊ฐ™์€ ESM ๋ž˜ํผ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ๋Š” ๋Œ€์กฐ์ ์ž…๋‹ˆ๋‹ค.

๊ฐ€์ •ํ•˜๋ฉด ์•„์ง ์–ธ๊ธ‰๋˜์ง€ ์•Š์€ ๋ช‡ ๊ฐ€์ง€ ๋ฉ”๋ชจ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ESM ๋ฐ CommonJS ํŒŒ์ผ์ด ๋ชจ๋‘ .js ์‚ฌ์šฉํ•˜๋Š” Node.js ํŒจํ‚ค์ง€๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. "type": "module" ๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋ชจ๋“  CommonJS ํŒŒ์ผ์€ ๋Œ€์‹  .cjs ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ตญ๊ฐ€ ๋ฐ ํ‰๋“ฑ ์ด์ค‘ ํŒจํ‚ค์ง€ ์œ„ํ—˜์€ CJS์™€ ESM์ด ๋ชจ๋‘ ์žˆ๋Š” ์œ ์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ž ์žฌ์ ์œผ๋กœ ๋™์ผํ•œ ํŒจํ‚ค์ง€์˜ 2๊ฐœ ๋ฒ„์ „์„ ๋กœ๋“œํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ React์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„๋„ ์ฆ๊ฐ€ํ•˜๋ฉฐ React๋Š” ์ž‘์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ฑฐ๋ž˜ ์ฐจ๋‹จ๊ธฐ๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ๋ช…์‹ฌํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • React์˜ ๋‚ด๋ถ€ ์ƒํƒœ ์™ธ์— ์ด์ค‘ ํŒจํ‚ค์ง€ ์œ„ํ—˜ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๊ณ  ๋ด…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Component ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์ด ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•˜๋Š” CJS ์ฝ”๋“œ์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹ˆ๊ณ  ๋Œ€์‹  CJS/ESM ๋ฒˆ๋“ค์˜ ์ผ๋ถ€์ธ ๊ฒฝ์šฐ ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ instanceof Component ๊ฒ€์‚ฌ์˜ ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ๊ดด.

ESM ๋ฐ CommonJS ํŒŒ์ผ์ด ๋ชจ๋‘ .js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Node.js ํŒจํ‚ค์ง€๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. "type": "module"์„ ์„ค์ •ํ•˜๋ฉด ๋ชจ๋“  CommonJS ํŒŒ์ผ์€ ๋Œ€์‹  .cjs ํŒŒ์ผ ํ™•์žฅ์ž๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์—์žˆ๋Š” ํŒŒ์ผ NodeJS์— ๋Œ€ํ•œ (ํ•˜์ง€๋งŒ bundlers ์œ„ํ•ด) ๋•Œ๋ฌธ์—,์ด ์‚ฌ์‹ค์ด๋‹ค cjs ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ข…๋ฃŒํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค .cjs .

์ž ์žฌ์ ์œผ๋กœ ๋™์ผํ•œ ํŒจํ‚ค์ง€์˜ 2๊ฐœ ๋ฒ„์ „์„ ๋กœ๋“œํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ React์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„๋„ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ npm์— ๊ฒŒ์‹œ๋œ tarball ํฌ๊ธฐ๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ ๋””์Šคํฌ์˜ ์ „์ฒด ํฌ๊ธฐ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ๋ฉ”๋ชจ๋ฆฌ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์•„๋Š” ํ•œ, ๋ฒˆ๋“ค๋Ÿฌ์™€ NodeJS๋Š” import / require() ๋ฅผ ํ†ตํ•ด ๋กœ๋“œ๋˜์ง€ ์•Š์€ ์ฝ”๋“œ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๊ฐ€์ ธ์˜ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ํ’‹ํ”„๋ฆฐํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝ๋˜๋Š”์ง€ ๋ช…ํ™•ํžˆ ํ•ด์ฃผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ๋ฅผ ๋“ค์–ด Component ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์ด ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•˜๋Š” CJS ์ฝ”๋“œ์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹ˆ๊ณ  ๋Œ€์‹  CJS/ESM ๋ฒˆ๋“ค์˜ ์ผ๋ถ€์ธ ๊ฒฝ์šฐ ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ instanceof Component ๊ฒ€์‚ฌ๊ฐ€ ์ค‘๋‹จ๋  ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ์•ˆ๋œ ์†”๋ฃจ์…˜( 1 , 2 ) ์ค‘ ํ•˜๋‚˜๋Š” NodeJS esm ๊ตฌํ˜„์ด CJS ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ESM ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด Node.js์—์„œ ์‚ฌ์šฉ๋˜๋Š” Component ์ •์˜๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. 1๋‹จ๊ณ„์™€ 2๋‹จ๊ณ„๋Š” NodeJS์—์„œ ์‹คํ–‰๋˜๋Š” ํ•ญ๋ชฉ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ด๋Š” 3๋‹จ๊ณ„์—๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ตœ๊ทผ์— ์šฐ๋ฆฌ(webpack)๊ฐ€ webpack 5์— exports ํ•„๋“œ ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ์ฃผ์ œ์— 2์„ผํŠธ๋ฅผ ์ฃผ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

  • ์ด WIP(work-in-process) ๋ฌธ์„œ์—๋Š” webpack์— ๊ด€ํ•œ exports ํ•„๋“œ๋ฟ ์•„๋‹ˆ๋ผ Node.js ๋ฐ ์ผ๋ฐ˜์ ์œผ๋กœ https://gist.github.com/sokra/e032a0f17c1721c71cfced6f14516c62์— ๋Œ€ํ•œ ๋งŽ์€ ์ •๋ณด๊ฐ€
  • ๋‹ค์Œ์€ Node.js์™€ ๋น„๊ตํ•œ ํ•ต์‹ฌ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

    • webpack 5์—๋Š” development ๋ฐ production ์กฐ๊ฑด๋„ ์ถ”๊ฐ€๋˜์–ด ๋ฐ˜์‘์— ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ( process.env.NODE_ENV ๋Š” ๊ณ„์† ์ง€์›๋˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ Node.js์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ํ”„๋ŸฐํŠธ์—”๋“œ ์ฝ”๋“œ์—์„œ๋Š” ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

    • webpack(๋ฐ ๊ธฐํƒ€ ๋ฒˆ๋“ค๋Ÿฌ)์€ require("esm") ์ง€์›ํ•˜๋ฏ€๋กœ ํ•ญ์ƒ ESM์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด์ค‘ ์ƒํƒœ ๋ฌธ์ œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค( require() ). webpack์€ ์ด์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ์กฐ๊ฑด์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค: module . ์ด CommonJs ๋ฐ ESM ๋ฒ„์ „์˜ ๊ฒฝ์šฐ ๋™์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋‚ด๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ Node.js๋งŒํผ ์ด์ค‘ ์ƒํƒœ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋Œ€๋ถ€๋ถ„ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฏธ๋ž˜์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

      ์ตœ๋Œ€ํ•œ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ๋‹ค์Œ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

ํŒจํ‚ค์ง€.json

{
    "type": "commonjs",
    "main": "index.js",
    "module": "esm/wrapper.js",
    "exports": {
        ".": {
            "node": {
                "development": {
                    "module": "./esm/index.development.js",
                    "import": "./esm/wrapper.development.js",
                    "require": "./cjs/index.development.js"
                },
                "production": {
                    "module": "./esm/index.production.min.js",
                    "import": "./esm/wrapper.production.min.js",
                    "require": "./cjs/index.production.min.js"
                },
                "import": "./esm/wrapper.js",
                "default": "./cjs/index.js"
            },
            "development": "./esm/index.development.js",
            "production": "./esm/index.production.min.js",
            "default": "./esm/index.production.min.js"
        },
        "./index": "./index.js",
        "./index.js": "./index.js",
        "./umd/react.development": "./umd/react.development.js",
        "./umd/react.development.js": "./umd/react.development.js",
        "./umd/react.production.min": "./umd/react.production.min.js",
        "./umd/react.production.min.js": "./umd/react.production.min.js",
        "./umd/react.profiling.min": "./umd/react.profiling.min.js",
        "./umd/react.profiling.min.js": "./umd/react.profiling.min.js",
        "./package.json": "./package.json"
    }
}

esm/ํŒจํ‚ค์ง€.json

์ด ๋””๋ ‰ํ† ๋ฆฌ์—์„œ .js ๋ฅผ ํ™•์žฅ์ž๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” .mjs ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋„๊ตฌ์—์„œ ํ™•์žฅ์„ ํ™•์ธํ•  ๋•Œ ์ž ์žฌ์ ์ธ ๋ถ€์ž‘์šฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ .js ๋Š” ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

{
    "type": "module"
}

esm/wrapper.js

์ด ๋ž˜ํผ๋Š” Node.js๊ฐ€ ์ด์ค‘ ์ƒํƒœ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

import React from "../cjs/index.js";
export const {
    Children,
    Component,
    ...,
    useState,
    version
} = React;
export { React as default };

cjs/index.js

development ๋ฐ production ์กฐ๊ฑด์ด ์ง€์›๋˜์ง€ ์•Š์„ ๋•Œ Node.js์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

'use strict';

if (process.env.NODE_ENV === 'production') {
  module.exports = require('./cjs/react.production.min.js');
} else {
  module.exports = require('./cjs/react.development.js');
}

esm/wrapper.development.js (esm/wrapper.production.min.js ์œ ์‚ฌ)

์ด๋Ÿฌํ•œ ๋ž˜ํผ๋Š” ์ด์ค‘ ์ƒํƒœ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด Node.js์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
Node.js๊ฐ€ development ๋ฐ production ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

import React from "../cjs/index.development.js";
export const {
    Children,
    Component,
    ...,
    useState,
    version
} = React;
export { React as default };

index.js

์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด.

module.exports = require('./cjs/index.js');

esm/index.development.js, esm/index.production.min.js

์ด๊ฒƒ์€ exports ํ•„๋“œ, module ์กฐ๊ฑด ๋ฐ production / development ์กฐ๊ฑด์„ ์ง€์›ํ•˜๋Š” ๋„๊ตฌ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

/* React in ESM format */

// compat for the default exports with support for tree-shaking
import * as self from "./esm/index.development.js";
export { self as default }

๊ฒฐ๊ณผ

  • ์›นํŒฉ 5: ./esm/index.development.js ๋˜๋Š” ./esm/index.production.min.js
  • ๋ธŒ๋ผ์šฐ์ €ํ™”: ./cjs/index.js
  • .mjs์˜ ์›นํŒฉ 4: ./cjs/index.js
  • ๋‹ค๋ฅธ ๋ฒˆ๋“ค๋Ÿฌ: ./esm/wrapper.js
  • Node.js(ESM): ./cjs/index.js (ํ•„์ˆ˜) ๋˜๋Š” ./esm/wrapper.js (๊ฐ€์ ธ์˜ค๊ธฐ)
  • Node.js(์ด์ „): ./cjs/index.js
  • Node.js๋ฅผ (ESM + DEV / ์ž๊ทน) : ./esm/wrapper.development.js ๋˜๋Š” ./esm/wrapper.production.min.js ์ˆ˜์ž…, ./cjs/index.development.js ๋˜๋Š” ./cjs/index.production.min.js ์— ํ•„์š”ํ•œ

๋…ธํŠธ

์กฐ๊ฑด๋ถ€๋กœ ๋ฒ„์ „์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ์€ ์ฃผ์š” ์ ˆ์ถฉ ์—†์ด ESM์—์„œ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— esm/index.js ๋Š” ์—†์Šต๋‹ˆ๋‹ค.
๋„๊ตฌ๋Š” exports ํ•„๋“œ, module ์กฐ๊ฑด(์ด์ค‘ ์ƒํƒœ ๋ฌธ์ œ ๋•Œ๋ฌธ์—) ๋ฐ production / development ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฐ˜์‘ ESM์˜ ์ด์ ์„ ์ถฉ๋ถ„ํžˆ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

๋„๊ตฌ๋Š” module ํ•„๋“œ ๋˜๋Š” exports ํ•„๋“œ๋ฅผ ์ง€์›ํ•  ๋•Œ ๋ฐ˜์‘ ESM์˜ ์ด์ ์„ ๋ถ€๋ถ„์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { useState } from "react" ๋˜๋Š” import * as React from "react" ๋Š” long react๊ฐ€ CommonJs ๋ชจ๋“ˆ์ธ ํ•œ ๊ธฐ์ˆ ์ ์œผ๋กœ ๋ถˆ๋ฒ•์ž…๋‹ˆ๋‹ค.
๋Œ€๋ถ€๋ถ„์˜ ๋„๊ตฌ๋Š” ์—ฌ์ „ํžˆ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์ง€์›ํ•˜์ง€๋งŒ ์ผ๋ถ€๋Š” ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์˜ˆ: Node.js).
๋”ฐ๋ผ์„œ ํ˜„์žฌ ๋ชจ๋“  ๊ณณ์—์„œ ์œ ํšจํ•œ react๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ import React from "react" ์ž…๋‹ˆ๋‹ค.
์ด ๋ฐฉ๋ฒ•์€ ๊ณ„์† ์ง€์›๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ง€๊ธˆ ๋ฐ˜์‘ํ•˜๊ณ  ESM ์ถ”๊ฐ€ ํ›„ ๋ฐ˜์‘์— ์œ ํšจํ•œ ๊ตฌ๋ฌธ์ด ์—†๋Š” ๊ฒฝ์šฐ(์˜ˆ: Node.js 14)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Node.js๋ฅผ๊ฐ€ ์ฒจ๊ฐ€ ๊ฑฐ๋ถ€ development / production ๋Œ€ํ•œ ์กฐ๊ฑด exports ์ง€๊ธˆ์žˆ๋‹ค.
๊ทธ๊ฒƒ์€ ์Šฌํ”„๊ณ , ๋‚˜๋Š” ์—ฌ์ „ํžˆ ๊ทธ๋“ค์ด ๊ฒฐ๊ตญ ๊ทธ๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.
๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์œ„์˜ exports ํ•„๋“œ์— ์ด์— ๋Œ€ํ•œ ์ง€์›์ด ์ค€๋น„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

@sokra ํ›Œ๋ฅญํ•œ ๋ถ„์„, ๋งค์šฐ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

์ž‘์€ ์งˆ๋ฌธ ํ•˜๋‚˜:

Node.js๋Š” ํ˜„์žฌ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์œ„ํ•œ ๊ฐœ๋ฐœ/์ƒ์‚ฐ ์กฐ๊ฑด ์ถ”๊ฐ€๋ฅผ ๊ฑฐ๋ถ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ์ดํ•ด๋Š” ๊ทธ๊ฒƒ์ด ์•„์ง ์ž‘์—… ์ค‘์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๊นŒ? https://github.com/nodejs/node/pull/33171 ํ•˜์ง€๋งŒ ์•„๋งˆ๋„ ๋‚ด๊ฐ€ ๊ทธ PR์„ ์˜คํ•ดํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค

[ํŽธ์ง‘] ๋‚ด๊ฐ€ ๋งํฌํ•œ ์œ„์˜ PR์€ https://github.com/nodejs/node/pull/34637 ๋กœ ๋Œ€์ฒด๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

[edit2] ์ด์ œ nodejs์— ๋ณ‘ํ•ฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@sokra ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ์œ ์šฉํ•œ ์ œ์•ˆ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ณด๋Š” ์˜ต์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ชจ๋‘ ๊ธฐ์ˆ ์ ์œผ๋กœ ๊ฐ€๋Šฅํ•˜๊ณ  ๊ฒฐ์ •์€ ๊ธฐ์ˆ  ๊ตฌํ˜„๋ณด๋‹ค ์ „๋žต ์ค‘ ํ•˜๋‚˜์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์˜ต์…˜ 1

export default React ๋ฅผ React 17 ESM ๋นŒ๋“œ์— ์ถ”๊ฐ€ํ•˜๊ณ  import React from 'react' ๋Œ€ํ•œ CJS ์ง€์›์ด ์ค‘๋‹จ๋˜๋ฉด ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค(์•„๋งˆ๋„ React 18์—์„œ?).

์˜ต์…˜ 2

export default React ์ถ”๊ฐ€ํ•˜์ง€ ๋ง๊ณ  ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋งŒ ์žˆ๋Š” React 17 ESM ๋นŒ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.

์˜ต์…˜ 3

React 17 ESM ๋นŒ๋“œ๋ฅผ ๊ฒŒ์‹œํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. (๐Ÿ˜ข) ESM ๋นŒ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์ „์— import React from 'react'; ์ง€์›์ด ์ค‘๋‹จ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์„ธ์š”.

๋น„๊ต

| | ์˜ต์…˜ 1 | ์˜ต์…˜ 2 | ์˜ต์…˜ 3 |
| - | -------- | -------- | -------- |
| ์ฐธ์กฐ๋˜์ง€ ์•Š์€ ESM ๋นŒ๋“œ | v17 | v17 | v18+ |
| package.json "module"(๊ธฐ๋ณธ์ ์œผ๋กœ ํŠธ๋ฆฌ ํ”๋“ค๊ธฐ) | v17 | v18+ | v18+ |
| package.json "์œ ํ˜•" / "๋‚ด๋ณด๋‚ด๊ธฐ"(NodeJS๋Š” ESM ์‚ฌ์šฉ) | v18+ 1 | v18+ | v18+ |

  1. ์™„์ „ํžˆ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ package.json ์œ ํ˜•/๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์˜ต์…˜ 1์ด ์„ ํƒ๋˜๋ฉด React 17์˜ ์ผ๋ถ€๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋‚ด ์„ ํ˜ธ๋„๋Š” ์˜ต์…˜ 1์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์˜ต์…˜ 2๋„ ๋‚˜์—๊ฒŒ ๋งค์šฐ ํฅ๋ฏธ์ง„์ง„ํ•ฉ๋‹ˆ๋‹ค. ์˜ต์…˜ 3์€ ๋ฌผ๋ก  ๋œ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. ์ด github ๋ฌธ์ œ์—์„œ ์ˆ˜์ง‘ํ•œ ๊ฒƒ์—์„œ ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ ์ผ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๊ธฐ์ˆ ์  ์ „๋ฌธ ์ง€์‹์„ ๊ฐ–์ถ”๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(์•„๋งˆ๋„ ๋…ธ๋™๋ ฅ๊นŒ์ง€!).

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ดˆ๊ธฐ ๋ฐ˜์‘์€ "์ด ๋ฌธ์ œ๊ฐ€ 3๋…„์ด ์ง€๋‚œ ํ›„์—๋„ ๊ณต๊ฐœ๋˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?"์˜€์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€๋ฅผ ์ฝ๊ณ  ๋‚˜๋ฉด ์™œ ๊ทธ๋ ‡๊ฒŒ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š”์ง€ ์ดํ•ด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. React์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์—„์ฒญ๋‚œ ์ž‘์—…์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๐Ÿ™‡๐Ÿป

React 17์— ๋Œ€ํ•œ ์ตœ๊ทผ ๋‰ด์Šค๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ํ–ฅํ›„ ๊ณ„ํš์— ๋Œ€ํ•ด React 16 ๋Œ€์‹  React 17์„ ์ฐธ์กฐํ•˜๋„๋ก ์ด์ „ ์˜๊ฒฌ์„ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ์„ธ ๊ฐ€์ง€ ์˜ต์…˜ ์ค‘ ์–ด๋Š ๊ฒƒ์ด ์„ ํ˜ธ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ์˜๊ฒฌ์„ ๋ณด๋‚ด์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

React 17์˜ package.json ์— exports ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๋ฒ„์ „์œผ๋กœ๋„ ๋ฐฑํฌํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{
  "exports": {
    ".": {
      "development": "./esm/react.development.mjs",
      "production": "./esm/react.production.mjs",
      "node": {
        "import": "./esm/react.node.mjs",
        "require": "./index.js"
      },
      "default": "./index.js"
    },
    "./jsx-dev-runtime": {
      "development": "./esm/react-jsx-dev-runtime.development.mjs",
      "production": "./esm/react-jsx-dev-runtime.production.mjs",
      "node": {
        "import": "./esm/react-jsx-dev-runtime.node.mjs",
        "require": "./jsx-dev-runtime.js"
      },
      "default": "./jsx-dev-runtime.js"
    },
    "./jsx-runtime": {
      "development": "./esm/react-jsx-runtime.development.mjs",
      "production": "./esm/react-jsx-runtime.production.mjs",
      "node": {
        "import": "./esm/react-jsx-runtime.node.mjs",
        "require": "./jsx-runtime.js"
      },
      "default": "./jsx-runtime.js"
    },
    "./": "./"
  },
}

์ƒˆ๋กœ์šด esm ๋ฒˆ๋“ค์ด ํ•„์š”ํ•˜์ง€๋งŒ ๋กค์—…์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๊ทธ๋ฆฌ ์–ด๋ ต์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ./esm/react.development.mjs ๋ฐ ./esm/react.production.mjs ๋ฒˆ๋“ค์€ process.env.NODE_ENV ์ˆ˜ํ‘œ๊ฐ€ ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    • ์กฐ๊ฑด์€ exports ํ•„๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ค๊ธฐ/๋ฒˆ๋“ค ์‹œ๊ฐ„์— ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

    • process ๋Š” ๋…ธ๋“œ API์ด๋ฉฐ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ์˜๋ฏธ๊ฐ€ ์—†์œผ๋ฉฐ ์˜ˆ๋ฅผ ๋“ค์–ด webpack 5์—์„œ _default_์—์„œ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ./esm/react.node.mjs ๋Š” process.env.NODE_ENV ์ˆ˜ํ‘œ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

    • ๋…ธ๋“œ ์ธก์— ํฐ ๋ฒˆ๋“ค์„ ๊ฐ–๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

    • ์‚ฌ์šฉ์ž๋Š” --conditions CLI ํ”Œ๋ž˜๊ทธ๋ฅผ ํ†ตํ•ด dev/prod ๋ฒˆ๋“ค์— ๊ณ„์† ์˜ตํŠธ์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • https://nodejs.org/dist/latest-v15.x/docs/api/packages.html#packages_resolving_user_conditions

  • AFAIK ์ „์šฉ webpack 5 ๋ฐ ๋…ธ๋“œ๋Š” ํ˜„์žฌ exports ํ•„๋“œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด WDYT๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์˜คํžˆ๋ ค ์•ˆ์ „ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

https://webpack.js.org/guides/package-exports/
https://nodejs.org/dist/latest-v15.x/docs/api/packages.html

"./": "./" ๋Š” ์•ˆ์ „ํ•˜์ง€๋งŒ ์บก์Šํ™”๋„ ๋ฐฉ์ง€ํ•˜๋ฏ€๋กœ semver-major๊ฐ€ ์žˆ๋Š” ์ฆ‰์‹œ ์ œ๊ฑฐํ•˜๊ณ  ์‹ถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

FWIW babel์€ ์ƒˆ๋กœ์šด jsx ๋Ÿฐํƒ€์ž„ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

import { jsxs, jsx, Fragment } from 'react/jsx-runtime';

๊ทธ๋Ÿฌ๋‚˜ Node์—์„œ ์ด์™€ ๊ฐ™์€ ๋ชจ๋“ˆ์„ ๋กœ๋“œํ•˜๋ฉด ํŒŒ์ผ ํ™•์žฅ์ž๊ฐ€ ์—†๋‹ค๊ณ  ๋ถˆํ‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

> node .\node.mjs
node:internal/process/esm_loader:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'test\node_modules\react\jsx-runtime' imported from test\node_modules\react-data-grid\lib\bundle.js
Did you mean to import react/jsx-runtime.js?
    at new NodeError (node:internal/errors:259:15)
    at finalizeResolution (node:internal/modules/esm/resolve:307:11)
    at moduleResolve (node:internal/modules/esm/resolve:742:10)
    at Loader.defaultResolve [as _resolve] (node:internal/modules/esm/resolve:853:11)
    at Loader.resolve (node:internal/modules/esm/loader:85:40)
    at Loader.getModuleJob (node:internal/modules/esm/loader:229:28)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:51:40)
    at link (node:internal/modules/esm/module_job:50:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

exports ์ถ”๊ฐ€ํ•˜๋ฉด ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค ๐Ÿค”

@nstepien์ด ์ด์ „ ๊ฒŒ์‹œ๋ฌผ์—์„œ ๋ณด์—ฌ์ฃผ๋“ฏ์ด ์ „์ฒด exports ์ง€๋„๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์ œ๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์˜ต์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค. cjs interop๊ณผ ๊ด€๋ จํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๋Š” ๋…ธ๋“œ๋Š” ๊ธฐ์กด ์ƒํƒœ๊ณ„์™€ ์ž˜ ์–ด์šธ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด์ค‘ ํŒจํ‚ค์ง€ ์œ„ํ—˜์€ ํ˜„์‹ค์ ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ๋‹จ์ผ ์‚ฌ๋ณธ์ด ํ•„์š”ํ•œ Reac๊ณผ ๊ฐ™์€ ํŒจํ‚ค์ง€์˜ ๊ฒฝ์šฐ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

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

@Andarist ๊ทธ๊ฒƒ์€ ์ž˜ ์ž‘๋™ํ•˜๊ณ  ๋ฐ˜์‘์˜ ๊ฒฝ์šฐ์—๋„ ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ ๊ทธ ์œ„ํ—˜์ด ์žˆ์—ˆ๊ณ  ์ƒํƒœ๊ณ„๋Š” ๋ฐ˜์‘์„ ๋ชจ๋“  ๊ณณ์—์„œ ํ”ผ์–ด ๋Ž์œผ๋กœ ๋งŒ๋“ค์–ด ์ด๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ESM ํŒŒ์ผ๊ณผ CJS ํŒŒ์ผ์ด ๋™์ผํ•œ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•˜๋Š” ํ•œ "๋‚ด๋ณด๋‚ด๊ธฐ" ๋งต์€ ์—ฌ๊ธฐ์—์„œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐ„๋‹จํ•œ ESM ๋ž˜ํผ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ „์ด์ ์ด๋“  ์•„๋‹ˆ๋“  React์˜ ๋ชจ๋“  ์ข…์†์„ฑ์ด React(์ด ๊ฒฝ์šฐ์—๋Š” ์žˆ์Œ)์˜ ์ œ์–ด ํ•˜์— ์žˆ๊ณ  ๋ชจ๋“  ESM ์ง„์ž…์ ์ด CJS ์ฝ˜ํ…์ธ ๋ฅผ ๋‹ค์‹œ ๋‚ด๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ ์ด ํŠน์ • ๊ฒฝ์šฐ์— ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ESM ํ•ญ๋ชฉ์˜ ์‹ค์ œ ๋ชจ์–‘์ด ์–ด๋– ํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ „์ฒด ๋“œ๋ผ๋งˆ๊ฐ€ ์—ฌ์ „ํžˆ ์žˆ์Šต๋‹ˆ๋‹ค(์ด๋ฆ„ ์ง€์ •, ๊ธฐ๋ณธ๊ฐ’, ๋‘˜ ๋‹ค).

  • Named-only: ๋งŽ์€ ์ฝ”๋“œ๊ฐ€ import React from 'react' ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ๋กœ๋Š” ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ESM์„ ์‚ฌ์šฉํ•  ๋•Œ ๋…ธ๋“œ์—์„œ ์‹ค์ œ๋กœ React๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
  • default-only: ๋งŽ์€ ์ฝ”๋“œ๊ฐ€ import * as React from 'react' ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ๋กœ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ข…์ข… ์œ ํ˜• ๊ฒ€์‚ฌ๊ธฐ ๋ฐ ๊ธฐํƒ€ ๋„๊ตฌ์— ์˜ํ•ด ์Šน๊ฒฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋‘˜ ๋‹ค: ์™„์ „ํžˆ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋„๋ก ํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด๋ฏ€๋กœ ๋ชจ๋“  ํ˜„์žฌ ๋กœ๋“œ ์Šคํƒ€์ผ๊ณผ ์ข…์†์„ฑ ํŠธ๋ฆฌ์—์„œ ESM ๋ฐ CJS ๋ชจ๋“ˆ์„ ํ˜ผํ•ฉํ•  ๋•Œ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋‘ ๊ฐ€์ง€ ๋ชจ๋‘๋ฅผ ์ œ๊ณตํ•˜๋Š” ์œ ์ผํ•œ ๋ณดํŽธ์ ์ธ ์ „๋žต์€ ์‚ฌ์‹ค ๋ชจ๋“  ์‹ค์ œ ์ฝ”๋“œ๋ฅผ CJS๋กœ ๋งŒ๋“ค๊ณ  ๊ทธ ์ฃผ์œ„์— ESM ๋ž˜ํผ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ ๋ช…๋ช…๋œ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค. ์ƒํƒœ ์ €์žฅ์ด ์•„๋‹ˆ๊ฑฐ๋‚˜ ID์— ์˜์กดํ•˜๋Š” ์ฝ”๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‘˜ ๋‹ค์— ์ž‘์„ฑ ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” ํ•˜์œ„ ์ง‘ํ•ฉ์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

jsx-runtime ๋Š” ์Šคํ…Œ์ดํŠธํ’€(Stateful)์ด ์•„๋‹Œ๊ฐ€์š”? ๋ž˜ํผ ์—†์ด esm/cjs๋ฅผ ๋ชจ๋‘ ๋ฐฐ์†กํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

esm ๋…ธ๋“œ์—์„œ react/jsx-runtime ๊ฐ€์ ธ์˜ค๊ธฐ์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ๋ฌธ์ œ๋ฅผ ๊ธฐ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

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

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

@sokra ์‹ค์ œ๋กœ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด ๋กค์—…์„ ์‚ฌ์šฉํ•˜๋ฉด cjs ๋ชจ๋“ˆ์ด esm ๋ชจ๋“ˆ๋กœ ๋ณ€ํ™˜๋˜๋ฏ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•  ๋•Œ๋งˆ๋‹ค esm ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

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

๊ทธ๋Ÿฌ๋‚˜ webpack 5๋Š” esm/cjs(export ๋งต์—์„œ ์˜ค๋Š” ๊ฒƒ)๋ฅผ ์ค‘๋ณต ์ œ๊ฑฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํŠน๋ณ„ํ•œ "module" ์กฐ๊ฑด์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

@ljharb์˜ ์ œ์•ˆ์„ ๊ณ ๋ คํ•˜๋ฉด ์ด๊ฒƒ์€ esm ํŒŒ์ผ์ด cjs ํŒŒ์ผ์„ ๋‹ค์‹œ ๋‚ด๋ณด๋‚ด๋Š” ๋ช‡ ์ค„์˜ ๋ž˜ํผ ์ฝ”๋“œ์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ œ์•ˆํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ๋กœ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค.

์–‡์€ ESM ๋ž˜ํผ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ์žˆ๋“  ์—†๋“  ์ถ”๊ฐ€ ์œ„ํ—˜์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜ํ”„์˜ ์†์ž„์ˆ˜์— ๋Œ€ํ•ด ํ”ผ์–ด dep๊ฐ€ ํ”ผํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์œ„ํ—˜๋ฟ์ž…๋‹ˆ๋‹ค.

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