Material-ui: [RFC] ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

์— ๋งŒ๋“  2017๋…„ 02์›” 11์ผ  ยท  164์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: mui-org/material-ui

styled-components ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?


์˜ค๋ž˜๋œ ๋น„๊ต

JSS์— ๋น„ํ•ด ๋งŽ์€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ ๋น„๊ต ํ‘œ์™€ ๋‹ค์Œ ๋ฒ„์ „์€ SSR ์Šคํƒ€์ผ์ด ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์„ ํ”ผํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค!

๊ธฐ๋Šฅ | ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ | ๋ฐ˜์‘-jss
------------ | -------------- | --------------
๋นŒ๋“œ ์š”๊ตฌ ์‚ฌํ•ญ ์—†์Œ | โœ…| โœ…
์ž‘๊ณ  ๊ฐ€๋ฒผ์šด | โœ… | โœ…
๊ธ€๋กœ๋ฒŒ CSS ์ง€์› | โœ… | โœ…
CSS ์ „์ฒด ์ง€์› | โœ… | โœ…
์ฝ”๋กœ์ผ€์ด์…˜ | โœ… | โœ…
์ ˆ์—ฐ | โœ… | โœ…
์ธ๋ผ์ธ ์Šคํƒ€์ผ์„ ๊นจ๋œจ๋ฆฌ์ง€ ์•Š์Œ | โœ… | โœ…
์žฌ์ •์˜ํ•˜๊ธฐ ์‰ฌ์šด | โœ… | โœ…
ํ…Œ๋งˆ | โœ… | โœ…
์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง | โœ… | โœ…
๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ ์—†์Œ | โŒ | โœ…
ReactNative ์ง€์› | โœ… | โŒ

๋ฒ”๋ก€: โœ… = ์˜ˆ, โŒ = ์•„๋‹ˆ์˜ค, ๐Ÿ˜• = ์•ฝ๊ฐ„, ์ฐธ๊ณ  ๋˜๋Š” ๊ด„ํ˜ธ ์ฐธ์กฐ

discussion enhancement

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

@oliviertassinari https://github.com/mui-org/material-ui/issues/6115#issuecomment -643398897์— ์–ธ๊ธ‰๋œ ๋Œ€๋กœ ์ง„ํ–‰ ์ค‘์ธ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ์— ๋”ฐ๋ผ ๋จธํ‹ฐ๋ฆฌ์–ผ ํŒ€์ด ์ธ๊ธฐ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋Š๋ฆฝ๋‹ˆ๋‹ค. ํ•ญ์ƒ ๊ทธ๋ž˜์™”๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ CSS์˜ JS ํ‘œ๊ธฐ๋ฒ• ๊ฐ™์€ ๊ฒƒ์„ ๋ฐฐ์›Œ์•ผ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๋Š” ์š”์ ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ์ž‘์—…์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž์˜ ์‚ถ์„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ํŒจํ‚ค์ง€ ์œ ์ง€ ๊ด€๋ฆฌ์ž๋กœ์„œ ์šฐ๋ฆฌ๊ฐ€ ํ•˜๋Š” ์ผ์˜ ์ผ๋ถ€์ด์ง€๋งŒ(๋‚ด ํ”„๋กœ์ ํŠธ์˜ ๊ฒฝ์šฐ) ์ด๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ๊ณผ ์„ฑ๋Šฅ์„ ๋†’์ด๋Š” ๊ฒƒ ์‚ฌ์ด์—๋Š” ์„ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋‚ด๊ฐ€ makeStyles๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ๋„์ž…๋œ ์ดํ›„๋กœ ํ•ญ์ƒ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

๋‚ด ๋งˆ์ง€๋ง‰ ํŒ€ ๊ฑด์ถ•๊ฐ€๋Š” ๋“ฃ์ง€ ์•Š๊ณ  ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€๊ธˆ ์‚ฌ์ดํŠธ๊ฐ€ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ๋ธŒ๋žœ์น˜์—์„œ makeStyles๋กœ ์ „ํ™˜ํ•˜์—ฌ ๋ชจ๋ฐ”์ผ ์žฅ์น˜์˜ TTI์—์„œ 50%(10์ดˆ)๋ฅผ ์ ˆ์•ฝํ–ˆ์ง€๋งŒ, ๊ทธ ๋Œ“๊ธ€์—์„œ ๋งํ–ˆ๋“ฏ์ด JS ํ‘œ๊ธฐ๋ฒ•์€ ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ์•Œ๋ ค์ ธ ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ›์•„๋“ค์—ฌ์ง€์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋‚ด๋ถ€์ ์œผ๋กœ ์žฌ๋ฃŒ๋Š” ์›ํ•˜๋Š” ๋Œ€๋กœ ์„ ํƒํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ฑ๋Šฅ์„ ๋ฐœํœ˜ํ•˜๋„๋ก ํ•˜์‹ญ์‹œ์˜ค.

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

@kybarg ๋ฌธ์ œ๋ฅผ ์—ด์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! CSS-in-JSS๋Š” ์›€์ง์ด๋Š” ๋ถ„์•ผ์ž…๋‹ˆ๋‹ค. ๊ณผ๊ฑฐ์— ์„ ํƒํ•œ ์‚ฌํ•ญ์€ ๋ฌธ์ œ์™€ ์†”๋ฃจ์…˜์ด ๋ณ€๊ฒฝ๋จ์— ๋”ฐ๋ผ ๋” ์ด์ƒ ์œ ํšจํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๊ณผ๊ฑฐ์—๋Š” ์™œ ์—†์—ˆ์Šต๋‹ˆ๊นŒ?

JSS๋ฅผ ์„ ํƒํ•˜๊ธฐ ์ „์— ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋‹ค์–‘ํ•œ ์Šคํƒ€์ผ๋ง ์†”๋ฃจ์…˜์„ ๋น„๊ต ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ styled-components ๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

  • ์ถ”์ƒํ™” ๋น„์šฉ. css-in-js-perf-tests ๋Š” ์ข‹์€ ๋ฆฌ์†Œ์Šค์ด๋ฉฐ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋งค๋ ฅ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

    • JSS์˜ ๊ฒฝ์šฐ 22kb๋ณด๋‹ค ์••์ถ• ํ•ด์ œ๋œ 126kb

    • ์ฒซ ๋ฒˆ์งธ ํŽ˜์ธํŠธ ์‹œ๊ฐ„์ด ๋” ๋Š๋ฆฝ๋‹ˆ๋‹ค. https://github.com/MicheleBertoli/css-in-js ์˜ ๋™๋“ฑํ•œ ๋ฐ๋ชจ์—์„œ ์ฒ˜์Œ ํŽ˜์ธํŠธํ•˜๋Š” ์‹œ๊ฐ„์„ ๋น„๊ตํ•˜๋ฉด JSS๊ฐ€ 40% ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ๋ณด์ž…๋‹ˆ๋‹ค.

  • className ๋ฐ CSS ๋”ฅ ์…€๋ ‰ํ„ฐ ๊ธฐ๋Šฅ์„ ๋…ธ์ถœํ•˜๋ฉด ์„ฑ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด <Grid /> : #6010.
  • ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง ๋™์‹œ์„ฑ ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. JSS๋Š” ๊ฐ ์š”์ฒญ์—์„œ ์Šคํƒ€์ผ์„ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋Š” ๋™์•ˆ ์‹ฑ๊ธ€ํ†ค์— ์˜์กดํ•˜์—ฌ ์Šคํƒ€์ผ์„ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค. ์ŠคํŒ€์€ ์ •๋ง ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค.

์‚ฌ์‹ค @nathanmarks ๊ฐ€ ์ธ๋ผ์ธ ์Šคํƒ€์ผ์—์„œ ๋ฒ—์–ด๋‚˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ styled-components ๋Š” ์กด์žฌํ•˜์ง€๋„ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋น„๊ตํ‘œ

๊ธ€๋กœ๋ฒŒ CSS ์ง€์›

https://github.com/cssinjs/jss-global ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const styles = {
  '<strong i="35">@global</strong> body': {
    color: 'green'
  }
}

์žฌ์ •์˜ํ•˜๊ธฐ ์‰ฌ์›€

์ด๊ฒŒ ์–ด๋–ป๊ฒŒ ์‰ฝ์ง€ ์•Š์ง€? Material-UI ์ธก์—๋Š” ์‚ฌ์ „ ์ •์˜๋œ ์‚ฌ์ถœ ์ˆœ์„œ ํ…Œ์ด๋ธ”์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์˜์—ญ์—์„œ๋Š” ํ›Œ๋ฅญํ•œ ์ตœ์Œ ์žฌ์ •์˜ API๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ตœ์Œ์ œ ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ ์—†์Œ

Material-UI ์ธก์—๋Š” ๋ž˜ํผ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. withStyles ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ ์„ฑ๋Šฅ์ƒ์˜ ์ด์œ ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ปจํ…์ŠคํŠธ ๊ตฌํ˜„์„ ์ถ”์ƒํ™”ํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ๊ณ ์ฐจ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ๋งˆ

์šฐ๋ฆฌ๋Š” ๋‚ด๋ถ€์  ์œผ๋กœ jss-theme-reactor๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. JSS๋Š” ์ด๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ์ €์ˆ˜์ค€ API๋ฅผ ๋…ธ์ถœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ReactNative ์ง€์›

์ข‹์€ ์ง€์ ์ž…๋‹ˆ๋‹ค. react-with-styles API๋Š” ๋งค์šฐ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค!

๋ฏธ๋ž˜

์•ž์œผ๋กœ ๊ฐ€์žฅ ์œ ๋งํ•œ ๊ฒฝ๋กœ๋Š” ์Šคํƒ€์ผ ๊ตฌํ˜„์„ ์ „ํ™˜ ํ•  ์ˆ˜ ์žˆ๋Š” API๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‘ ๊ฐ€์ง€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • Material-UI๋Š” ์–ด๋–ค ์Šคํƒ€์ผ๋ง ์†”๋ฃจ์…˜๊ณผ๋„ ๋œ ๊ฒฐํ•ฉ ๋ฉ๋‹ˆ๋‹ค.
  • styled-components / aphrodite/... ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” JSS ์˜ค๋ฒ„ํ—ค๋“œ ๋ฅผ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

react-toolbox ๊ฐ€ ํ•ด๋‹น ๊ฒฝ๋กœ ๋ฅผ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์œ ์ผํ•œ ๊ด€์‹ฌ์‚ฌ๋Š” ์ถ”๊ฐ€๋˜๋Š” ์˜ค๋ฒ„ ํ—ค๋“œ์ž…๋‹ˆ๋‹ค. ๋‚ด ๋ง์€, ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ฃจํ”„์— @kof ๋ฐ @mxstbr ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@kybarg ์‚ฌ์‹ค, ๋‚˜๋Š” ๋‹น์‹ ์ด ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์„ ์™„์ „ํžˆ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.
๊ท€ํ•˜์˜ ์งˆ๋ฌธ์— ๋”ฐ๋ฅด๋ฉด react-jss ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค .

์šฐ๋ฆฌ๋ผ๊ณ  ํ•  ๋•Œ ์‚ฌ์šฉ์ž ๋˜๋Š” Material-UI๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๊นŒ?

๋‚ด ํฌ์ธํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • styled-components ๋Š” JSS ์ฝ”์–ด๋ณด๋‹ค ํ›จ์”ฌ ๋†’์€ ์ˆ˜์ค€์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณ„์ธต์—์„œ ํ™•์‹คํžˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์œ„์˜ ๋น„๊ตํ‘œ๋Š” JSS core๊ฐ€ ์•„๋‹Œ react-jss์— ๋Œ€ํ•œ ๊ฒƒ์œผ๋กœ Max์˜ ์ฃผ๊ด€์ ์ธ ์˜๊ฒฌ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋ถ€๋ถ„์ ์œผ๋กœ ์‚ฌ์‹ค์ด ์•„๋‹ˆ๋ฉฐ ๋ถ€๋ถ„์ ์œผ๋กœ๋Š” ์šฐ๋ฆฌ๊ฐ€ ํ‘œ์—์„œ ๋ณผ ์ˆ˜ ์—†๋Š” ํŠน์ •ํ•œ ๊ด€์ ์—์„œ ๋ณธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ์šฐ๋ฆฌ๋Š” ๋ณด๋‹ค ํšจ์œจ์ ์ธ ๋™์  ์Šคํƒ€์ผ๋ง์„ ์œ„ํ•ด ๋™์  ๊ทœ์น™ ๋ Œ๋”๋ง ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. jss-theme-reactor๊ฐ€ ์ด๋ฏธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ง€ ์ตœ์ ํ™” ๋ฌธ์ œ์ผ ๋ฟ์ด๋ฉฐ, ์ด๋Š” ์•„๋งˆ๋„ MUI์™€ ๋ณ„๋กœ ๊ด€๋ จ์ด ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • MUI๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ตœ์ข… ์‚ฌ์šฉ์ž๊ฐ€ ์ „ํ˜€ ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ MUI๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฌด์—‡์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ๋˜๋Š” ํ…Œ๋งˆ๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ตœ์†Œํ•œ ๋‹ค์†Œ ๊ทœ์น™์ ์ธ cssinjs ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • MUI๊ฐ€ ํ˜„์žฌ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๊ฐ€์ ธ์™€์„œ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ํ•ญ์ƒ ํ†ตํ•ฉ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋•๊ณ  gitter์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.
  • ์–ด์จŒ๋“  ๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ ์ง€์›์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์›น ํ”Œ๋žซํผ์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์ด ์•„๋‹™๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ด์•ผ ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด JSS๊ฐ€ react-native๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค. ์—ฌ๊ธฐ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํ‘œ๋Š” ์‹ค์ œ๋กœ ๋งค์šฐ ์ฃผ๊ด€์ ์ด๋ฉฐ ๋‚ด ๊ฒฝํ—˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. FWIW, styled-components ๋Š” ํƒ€์‚ฌ ๊ตฌ์„ฑ ์š”์†Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

import { Button } from 'material-ui'

const MyButton = styled(Button)`
  // Only these styles will be overridden
  background: red;
`

๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ผ๋ถ€ DOM ๋…ธ๋“œ์— className ์†Œํ’ˆ์„ ์ฒจ๋ถ€ํ•˜๋Š” ํ•œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

const MaterialUIButton = (props) => {
  /* ... */
  // As long as props.className is attached, the above usage will work
  return <button className={`bla ${props.className}`} />
}

์–ด์จŒ๋“  ๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ ์ง€์›์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์›น ํ”Œ๋žซํผ์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์ด ์•„๋‹™๋‹ˆ๊นŒ?

์•„๋‹ˆ์š”, ๊ทธ๋ ‡๊ฒŒ ์‰ฌ์šด ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค ๐Ÿ˜‰ JSS์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์Šคํƒ€์ผ ๊ฐœ์ฒด๋ฅผ StyleSheet.create() ์— ์ „๋‹ฌํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. CSS ๋ฌธ์ž์—ด์ด ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด styled-components ์ธก์—์„œ ์กฐ๊ธˆ ๋” ๋…ธ๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


๋‚˜๋Š” ์ง€๊ธˆ ์ž ์‹œ @javivelasco ์™€ ์ด์•ผ๊ธฐ๋ฅผ ๋‚˜๋ˆ„์—ˆ๊ณ  ๊ทธ๊ฐ€ react-toolbox ์™€ ํ•จ๊ป˜ ๊ฐ€๋Š” ๊ณณ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ์˜ ๊ตฌํ˜„์€ ๋†€๋ž๊ณ  ๋ชจ๋“  ํƒ€์‚ฌ ๊ตฌ์„ฑ ์š”์†Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ด๋ฅผ ์ฑ„ํƒํ•˜๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฐ€ ์—ฌ๊ธฐ์— ๊ทธ์˜ ์•„์ด๋””์–ด๋ฅผ ์ฐจ์ž„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ทธ๋ฅผ ํ•‘!


์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง ๋™์‹œ์„ฑ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. JSS๋Š” ๊ฐ ์š”์ฒญ์—์„œ ์Šคํƒ€์ผ์„ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•ด ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋Š” ๋™์•ˆ ์‹ฑ๊ธ€ํ†ค์— ์˜์กดํ•˜์—ฌ ์Šคํƒ€์ผ์„ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค. ์ŠคํŒ€์€ ์ •๋ง ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค.

์ „ํ˜€ ๊ด€๋ จ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ ์— ๋Œ€ํ•ด ์ด๋ฅผ ํ—ˆ์šฉํ•  API์— ๋Œ€ํ•œ ์•„์ด๋””์–ด์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์šฐ๋ฆฌ๋Š” ๋ฌด์—‡์„ ํ•  ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๊ท€ํ•˜์˜ ์˜๊ฒฌ์„ ๋งค์šฐ ๊ฐ์‚ฌํ•˜๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, gitter์—์„œ ์ด๊ฒƒ์— ๋Œ€ํ•ด ๋ฌธ์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์˜ ๊ฒฌํ•ด๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์—๋„ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” material-ui _next_๊ฐ€ ์ปค์Šคํ…€ jss ์†”๋ฃจ์…˜์— ๋ง‰๋Œ€ํ•œ ํˆฌ์ž๋ฅผ ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ณด๋‹ค jss๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์˜ ์‹ฌ๊ฐํ•œ ์ด์ ์„ ๋ฐœ๊ฒฌํ•œ ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

jss๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(injectstyles) ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ๊ฐ™์€ ์—ฌ๋Ÿฌ ํŒจํ„ด์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์ง€๋งŒ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ, ์‚ฌ์šฉ์ž ์ง€์ • ์„ค์ • ๋ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— styled-components์˜ ์ง์ ‘์ ์ธ ์ ‘๊ทผ ๋ฐฉ์‹์ด ํ›จ์”ฌ ๊นจ๋—ํ•˜๋‹ค๊ณ  โ€‹โ€‹์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

styled-comp์—์„œ ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์ด๋ฏธ ์Šคํƒ€์ผ์ด ์ง€์ •๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์Šคํƒ€์ผ์„ ์ „๋‹ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์Šคํƒ€์ผ์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ‰๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ์†Œํ’ˆ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
์„ค์ • ์—†์Œ(createJss)
ํ”Œ๋Ÿฌ๊ทธ์ธ ์—†์Œ(์ ‘๋‘์‚ฌ)
JSON DSL ์—†์Œ

๋ˆ„๊ตฐ๊ฐ€ ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ž ๊ฐ€์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@rainice jss์—๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฉฐ HOC๋Š” react-jss์˜ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด๋ฉฐ ์—ฌ๊ธฐ์—์„œ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์™œ ์ด๊ฒƒ์„ ์ž ๊ฐ€์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๊ฑด์ „ํ•œ ํ† ๋ก ์ž…๋‹ˆ๋‹ค IMO

์—ฌ๊ธฐ์— ์žˆ๋Š” ์ตœ์ข… ์‚ฌ์šฉ์ž ๊ธฐ๋ฐ˜ ์ฝ˜ํ…์ธ (lib ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹˜)๋Š” ๋งค์šฐ ํ”ผ์ƒ์ ์ด๋ฉฐ ๊ทธ๋“ค์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๋’ค์— ์žˆ๋Š” ์ฝ”๋“œ ํ•œ ์ค„๋„ ์ฝ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

์‚ฌ๋žŒ๋“ค์ด ๋‹ซํžŒ ์Šค๋ ˆ๋“œ์— ๊ณ„์† ๊ฒŒ์‹œํ•˜์ง€ ์•Š์„ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ์„ฑ์ˆ™ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•„์š”ํ•  ๊ฒฝ์šฐ ์ž ๊ธ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

@mxstbr styled-components ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ className ์†Œํ’ˆ์„ ์ผ๋ถ€ DOM ๋…ธ๋“œ์— ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ํ•œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ mui:next ๊ฐ€ ์ถœ์‹œ๋  ๋•Œ ์‚ฌ์šฉ ๊ฐ€์ด๋“œ์˜ ์–ด๋”˜๊ฐ€์— ๊ฐ•์กฐ ํ‘œ์‹œํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋Œ“๊ธ€์ด ์ €๋ฅผ ๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค.

IE10์šฉ Flex ์Šคํƒ€์ผ์€ jss์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์ง€๋งŒ ๋งค๋ ฅ์ฒ˜๋Ÿผ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ๋Š” ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

@yhaiovyi Material-UI๋Š” IE10์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ณต๊ธ‰์—…์ฒด ์ ‘๋‘์–ด evtl. jss์— ๋Œ€ํ•ด ๊ณง ์ˆ˜์ •๋  ์˜ˆ์ •์ด์ง€๋งŒ mui๊ฐ€ IE10์—์„œ ํ…Œ์ŠคํŠธ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ชจ๋“  ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

์–ด์จŒ๋“  ๋‚˜๋Š” ์ง€๊ธˆ๊นŒ์ง€ IE10์—์„œ CSS flex๋ฅผ ์‚ฌ์šฉํ•œ ๋‹ค์Œ ๋‹ค๋ฅธ ๋ฌธ์ œ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

Material UI ์Šคํƒ€์ผ์„ Styled Components๋กœ ์žฌ์ •์˜ํ•˜๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค(๋” ์‰ฌ์šธ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ชจ๋“  ๊ฒƒ์ด ๊ฝƒ์€ ์•„๋‹™๋‹ˆ๋‹ค). ์—ฌ๊ธฐ ๋‚ด ์š”์  ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋กœ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ API๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://material-ui-next.com/customization/css-in-js/#styled -components-api-15-lines-

styled-jss ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: https://codesandbox.io/s/32mvjyjyxq ).

์ผ๋ฐ˜์ ์œผ๋กœ JSS์˜ ์œ ์ผํ•œ ๋‹จ์  ์€ ์—ฌ๊ธฐ์—๋„ ๋งํ–ˆ๋“ฏ ์ด ์ฝ”๋“œ ํŽธ์ง‘๊ธฐ์—์„œ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์ด ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. styled-components์—์„œ์ฒ˜๋Ÿผ CSS๋ฅผ js๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„ ๊ณผ๋ถ€ํ•˜

ํŽธ์ง‘: ๋ฐฉ๊ธˆ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค.

์งœ์ฆ๋‚˜๋Š” ๊ฒƒ์€ Mui์˜ ์ปจํ…์ŠคํŠธ์™€ withStyles HOC๊ฐ€ ํ•ต์‹ฌ react-jss ๋ฐ styled-jss ThemeProvider https://codesandbox.io/s/32mvjyjyxq ์™€ ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค( Typography ํ•˜์ง€๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŽธ์ง‘: nvm, ์—ฌ์ „ํžˆ ๋งŒ์ง€์ž‘๊ฑฐ๋ฆฌ๊ณ  ์žˆ์Œ)

๋‚˜์ค‘์—(v1 ์ดํ›„) src/styles/withStyles ๋ฐ MuiThemeProvider + JSSProvider ์ด์ค‘ ๋ ˆ์ด์–ด๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ณ  react-jss ๋ฐ styled-jss๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ข€ ๋” ๋‹จ์ˆœํ•œ ๊ฒƒ์„ ๊ฐ–๋Š” ๊ฒƒ์ด ๊ฐ€์น˜๊ฐ€ ์—†๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์„ ์œ„ํ•ด ์™„์ „ํžˆ!

2018๋…„ 3์›” 13์ผ 13์‹œ 55๋ถ„์— "Cyril Auburtin" [email protected] ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

์งœ์ฆ๋‚˜๋Š” ๊ฒƒ์€ Mui์˜ ์ปจํ…์ŠคํŠธ์™€ withStyles HOC๊ฐ€ ์žฌ์ƒ๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
ํ•ต์‹ฌ react-jss ๋ฐ styled-jss ThemeProvider์™€ ์ž˜ ์–ด์šธ๋ฆฝ๋‹ˆ๋‹ค.
https://codesandbox.io/s/32mvjyjyxq

๋‚˜์ค‘์—(v1 ์ดํ›„) ๋‹จ์ˆœํ™”ํ•  ๊ฐ€์น˜๊ฐ€ ์—†๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.
src/styles/withStyles ๋ฐ MuiThemeProvider + JSSProvider ์ด์ค‘ ๋ ˆ์ด์–ด

โ€”
์ด ์Šค๋ ˆ๋“œ์— ๊ฐ€์ž…ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/mui-org/material-ui/issues/6115#issuecomment-372655385 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AADOWAbwLOnRoypx9ANCZnKyalZyD0M9ks5td8HNgaJpZM4L-GwD
.

styled-components์—์„œ์™€ ๊ฐ™์ด CSS๋ฅผ js๋กœ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„์˜ ๊ณผ๋ถ€ํ•˜์ž…๋‹ˆ๋‹ค.

CSS์— ๋Œ€ํ•œ ๊ฐ์ฒด ๊ตฌ๋ฌธ ๋ถ„์„์ด :wink์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋ฌธ์ž์—ด ๊ตฌ๋ฌธ ๋ถ„์„์€ ๊ฑฐ์˜ ๋™์ผํ•œ ์†๋„์ด๋ฉฐ ์†”์งํžˆ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. https://github.com/A-gambit/CSS-IN-JS-Benchmarks/blob/master/RESULT.md

์†”๋ฃจ์…˜ | CSS ์‚ฌ์šฉ | ์ธ๋ผ์ธ ์Šคํƒ€์ผ ์‚ฌ์šฉ | ๋งˆ์šดํŠธ ์‹œ๊ฐ„(ms) | ๋ Œ๋”๋ง ์‹œ๊ฐ„(ms)
:--- | :--- | :--- | :--- | :---
...
์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ | + | - | 182 | 146.84
์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ ๋ถ„๋ฆฌ ์…€ | + | - | 213.53 | 152.39
...
๋ฐ˜์‘-jss | + | - | 198.97 | 297.74

@mxstbr ๋Ÿฐํƒ€์ž„์— js๋กœ ์ž‘์„ฑ๋œ ์ „์ฒด CSS ํŒŒ์„œ๋Š” ํ™•์‹คํžˆ ๊ฐ€๊ฒฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋ฒค์น˜๋งˆํฌ๋Š” ๋น„์šฉ์„ ์ธก์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋Ÿฐํƒ€์ž„์— js๋กœ ์ž‘์„ฑ๋œ ์ „์ฒด CSS ํŒŒ์„œ๋Š” ํ™•์‹คํžˆ ๊ฐ€๊ฒฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก , ํ•˜์ง€๋งŒ ๋ฌธ์ž์—ด์ด ์•„๋‹Œ ๊ฐ์ฒด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์™„์ „ํ•œ CSS ํŒŒ์„œ ์ด์ƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์‹ค์ œ CSS ๋ฌธ์ž์—ด์—์„œ ์ž‘๋™ํ•˜๋Š” CSS ํŒŒ์„œ๋Š” ์˜ค๋žซ๋™์•ˆ ์ตœ์ ํ™”๋˜๊ณ  ํƒ์ƒ‰๋˜์—ˆ์œผ๋ฉฐ ๊ฐ์ฒด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํŒŒ์„œ๋Š” ํ›จ์”ฌ ์ ์Šต๋‹ˆ๋‹ค. :๋ถ‰ํžˆ๋‹ค:

ํŒŒ์„œ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๋กœ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ CSS๋ฅผ ๋ฒค์น˜๋งˆํ‚นํ•˜๋Š” ๊ฒƒ๊ณผ ์šฐ๋ฆฌ ํŒŒ์„œ์ธ ์Šคํƒ€์ผ๋ฆฌ์Šค๊ฐ€ ์žˆ๋Š” ๋ถ€ํŠธ์ŠคํŠธ๋žฉ CSS๋ฅผ ๋ฒค์น˜๋งˆํ‚นํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์„œ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๋กœ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ CSS๋ฅผ ๋ฒค์น˜๋งˆํ‚นํ•˜๋Š” ๊ฒƒ๊ณผ ์šฐ๋ฆฌ ํŒŒ์„œ์ธ ์Šคํƒ€์ผ๋ฆฌ์Šค๊ฐ€ ์žˆ๋Š” ๋ถ€ํŠธ์ŠคํŠธ๋žฉ CSS๋ฅผ ๋ฒค์น˜๋งˆํ‚นํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ์ ์ ˆํ•œ ๋ฒค์น˜๋งˆํฌ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์•ฝ๊ฐ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋‹ˆ ๊ฐœ์ฒด ์ž‘์—…์ด 10-20๋ฐฐ ๋” ๋นจ๋ผ์กŒ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ ํฌํ•จํ•  jss ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋ฉฐ ๊ตฌ๋ฌธ ์„คํƒ• ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ TBH. ์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ISTF๋กœ ์˜ฎ๊ฒจ๊ฐ€๋„ ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์•ฝ๊ฐ„์˜ ํ…Œ์ŠคํŠธ๋ฅผ ํ–ˆ๊ณ , ๊ฐœ์ฒด ์ž‘์—…์€ 10-20๋ฐฐ ๋” ๋น ๋ฆ…๋‹ˆ๋‹ค.

๋ฌผ๋ก ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ 10ms(์Šคํƒ€์ผ๋Ÿฌ์Šค๊ฐ€ ์ „์ฒด ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ์Šคํƒ€์ผ์‹œํŠธ๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„)์™€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ์ „์ฒด CSS๋ฅผ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๋ฐ 1ms๊ฐ€ ์†Œ์š”๋˜๋Š” ๊ฒƒ์€ ์ „์ฒด์ ์ธ ๊ตฌ์กฐ์—์„œ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋ˆ„๊ตฐ๊ฐ€์˜ ์•ฑ์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๊นจ๋œจ๋ฆฌ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์–ด์จŒ๋“  ํ•„์š” ์ด์ƒ์œผ๋กœ ๋งŽ์€ ์•Œ๋ฆผ์œผ๋กœ์ด ๋ฌธ์ œ์—์„œ ์งœ์ฆ๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์ค‘์ง€ํ•ฉ์‹œ๋‹ค.

ใ…‹ ์ด ๋ฒค์น˜๋งˆํฌ๊ฐ€ ๋” ์ •ํ™•ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. http://necolas.github.io/react-native-web/benchmarks/ ์ฒซ ๋ฒˆ์งธ ๊ตฌ๋ฌธ ๋ถ„์„ ํ›„ ์บ์‹œ์— ์˜์กดํ•˜์ง€ ์•Š์ง€๋งŒ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@mxstbr ์ด ๋ฌธ์ œ๋Š” ํ˜„์žฌ ์ž ๊ฒจ ์žˆ์ง€๋งŒ ์•ฝ๊ฐ„์˜ ๊ฑด์ „ํ•œ ๊ฒฝ์Ÿ์€ ๋ชจ๋‘์—๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค. ์–ธ์ œ๋“ ์ง€ ๋‹ค์‹œ ์˜ค์‹ญ์‹œ์˜ค. ๋ฌธ์ œ๊ฐ€ ํ† ๋ก ์„ ์œ„ํ•œ ์ ์ ˆํ•œ ์žฅ์†Œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ gitter ์ฑ„ํŒ…์—์„œ ์ €ํฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” 1๋…„์ด ๋„˜์—ˆ์Šต๋‹ˆ๋‹ค. ์–˜๋“ค์•„, ๋Œ“๊ธ€ ๊ทธ๋งŒ ๋‹ฌ์ž. ํ† ๋ก ์„ ์ƒˆ ํ† ๋ก ์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ† ๋ก ์ด ์‹œ์ž‘๋œ ํ›„ ๋งŽ์€ ๊ฒƒ์ด ๋ณ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ž ๊ธˆ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ์‹œ๋‹ค. ๋” ๋‚˜์€ ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๊ธฐ ์œ„ํ•ด ๊ฐ€๋Šฅํ•œ ํ•œ ๋งŽ์€ ํ”ผ๋“œ๋ฐฑ์„ ๊ณ„์† ์ˆ˜์ง‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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

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

Capture dโ€™eฬcran 2019-03-10 aฬ€ 10 38 56

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

  1. ๋ฒˆ๋“ค ํฌ๊ธฐ . ์šฐ๋ฆฌ๋Š” ์‚ฌ๋žŒ๋“ค์ด 20KB์˜ ์••์ถ• ๋น„์šฉ์„ ์ง€๋ถˆํ•˜์ง€ ์•Š๊ณ ๋„ ๋‹จ์ผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ˆœ์œ„๋ณ„:

    1. ๊ฐ์ •์€ ์ด ๋ฐฉํ–ฅ์—์„œ ๊ฐ€์žฅ ์ข‹์€ ํ›„๋ณด์ž…๋‹ˆ๋‹ค: 10kB gzipped . ๊ทธ๋Ÿฌ๋‚˜ ์†Œ์ˆ˜์˜ ์‚ฌ๋žŒ๋“ค์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์šด๋กœ๋“œ ํ†ต๊ณ„๋ฅผ ๋ณด๋ฉด 80%๊ฐ€ ์Šคํ† ๋ฆฌ๋ถ์—์„œ ๋‚˜์˜จ๋‹ค๊ณ  ?

    2. styled-components ๋ฌด๊ฒŒ ์•ฝ 16KB gzipped . ๊ทธ์˜ ์žฅ์ ์€ ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์˜ ์ˆ˜์—์„œ ๋น„๋กฏ๋ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ React ์‚ฌ์šฉ์ž์˜ 20%?

    3. ๋ฐ˜์‘ ๋ž˜ํผ ๊ฐ€์ค‘์น˜๊ฐ€ ์•ฝ 15KB์ธ JSS๊ฐ€ gzip์œผ๋กœ ์••์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์šด๋กœ๋“œ ํ†ต๊ณ„๋ฅผ ๋ณด๋ฉด Material-UI์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  2. ์„ฑ๋Šฅ . ์šฐ๋ฆฌ๋Š” ์‚ฌ๋žŒ๋“ค์ด ์šฐ๋ฆฌ์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ํ•œ ๋นจ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒค์น˜๋งˆํฌ๋Š” ๋‹ค์Œ ์ˆœ์œ„๋ฅผ ์‚ฐ์ถœํ•ฉ๋‹ˆ๋‹ค.

    1. ๊ฐ์ •

    2. jss

    3. ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ

  3. ์‚ฌ์šฉ์ž ์ •์˜ API . ๋ณ€ํ˜• ์‚ฌ์šฉ์ž ์ •์˜๋Š” ์‰ฌ์›Œ์•ผ ํ•˜๊ณ  ์ค‘์ฒฉ ์š”์†Œ ์‚ฌ์šฉ์ž ์ •์˜๋Š” ์‰ฌ์›Œ์•ผ ํ•˜๋ฉฐ ์ƒˆ ๋ณ€ํ˜• ์ถ”๊ฐ€๋Š” ์‰ฌ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ ์šฐ๋ฆฌ๋Š” classes API, theme.overrides API ๋ฐ ์ „์—ญ ๊ฒฐ์ •์  ํด๋ž˜์Šค ์ด๋ฆ„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  4. ์ƒํ˜ธ ์šด์šฉ์„ฑ . !important ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํ•ด๊ฒฐ์ฑ…์ด ์•„๋‹™๋‹ˆ๋‹ค.
  5. RTL ์ง€์›

๋‚˜๋Š” ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ, ๊ฐ์ • ๋ฐ JSS๋งŒ ์–ธ๊ธ‰ํ–ˆ์ง€๋งŒ linaria, SASS ๋“ฑ ๋‹ค๋ฅธ ๋Œ€์•ˆ์ž…๋‹ˆ๋‹ค.

Material-UI์—์„œ ์‚ฌ์šฉํ•˜๋Š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ž‘์—…ํ•  ์‹œ๊ฐ„์ด ์žˆ์„ ๋•Œ ๊ฒฐ์ •์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@o-alexandrov JSS๋Š” styled-components์™€ ๋™์ผํ•œ ์ „๋žต์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋‹น์‹ ์˜ ์š”์ ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋ช…ํ™•ํžˆ ํ•ด์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์ฐจ์ด์ ์ด ๋ญ์•ผ? ์–ด๋–ป๊ฒŒ ๋” ๋‚ซ๊ฑฐ๋‚˜ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@oliviertassinari
์ด์ „ ๋ฉ”์‹œ์ง€์—์„œ styled-components ๋˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์™„๋ฒฝํ•œ ๊ท ํ˜•์„ ๊ฐ–์ถ˜ ๋‹ค๋ฅธ CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์„ ํ‰๊ฐ€ํ•˜๋ ค๋Š” ์•„์ด๋””์–ด๋ฅผ ํ™˜์˜ํ•œ๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๊ณ ๋Š” styled-components ์— ๋Œ€ํ•ด ์•„๋ฌด ๋ง๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ๊ฐœ๋ฐœ ๊ฒฝํ—˜(์ต์ˆ™ํ•จ ๋ฐ ์œ ์—ฐ์„ฑ, ์ถ”๊ฐ€ ๊ธฐ์—ฌ, ๊ฐœ๋ฐœ์ž์˜ ์‹ค์ œ ์‚ฌ์šฉ ๋“ฑ)
  • ์„ฑ๋Šฅ

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

๊ฐœ์ธ์ ์œผ๋กœ ๋‹ค์Œ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

  • ํ›จ์”ฌ ๋” ๊ด‘๋ฒ”์œ„ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ์ฑ„ํƒ์„ ์œ„ํ•ด jss ๋ณด๋‹ค styled-components .
    ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ฑ„ํƒ์ด ๋จธํ‹ฐ๋ฆฌ์–ผ UI๊ฐ€ ๊ณ ๋ คํ•ด์•ผ ํ•  ํ•ต์‹ฌ ์ธก๋ฉด์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@o-alexandrov ์ข‹์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์ฒซ ๋ฒˆ์งธ ๋Œ“๊ธ€์„ ์ฃผ์ œ์—์„œ ๋ฒ—์–ด๋‚œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. v5์—์„œ๋Š” ํ•ต์‹ฌ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์Šคํƒ€์ผ๋ง ์†”๋ฃจ์…˜์—์„œ ๋ถ„๋ฆฌํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋„ค์ดํ‚ค๋“œ, JSS, ๊ฐ์ •, linaria ๋ฐ styled-components(๊ธฐ๋ณธ๊ฐ’์œผ๋กœ) ๋ฒ„์ „์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋น„์ „์ž…๋‹ˆ๋‹ค. ์ด์ œ ๊ตฌํ˜„์ด ์–ด๋ ค์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

๋ฒˆ๋“ค ํฌ๊ธฐ

styled-components ์€ @5.0.0-beta.8 ์—์„œ 12.3kB ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ž…์ฆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ API

ํŒจํ‚ค์ง€ ๋˜๋Š” ์™ธ๋ถ€ ํŒจํ‚ค์ง€์— https://github.com/styled-components/styled-components/pull/2625 ๋ฅผ ๋„์ž…ํ•˜๋ฉด ์–ธ์  ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ๋Š” ์Šคํƒ€์ผ์ด ์—†๋Š” ๊ตฌ์„ฑ ์š”์†Œ API๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— Mui์— ๋Œ€ํ•œ API ํŒจ๋ฆฌํ‹ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. , ํŠนํžˆ ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ์—์„œ ํ•˜์ง€๋งŒ Mui ์ž์ฒด์—์„œ API๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์ž์ฃผ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ๋ฐ–์—,

๋‚ด ๊ฐœ์ธ์ ์ธ ๊ฒฝํ—˜ styled-components ์ด ์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ์‹ถ์€์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ƒํ˜ธ ์šด์šฉ์„ฑ.

์ด ๋งฅ๋ฝ์—์„œ ๋‹น์‹ ์—๊ฒŒ ์ด๊ฒƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‚ด๊ฐ€ ์•„๋Š” ํ•œ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ styled-components ์˜ ํ•ญ๋ชฉ์„ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

RTL ์ง€์›

์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฝ”๋”ฉํ•˜๋Š” ๋ฐฉ์‹์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? styled-components ๋˜๋Š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋‚ด ์ƒ๊ฐ

์†๋„

์ด์ „์—๋Š” ๋‹ค๋ฅธ ์†”๋ฃจ์…˜์— ๋น„ํ•ด ๋Š๋ ธ์ง€๋งŒ ๊ธฐ์—ฌ์ž๋“ค์˜ ์ง€์›๊ณผ ๋†€๋ผ์šด ๋…ธ๋ ฅ์œผ๋กœ JSS๋ณด๋‹ค ํ›จ์”ฌ ๋นจ๋ผ์กŒ์Šต๋‹ˆ๋‹ค.

ํฌ๊ธฐ

v5 12.3kB from 16.2kB $์—์„œ ๋งํ–ˆ๋“ฏ์ด v5์€(๋Š”) ์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ๊ทธ๋“ค์˜ ๋…ธ๋ ฅ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ •ํ†ต

API๊ฐ€ ๊ฐ€์žฅ ๋Œ€์ค‘์ ์ด์–ด์„œ ์‚ฌ๋žŒ๋“ค์€ ์ต์ˆ™ํ•˜์ง€๋งŒ, ์‹ค์ œ๋กœ styled(...) ... API๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ ์‹ค์ œ ํŒจํ‚ค์ง€๊ฐ€ ์•„๋‹Œ API๋ฅผ ์ฐธ์กฐํ•˜์—ฌ styled-components ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

๋„ค์ดํ‹ฐ๋ธŒ ๋ฐ˜์‘

Mui๋Š” ์›น์ด์ง€๋งŒ ์‚ฌ๋žŒ๋“ค์€ ๊ณ„์†ํ•ด์„œ styled-components ๋ฅผ ์ฑ„ํƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ํŒ€

Strong Core ํŒ€์€ ์˜ค๋Š˜ 81๊ฐœ์˜ ์ด์Šˆ์™€ 14๊ฐœ์˜ PR์ด ์—ด๋ ธ๊ณ , ์ด๊ฒƒ์€ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์˜ ์ˆ˜์— ๋น„ํ•ด ์ข‹์€ ์ˆซ์ž์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ @mxstbr ๊ณผ ๊ฐ™์€ ์‚ฌ๋žŒ๋“ค์€ ์‹ค์ œ๋กœ spectrum ์˜ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‹ค์ œ ๊ฒฝํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋†€๋ž์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์‹ค์ œ๋กœ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Š๋‚Œ์„ ์•Œ๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฐ›์•˜๋‹ค

๊ธ€์Ž„, ๋” ์ข‹์„ ์ˆ˜ ์—†๋‹ค https://www.styled-components.com/docs/tooling

UI ์ž‘์„ฑ์ž์šฉ

์˜ค๋Š˜๋‚  ๋””์ž์ธ ์‹œ์Šคํ…œ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ styled-components ์˜ ์ฑ„ํƒ์ด ๋งŽ์ด ์ฆ๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Atlassian, GitHub, Orbit ๋“ฑ.

์ด๊ฒƒ์€ ๋‹น์‹ ์ด ํ˜ผ์ž๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— Mui์— ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋งˆ๋„ ์‚ฌ๋žŒ๋“ค์€ ๋‹น์‹ ์ด ์ง๋ฉดํ•  ์ˆ˜ ์žˆ๋Š” ์ž ์žฌ์ ์ธ ์ƒํ™ฉ์„ ์ด๋ฏธ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ทธ๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ƒˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

TL;DR

์ €๋Š” styled-components ๋ฅผ ์ง€์ง€ํ•ฉ๋‹ˆ๋‹ค.

CSS์— ๋Œ€ํ•œ ๊ฐœ์ฒด ๊ตฌ๋ฌธ์ด ๋” ์‰ฌ์›Œ์กŒ๊ธฐ ๋•Œ๋ฌธ์— JSS๋ฅผ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” ๊ฒŒ์œผ๋ฅด๊ณ  ํ•ด๋‹น ์Šคํƒ€์ผ์„ style={{styles.dialogTitle}} ์ธ๋ผ์ธ ์Šคํƒ€์ผ๋กœ ์ „๋‹ฌํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋ฆฌํŒฉํ† ๋งํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

styled-components https://material-ui.com/styles/basics/#styled -components-api์™€ ๊ฐ™์€ ์š”์†Œ ๋ž˜ํผ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” styled-components๋ฅผ ์ •๋ง ์ข‹์•„ํ•˜์ง€๋งŒ ์ตœ๊ทผ์— ๊ทธ๊ฒƒ์ด tree-shaking ์ž‘์—…์„ ์ผ๊ด€๋˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ์†Œ๊ฐœํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” material-ui ํŒ€์ด ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด tree-shaking์ด ์™„์ „ํžˆ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ ์ž‘์—…์„ ํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ ๋ถ„๋ช…ํžˆ ์ด์— ๋Œ€ํ•œ ํšŒ๊ท€๋Š” ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹คํ–‰ํžˆ๋„ ๋Œ€๋ถ€๋ถ„์˜ ํŠธ๋ฆฌ ํ”๋“ค๊ธฐ ๋ฌธ์ œ๋Š” babel-plugin-styled-components ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  pure: true ๋ฅผ ์„ค์ •ํ•˜์—ฌ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค(https://www.styled-components.com/docs/tooling#dead-code-elimination ์ฐธ์กฐ). ). ๊ทธ๋Ÿฌ๋‚˜ ์•„์ง ๋ช‡ ๊ฐ€์ง€ ๋‚จ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:
https://github.com/styled-components/babel-plugin-styled-components/issues/245

๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์Šคํƒ€์ผ ๋‚ด์—์„œ ์™ธ๋ถ€ ๋„์šฐ๋ฏธ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋ฆฌ ํ”๋“ค๋ฆผ์ด ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค(ํŠน์ • ๊ธฐ๋Šฅ์„ ๋ฌด์‹œํ•˜๋„๋ก terser/uglify๋ฅผ ๊ตฌ์„ฑํ•˜์ง€ ์•Š๋Š” ํ•œ). ์˜ˆ:

const Button = styled.button`
  font-size: ${externalHelperFunction()};
`

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

@mbrowne ํŠธ๋ฆฌ ํ”๋“ค๊ธฐ ๋ฐ ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ์—๋Š” ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์˜ˆ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฏ€๋กœ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณต์ œํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.

// components.js
import React from "react";
import styled from "styled-components/macro";

const Wrapper = styled.div`
  color: blue;
`;

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

MyComponent.displayName = "FancyName";

export function OtherComponent() {
  return "only";
}

// App.js
import React from 'react';
import { OtherComponent } from "./components";

/* code */

๊ธฐ๋ณธ create-react-app . MyComponent ๋Š” ํ”„๋กœ๋•์…˜ ๋ฒˆ๋“ค์— ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

rollup ์—๋งŒ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์˜ˆ๋ฅผ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@eps1lon ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ์— ์ •์  ์†์„ฑ์„ ์„ค์ •ํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

const Wrapper = styled.div`
  color: blue;
`;

Wrapper.displayName = "FancyName";

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

export function OtherComponent() {
  return "only";
}

@mxstbr ์˜ˆ, ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ styled-components๊ฐ€ ๋ฒˆ๋“ค๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. MyComponent ์— displayName ์„ ์„ค์ •ํ•˜๋Š” ๋™์•ˆ ๋ฒˆ๋“ค์— MyComponent ํฌํ•จํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์—ฌ์ „ํžˆ styled-components ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ MyComponent ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰๋œ ๋ชจ๋“  ์ž‘์—…์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ์›๋ž˜ ์ œ๋Œ€๋กœ ํŠธ๋ฆฌ ์…ฐ์ดํฌ๋ผ๊ณ  ์ƒ๊ฐํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค(๋ฐฉ๊ธˆ FancyName ๊ฒ€์ƒ‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์—ฌ์ „ํžˆ styled-components ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. styled ํ˜ธ์ถœ์„ ๋ถ€์ž‘์šฉ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋”๋ผ๋„

import React from "react";
import styled from "styled-components";

export function Wrapper() {
  // nonsense
  return styled.div``;
}

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

export function OtherComponent() {
  return "only";
}

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

// Wrapper.js
import React from "react";
import styled from "styled-components";

export default function Wrapper() {
  // side-effect free module even if styled has side-effects
  const Component = styled.div``;
  return <Component />;
}

// components.js
// commenting this out removes styled-components from the bundle
export { default as Wrapper } from "./Wrapper";

export function OtherComponent() {
  return "only";
}

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { OtherComponent } from "./components";
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<OtherComponent />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

styled-components (https://github.com/eps1lon/styled-components-shake)๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

react-scripts, webpack ๋˜๋Š” styled-components์˜ ๋ฒ„๊ทธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๋””๋ฒ„๊น…ํ•˜๋Š” ๊ฒƒ์€ ์žฌํ˜„ ์—†์ด๋Š” ๋งค์šฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์ดํ•ด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์กฐ์‚ฌํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ด ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ๊ฒฝ์šฐ styled-components ๊ฐ€ ๋ฒˆ๋“ค์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๊ฐ€ ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ). ์˜คํžˆ๋ ค ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜๋Š”์ง€ ์—ฌ๋ถ€๊ฐ€ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™์œผ๋‹ˆ ๊ดœ์ฐฎ๊ฒ ์ฃ ?

@mxstbr ์ค‘์š”ํ•œ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํƒ€์ผ์ด ์ง€์ •๋˜์ง€ ์•Š์€ ์ผ๋ฐ˜ ๊ตฌ์„ฑ ์š”์†Œ(Modal, Popper, TextareaAutosize, useMediaQueries ๋“ฑ)๊ฐ€ ๋ช‡ ๊ฐ€์ง€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

import {ย Modal } from '@material-ui/core';

SASS์™€ ํ•จ๊ป˜. ์šฐ๋ฆฌ๋Š” +20kB gzip์ด ์•„๋‹ˆ๋ผ +5kB gzip์œผ๋กœ ์ฆ๊ฐ€ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค(์˜ค๋Š˜ ํ˜„์žฌ).

๊ทธ๋Ÿฌ๋‚˜ @material-ui/unstyled ๋ฅผ ์•ž์œผ๋กœ ํ‘ธ์‹œํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด ์‹ค์ œ๋กœ ์‚ฌ๋žŒ๋“ค์ด ์ด ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฐจ์ด๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

์—ฌ๊ธฐ์—์„œ ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ๋ฐ๋ชจ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
https://github.com/mbrowne/CRA-error-template/tree/styled-components-tree-shaking
git clone --single-branch --branch styled-components-tree-shaking [email protected]:mbrowne/CRA-error-template.git

Component1๋งŒ ํŠธ๋ฆฌ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ”๋“ค๋ฆฌ๋Š” ๋ฐฉ์‹์— ์œ ์˜ํ•˜์‹ญ์‹œ์˜ค.

์ข‹์€ ์†Œ์‹์€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ชจ๋‘ ํ•ด๊ฒฐ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ณ  @mxstbr ์ด ์—ฌ๊ธฐ์— ๋งค์šฐ ์ฐธ์—ฌํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ €๋Š” ๊ณง ์ตœ์†Œํ•œ ์ •์  ์†Œํ’ˆ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  PR ์ž‘์—…์„ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค(์ €๋Š” ์ด๋ฏธ ์ž‘์„ฑํ•œ ๋ณ„๋„์˜ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘๋™ํ•˜๋Š” POC๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค).

ํŠธ๋ฆฌ ํ”๋“ค๊ธฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด babel-plugin-styled-components์— ๋Œ€ํ•œ PR์„ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ๋•๊ณ  ์‹ถ๋‹ค๋ฉด @mxstbr ์ด ๊ทธ๊ฒƒ์„ ํ™˜์˜ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ์ƒํ•ฉ๋‹ˆ๋‹ค(๋ฌผ๋ก  ์ €๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค).
https://github.com/styled-components/babel-plugin-styled-components/pull/248

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„, ์ด ํ‹ฐ์ผ“์€ ํ˜„์žฌ ์–ด๋””์— ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์ด ์‹ค์ œ๋กœ ํ”„๋กœ์ ํŠธ๊ฐ€ v5์—์„œ ํ–ฅํ•˜๊ณ  ์žˆ๋Š” ๋ฐฉํ–ฅ์ด๋ผ๋ฉด MUI์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์ฐธ์—ฌํ•˜๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ํ•œ ๋ฒˆ์— ์ด๊ฒƒ์„ ํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด (๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์„ ์›ํ•˜๋Š”์ง€ ์˜์‹ฌ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค). styled-components๊ฐ€ jss์˜ ํ…Œ๋งˆ๋ฅผ ์ฝ๊ฑฐ๋‚˜ jss๊ฐ€ styled-components์˜ ํ…Œ๋งˆ๋ฅผ ์ฝ๋„๋ก ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ชฉํ‘œ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ณ„๋กœ ์Šคํƒ€์ผ์„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์•„๋งˆ๋„ ๋‹ค๋ฅธ ๋ถ„๊ธฐ์—์„œ ๋ฐœ์ƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์Šคํ„ฐ์˜ ๋ชจ๋“  ๊ฒƒ์„ ํ•œ ๋ฒˆ์— ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์ง€๋Š” ์•Š์ง€๋งŒ (v5์—์„œ) ํ•œ ๋ฒˆ์˜ ๋ณ€๊ฒฝ์œผ๋กœ ๋ฆด๋ฆฌ์Šคํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ด๊ฒƒ์€ ๋”์šฑ ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ์ง‘๋‹ˆ๋‹ค.

๋Œ“๊ธ€ ์‚ญ์ œ๋ฅผ ์š”์ฒญํ–ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„, ์ €๋„ ๊ธฐ์—ฌํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค... ๋ณ„๋„์˜ ๋ธŒ๋žœ์น˜๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ํ˜„๋ช…ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค... ํ•ด๋ณด์ž...!

@caprica-Six ์—๋„ˆ์ง€์— ๊ฐ์‚ฌํ•˜์ง€๋งŒ ์ƒˆ ๋ถ„๊ธฐ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ ๋ฒ„์ „์„ ์ ์ง„์ ์œผ๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(+ jss ๋ฐ ๊ฐ์ •)(v4 ๋™์•ˆ ๋ถˆ์•ˆ์ •). ๋™์‹œ์— ์Šคํƒ€์ผ์ด ์ง€์ •๋˜์ง€ ์•Š์€ ์Šคํ† ๋ฆฌ๋ฅผ ์•ž์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ œ์ถœํ•ด์•ผ ํ•˜๋Š” POC๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Styled-components (v5 beta) + dynamic props๋Š” ์šฐ๋ฆฌ๊ฐ€ JSS์™€ static ์Šคํƒ€์ผ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ๋ณด๋‹ค ์•ฝ๊ฐ„ ๋Š๋ฆฌ์ง€๋งŒ ์ด๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹ํ—ˆ์šฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@oliviertassinari ์šฐ๋ฆฌ๊ฐ€ ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ์–ด๋–ค ์ผ์— ๋›ฐ์–ด๋“ค๊ธฐ ์ „์— ๊ด€๋ฆฌ์ž๊ฐ€ ๋‚˜๋ฅผ ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ ์•ˆ๋‚ดํ•ด์ฃผ๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋ณด๋‹ค ๊ฐ์ •์„ ์„ ํ˜ธํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ทธ ์ด์œ ๋Š” "[๊ฐ์ •]์„ ์†Œ์ˆ˜์˜ ์‚ฌ๋žŒ๋“ค์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๋‹ค์šด๋กœ๋“œ ํ†ต๊ณ„๋ฅผ ๋ณด๋ฉด 80%๊ฐ€ ๋™ํ™”์ฑ…์—์„œ ๋‚˜์˜จ๋‹ค๊ณ ?"๋ผ๊ณ  ํ•˜๋Š”๋ฐ ์ด๊ฒƒ์€ ํ‹€๋ ธ๋‹ค. ๊ทธ๊ฒƒ์€ styled-components( ๋น„๊ต )๋ณด๋‹ค ๋” ๋งŽ์ด ์‚ฌ์šฉ๋˜๋ฉฐ ๋‹ค์šด๋กœ๋“œ์˜ 80%๊ฐ€ ์Šคํ† ๋ฆฌ๋ถ์—์„œ ์˜ค๋Š” ์ด์œ ๋ฅผ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ™•์‹คํžˆ ๋™ํ™”์ฑ…๋ณด๋‹ค ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์„ฑ์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

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

๋” ๊ฐ€๋ณ๊ณ  ๋น ๋ฅด๋ฉฐ ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์†์„ฑ ์ „๋‹ฌ, TypeScript ๊ธฐ๋ณธ ์ œ๊ณต(์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ์— ๋น„ํ•ด ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›๋จ), ์ฆ‰์‹œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ Next.js SSR(_app. js ๋ฐ _document.js ํŒŒ์ผ, ์ฒ˜์Œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ 1์‹œ๊ฐ„ ์†Œ์š”)

๊ฒŒ๋‹ค๊ฐ€ styled-component๋ณด๋‹ค ๋” ๋งŽ์ด ์‚ฌ์šฉ๋˜๋ฉฐ ๋ถ„๋ช…ํžˆ ์ถ”์ง„๋ ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@lcswillems ๊ฐ์„ฑ์„ ์„ ํ˜ธํ•˜๋Š” ๋ถ„๋“ค์„ ์œ„ํ•ด ๊ฐ์„ฑ๋„ ์ง€์›ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๊ธฐ๋ณธ๊ฐ’์ด์–ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • "๊ฐ€๋ฒผ์šด": ์ •ํ™•ํ•˜์ง€ ์•Š์Œ: https://bundlephobia.com/[email protected](12.2kB ) vs https://bundlephobia.com/result?p=@emotion/ styled + https://bundlephobia.com/result?p=@emotion/core + https://bundlephobia.com/result?p=emotion-theming (๊ณต์œ  ์˜์กด์„ฑ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์€ 13.1kB)
  • "Next.js SSR out-of-the-box": ์ค‘์š”ํ•œ ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ธ๋ผ์ธ

๋‹ต๋ณ€ํ•ด ์ฃผ์‹œ๊ณ  ์ˆ˜์ •ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

  • "๋ผ์ดํ„ฐ": ๋‹น์‹ ์ด ์˜ณ์Šต๋‹ˆ๋‹ค
  • "Next.js SSR ์ฆ‰์‹œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ": ์ด์ œ SSR์„ ์ฆ‰์‹œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์ด์œ ์™€ ์ˆ˜ํ–‰ ๋ฐฉ์‹์ด ์ข‹์ง€ ์•Š์€ ์ด์œ ๋ฅผ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.
  • "styled-components๋ณด๋‹ค ๋” ๋งŽ์ด ์‚ฌ์šฉ๋จ": ์ด๊ฒƒ์ด ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด ์ถœ์ฒ˜๋„ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • "๋” ๋น ๋ฆ„": ์˜ค๋ž˜๋œ ๋ฒค์น˜๋งˆํฌ๋งŒ ๋ณด์•˜์œผ๋ฏ€๋กœ ์•„๋‹ˆ์˜ค, ์—†์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ง๋ฉดํ•œ ์ฃผ์š” ๋ฌธ์ œ๋Š” ์†Œํ’ˆ ์ „๋‹ฌ/ํ•„ํ„ฐ๋ง์ž…๋‹ˆ๋‹ค. https://github.com/styled-components/styled-components/issues/439 . ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๋งค์šฐ ์ž์ฃผ ๋ฐœ์ƒํ•˜๋ฉฐ ๋งค๋ฒˆ ์ˆ˜๋™์œผ๋กœ ํ•„ํ„ฐ๋ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋‹น์‹ ์˜ ๋ง์„ ๋ณด๋ฉด ๊ฐ์ •์€ ๊ทธ๋‹ค์ง€ ์ข‹์€ ๋Œ€์•ˆ์ด ์•„๋‹Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

"๊ฐ€๋ฒผ์šด": ์ •ํ™•ํ•˜์ง€ ์•Š์Œ: https://bundlephobia.com/[email protected](12.2kB ) vs https://bundlephobia.com/result?p=@emotion/ styled + https://bundlephobia.com/result?p=@emotion/core + https://bundlephobia.com/result?p=emotion-theming (13.1 kB ์—†์ด

๊ฐ์ •์˜ ๊ฒฝ์šฐ css ์†Œํ’ˆ + @jsx pragma ๋Œ€์‹  @emotion/styled ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค. ๋˜ํ•œ emotion-theming ํŒจํ‚ค์ง€๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ThemeContext ๋Š” ์ด๋ฏธ @emotion/core ์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ 12.2KB ๋Œ€ 6.5KB์ž…๋‹ˆ๋‹ค.

์ธ๋ผ์ธ

๊ถ๊ธˆํ•œ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. MUI๊ฐ€ ์•„๋‹Œ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ @material-ui/styles ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ด๋Ÿฌํ•œ ์—…๋ฐ์ดํŠธ๋Š” ๋ฌด์—‡์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ? ์šฐ๋ฆฌ ํšŒ์‚ฌ์—์„œ๋Š” ์ด๊ฒƒ์„ styled-components ๋ณด๋‹ค ์˜๋„์ ์œผ๋กœ ์„ ํƒํ•œ ๋Œ€๊ทœ๋ชจ ๋‚ด๋ถ€ ๊ตฌ์„ฑ ์š”์†Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋งค์šฐ ๋งŒ์กฑํ•ฉ๋‹ˆ๋‹ค.

@material-ui/styles ํŒจํ‚ค์ง€์— ๋Œ€ํ•ด ์–ด๋–ค ์ข…๋ฅ˜์˜ ์‚ฌ์šฉ ์ค‘๋‹จ์ด ๊ณ„ํš๋˜์–ด ์žˆ๋Š”์ง€ ๋ฏธ๋ฆฌ ํ™•์ธํ•˜์—ฌ ๊ทธ์— ๋”ฐ๋ผ ๊ณ„ํšํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์–ด์จŒ๋“ , ๋‹น์‹ ์ด ๊ณ„์† ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  ํ›Œ๋ฅญํ•œ ์ž๋ฃŒ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

@nickjohnson-dev react-jss๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ๊ฐ„๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์กฐ์ง์— ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@oliviertassinari ๊ทธ๋Ÿด ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ ์ž์ฒด์˜ ๊ณต๊ฐœ API๋ฅผ ๊ฑฐ์˜ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ( classes prop ๊ธฐ๋ฐ˜ ๋กœ์ปฌ ์žฌ์ •์˜, ํ…Œ๋งˆ์—์„œ ๊ฐ€๋Šฅํ•œ ์ „์—ญ ์žฌ์ •์˜) ๊ตฌํ˜„ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

MUI๊ฐ€ ๋” ๋ถ„๋ฆฌ๋œ ํ›„ @material-ui/styles ์—์„œ ๋‹ค๋ฅธ ์Šคํƒ€์ผ ์˜ต์…˜์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๊ธฐ ์œ„ํ•œ ๊ณต์‹ ๋ฌธ์„œ๊ฐ€ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๊นŒ? ์–ธ๋œป ๋ณด๊ธฐ์— @material-ui/styles ์—์„œ ํ™œ์šฉํ•˜๊ณ  ์žˆ๋Š” react-jss ์— ๋ถ€์กฑํ•œ ๊ธฐ๋Šฅ์ด ๋ณด์ด์ง€ ์•Š์ง€๋งŒ MUI ํŒจํ‚ค์ง€๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ํŠน๋ณ„ํ•œ ๊ฒƒ์ด ๋ˆ„๋ฝ๋˜์—ˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌด๋Œ€ ๋’ค์—์„œ.

@nickjohnson-dev ์ตœ์„ ์„ ๋‹คํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ•˜๋ฉด ๋‹ค์Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ComponentA ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. $#$2 ComponentB ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ComponentA ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

const ComponentA = ({className}) => (
  <div className={className}>
    <div className='inner' />
  </div>
);

const ComponentB = ({ className, classNameInner }) => (
  <div className={className}>
    <div className='inner'>
      <ComponentA className={classNameInner} />
    </div>
  </div>
)

const StyledComponentB = styled(ComponentB)`
     ???
`;

ComponentA ๋ฐ ComponentB ์— ๋™์ผํ•œ className='inner' $ ๊ฐ€ ์žˆ๋Š” ์š”์†Œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. ComponentB ์—์„œ๋งŒ .inner ์š”์†Œ๋ฅผ ํƒ€๊ฒŸํŒ…ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

@oliviertassinari๋‹˜ , ์•ˆ๋…•ํ•˜์„ธ์š”, Material UI์˜ ๋‹ค์Œ ๋ฒ„์ „์„ ์œ„ํ•œ ์Šคํƒ€์ผ๋ง์— ๋Œ€ํ•œ ๋ชจ๋“  ์ƒ๊ฐ์„ ๊ณต์œ ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  Material UI์—๋„ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๊ทธ ์œ„์— ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

styled-components ์ฑ„ํƒ์— ๊ด€ํ•ด์„œ๋Š” ์ด๋ฏธ ๊ฒฐ์ •๋œ ์‚ฌํ•ญ์ด๋ฉฐ ๊ทธ ๋ชฉํ‘œ๋ฅผ ํ–ฅํ•œ ์ž‘์—…์€ ์ด๋ฏธ ์‹œ์ž‘๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ @croraf ์™€ @lcswillems ๊ฐ€ ๊ด€์ฐฐํ•œ ๋‚ด์šฉ ์ค‘ ์ผ๋ถ€๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋จธํ‹ฐ๋ฆฌ์–ผ UI ์Šคํƒ€์ผ๋ง์—์„œ ์ข‹์€ ์ ์€ classes ์†์„ฑ์ž…๋‹ˆ๋‹ค.

classes ์ž…๋ ฅ์ด ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ผ๋ถ€์ด๊ธฐ ๋•Œ๋ฌธ์— ์Šคํƒ€์ผ ์‚ฌ์šฉ์ž ์ •์˜ ๋ฐ ์œ ์ง€ ๊ด€๋ฆฌ์— ๋งŽ์€ ๋„์›€์ด ๋˜๋Š” ๊ฐ„๋‹จํ•œ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฌด์–ธ๊ฐ€๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ํ•ด์•ผ ํ•˜๊ณ  & .Component-root ์™€ ๊ฐ™์€ ์„ ํƒ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ Component ๊ฐ€ ๋ฒ„์ „ ๊ฐ„์— ํ•ด๋‹น CSS ํด๋ž˜์Šค๋ฅผ ์œ ์ง€ํ•œ๋‹ค๋Š” ๋ณด์žฅ์€ ์—†์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ <Component classes={{root: ....}} /> ๊ฐ€ ์žˆ์œผ๋ฉด ์ธํ„ฐํŽ˜์ด์Šค ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์œ ํ˜• ๊ฒ€์‚ฌ ์˜ค๋ฅ˜(TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ)๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ์š”์†Œ ์ž‘์„ฑ์ž๋กœ์„œ ์ €๋Š” ๊ณต๊ฐœ๋œ(์ง€์›๋˜๋Š”) ํด๋ž˜์Šค๋ฅผ ๋ฌธ์„œํ™”ํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ๋ฌธ์„œํ™”ํ•˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

style-components ๋ฅผ ์•ฝ 2๋…„ ๋™์•ˆ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์ค‘์ ์ด๊ณ  ๋งŽ์ด ๋ฐœ์ „ํ•œ ๊ฒƒ์ด ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ MUI ๋ฌธ์„œ ์˜ˆ์ œ์—์„œ @crod ๊ฐ€ ์–ธ๊ธ‰ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ๋ฅผ ๋ด…๋‹ˆ๋‹ค. ํ•˜์œ„ ๊ตฌ์„ฑ ์š”์†Œ์— ์Šคํƒ€์ผ์„ ์ „ํŒŒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•˜์œ„ ์„ ํƒ์ž & .inner ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ทจ์•ฝํ•ฉ๋‹ˆ๋‹ค(๋‚ด ๊ฒฝํ—˜์— ๋”ฐ๋ฅด๋ฉด ๊ทธ๊ฒƒ์€ ์ฝ”๋„ˆ ์ผ€์ด์Šค๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค ... ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๋ช‡ ๋ฒˆ ์ผ์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค). ๋‘ ๊ฐ€์ง€ ๊ฐ€๋Šฅํ•œ ์†”๋ฃจ์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • &.inner ๋ฅผ ์‚ฌ์šฉํ•œ ๋‹ค์Œ ๋ชจ๋“  ๊ณณ์—์„œ ${props.className}.inner ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์—ฌ๋Ÿฌ ๋ฒˆํ–ˆ๊ณ  ์“ฐ๊ธฐ๊ฐ€ ๊ณ ํ†ต ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.
  • > .inner ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๊ตฌ์„ฑ ์š”์†Œ ๊ตฌ์กฐ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ค‘๊ฐ„์— div ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋Š์–ด์ง‘๋‹ˆ๋‹ค.

JSS๊ฐ€ ์ธ๊ธฐ๊ฐ€ ์—†๋Š” ๊ฒƒ์€ ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” MUI ๋•Œ๋ฌธ์— ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ styled-components ๋กœ ์˜ค๋žœ ์‹œ๊ฐ„ ์ž‘์—…ํ•œ ํ›„ MUI ์Šคํƒ€์ผ์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์‹ ์„ ํ•˜๊ณ  ์ž‘์—…ํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฝ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. HOC ... ์ ์–ด๋„ ๊ทธ๊ฒƒ์€ ๋‚ด ๊ฐœ์ธ์ ์ธ ๊ฒฝํ—˜์ž…๋‹ˆ๋‹ค). ๊ฐ์ •์€ ํ˜„์žฌ ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ ๋‹ค์†Œ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ท€ํ•˜์˜ ์˜๊ฒฌ๊ณผ ํŠน์ • ๊ฒฝ์šฐ์— JSS ์„ฑ๋Šฅ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ์ฝ์€ ํ›„ ๋””์ž์ธ ์‹œ์Šคํ…œ์— ๊ฐ์ •์„ ์‚ฌ์šฉํ• ์ง€ ํ‰๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ styled-components ์— ๋Œ€ํ•ด ํ™•์‹ ์„ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ๋ณด๋‹ˆ classes ์†Œํ’ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ€์ผ ์‚ฌ์šฉ์ž ์ •์˜๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์˜ˆ๋ฅผ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ MUI ๋ฌธ์„œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์„œ๋Š” ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋ฌธ์ œ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ์†Œํ’ˆ๊ณผ ํ•จ๊ป˜ styled-components ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”?

JSS๋Š” ์ถฉ๋ถ„ํžˆ ํ›Œ๋ฅญํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ๋งค์šฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด์‚ฌ๋ฅผ ๊ฐ€์•ผ ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๊ฐœ์ธ์ ์œผ๋กœ ๋‚˜๋Š” styled-component๊ฐ€ ์ผ์ข…์˜ ํ›„ํ‡ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ณ  JSS๊ฐ€ ๋‚ด๊ฐ€ ์ •์งํ•˜๊ฒŒ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•œ ์ฃผ๋œ ์ด์œ ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@powerfulj ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋ณด๋‹ค JSS๋ฅผ ์„ ํ˜ธํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋‘ ๊ฐ€์ง€ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ด์•ผ ํ–ˆ๊ณ  style-components๊ฐ€ ๋‚˜์—๊ฒŒ ๋” ๋‚˜์€ ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

@lcswillems
๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ƒˆ๋กœ์šด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋„์ž…ํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ์†์„ฑ์— ๋Œ€ํ•ด ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๊ฒƒ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ƒˆ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ •๋ง๋กœ ํ•„์š”ํ•œ ๊ฒฝ์šฐ JSS ์†”๋ฃจ์…˜์œผ๋กœ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ธ๋ผ์ธ ์Šคํƒ€์ผ์—์„œ JSS ์Šคํƒ€์ผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋น ๋ฆ…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌํ˜„ ์ค‘์— ์ธ๋ผ์ธ ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•˜๊ณ  ๋” ์ปค์ง€๊ณ  ์žฌ์‚ฌ์šฉ๋˜๋ฉด JSS๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ €์—๊ฒŒ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋ถ€์ •์ ์ธ ์ธก๋ฉด์€ (๋ธŒ๋ผ์šฐ์ € devtools์—์„œ์™€ ๊ฐ™์€) CSS๊ฐ€ ์žˆ๊ณ  ์ด๋ฅผ JSS๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๊ตฌ๋ฌธ์„ ์กฐ์ •ํ•˜๋Š” ๋ฐ ๋” ๋งŽ์€ ์‹œ๊ฐ„์„ ์†Œ๋น„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. styled-component๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋‚ด ๋ฐœ๊ฒฌ์„ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด.
#16947์—์„œ ์š”๊ตฌํ•˜๋Š” ๋Œ€๋กœ ์ผ๋ถ€ ๋ฐ๋ชจ๋ฅผ styled-components๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๊ธฐ๋ณธ ํ…Œ๋งˆ์ž…๋‹ˆ๋‹ค. makeStyles ๋Š” defaultTheme๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. defaultTheme ๋ฅผ ์ œ๊ณตํ•˜๋Š” makeStyles ๋ž˜ํผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ useStyles hook ์€ ThemeProvider ๊ฐ€ ํ…Œ๋งˆ๋ฅผ ์ œ๊ณตํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด defaultTheme ๋ฅผ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.

styled-components์—๋Š” ๊ทธ๋Ÿฌํ•œ ๊ธฐ๋Šฅ์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ThemeProvider ๊ฐ€ ์—†์œผ๋ฉด defaultTheme๋Š” .attrs ๋ฉ”์„œ๋“œ๋กœ๋งŒ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. makeStyles ๋ž˜ํผ์™€ ์œ ์‚ฌํ•œ ๊ฒƒ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import styledWithoutDefault from 'styled-components';
import defaultTheme from './defaultTheme';

const styled = Component => {
  return styledWithoutDefault(Component).attrs({ theme: defaultTheme });
};

export default styled;

๊ทธ๋Ÿฌ๋‚˜ .attrs ๋ฉ”์„œ๋“œ๋Š” ThemeProvider ์ œ๊ณตํ•˜๋Š” ํ…Œ๋งˆ๋ฅผ ๋ฎ์–ด์”๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ €๋Š” ํ˜„์žฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” makeStyles ๊ฐ€ jss-plugin-default-unit ์‚ฌ์ „ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  styled-components๊ฐ€ ์•„๋‹Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ styled-components๋Š” spacing() ํ•จ์ˆ˜์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด px ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋งˆ์ง€๋ง‰ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ฐ€๋Šฅํ•œ ํ•ด๊ฒฐ์ฑ…์€ styled-components๊ฐ€ ์•„๋‹Œ Styled-JSS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ๊ท€ํ•˜์˜ ์•„์ด๋””์–ด/์ œ์•ˆ์ด ์žˆ์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค.

@fyodore82 .attrs ๋Š” ํ•จ์ˆ˜๋กœ ์ž‘๋™ํ•˜๋ฏ€๋กœ(https://www.styled-components.com/docs/api#attrs ์ฐธ์กฐ) ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

```js
.attrs(({ ํ…Œ๋งˆ = defaultTheme, ...props }) => ({ ...props, ํ…Œ๋งˆ }))
````

@croraf

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

Styled-components: css prop ์˜ ์ •๋ง ์ข‹์€ ์ ์„ ๋†“์ณค๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. CSS๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค ํ•„์š” ์—†์ด ๊ตฌ์„ฑ ์š”์†Œ์— CSS๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ธ๋ผ์ธ ์Šคํƒ€์ผ์—์„œ JSS ์Šคํƒ€์ผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋น ๋ฆ…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌํ˜„ ์ค‘์— ์ธ๋ผ์ธ ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•˜๊ณ  ๋” ์ปค์ง€๊ณ  ์žฌ์‚ฌ์šฉ๋˜๋ฉด JSS๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ €์—๊ฒŒ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

CSS prop์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ CSS prop์ด ์žˆ๋Š” ๊ตฌ์„ฑ ์š”์†Œ์—๋Š” style ์†์„ฑ์ด ์—†๊ณ , ์ด๋ฏธ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ณ€ํ™˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ class ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. CSS๊ฐ€ ๋” ์ปค์ง€๊ณ  ์žฌ์‚ฌ์šฉ๋˜๋ฉด ์ƒˆ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถ€์ •์ ์ธ ์ธก๋ฉด์€ (๋ธŒ๋ผ์šฐ์ € devtools์—์„œ์™€ ๊ฐ™์€) CSS๊ฐ€ ์žˆ๊ณ  ์ด๋ฅผ JSS๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๊ตฌ๋ฌธ์„ ์กฐ์ •ํ•˜๋Š” ๋ฐ ๋” ๋งŽ์€ ์‹œ๊ฐ„์„ ์†Œ๋น„ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. styled-component๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

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

Styled-components๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋งŒ๋“  ๋‹ค๋ฅธ ์ถ”๊ฐ€ ์ธ์ˆ˜:

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

JSS ๋ฒ„์ „:

import React from 'react';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import SkipPreviousIcon from '@material-ui/icons/SkipPrevious';
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
import SkipNextIcon from '@material-ui/icons/SkipNext';

const useStyles = makeStyles(theme => ({
  card: {
    display: 'flex',
  },
  details: {
    display: 'flex',
    flexDirection: 'column',
  },
  content: {
    flex: '1 0 auto',
  },
  cover: {
    width: 151,
  },
  controls: {
    display: 'flex',
    alignItems: 'center',
    paddingLeft: theme.spacing(1),
    paddingBottom: theme.spacing(1),
  },
  playIcon: {
    height: 38,
    width: 38,
  },
}));

export default function MediaControlCard() {
  const classes = useStyles();
  const theme = useTheme();

  return (
    <Card className={classes.card}>
      <div className={classes.details}>
        <CardContent className={classes.content}>
          <Typography component="h5" variant="h5">
            Live From Space
          </Typography>
          <Typography variant="subtitle1" color="textSecondary">
            Mac Miller
          </Typography>
        </CardContent>
        <div className={classes.controls}>
          <IconButton aria-label="previous">
            {theme.direction === 'rtl' ? <SkipNextIcon /> : <SkipPreviousIcon />}
          </IconButton>
          <IconButton aria-label="play/pause">
            <PlayArrowIcon className={classes.playIcon} />
          </IconButton>
          <IconButton aria-label="next">
            {theme.direction === 'rtl' ? <SkipPreviousIcon /> : <SkipNextIcon />}
          </IconButton>
        </div>
      </div>
      <CardMedia
        className={classes.cover}
        image="/static/images/cards/live-from-space.jpg"
        title="Live from space album cover"
      />
    </Card>
  );
}

์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ ๋ฒ„์ „:

import React from 'react';
import styled from 'styled-components';
import { useTheme } from '@material-ui/core';
import MuiCard from '@material-ui/core/Card';
import MuiCardContent from '@material-ui/core/CardContent';
import MuiCardMedia from '@material-ui/core/CardMedia';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import SkipPreviousIcon from '@material-ui/icons/SkipPrevious';
import MuiPlayArrowIcon from '@material-ui/icons/PlayArrow';
import SkipNextIcon from '@material-ui/icons/SkipNext';

export default function MediaControlCard() {
  const theme = useTheme();

  return (
    <Card>
      <Details>
        <CardContent>
          <Typography component="h5" variant="h5">
            Live From Space
          </Typography>
          <Typography variant="subtitle1" color="textSecondary">
            Mac Miller
          </Typography>
        </CardContent>
        <Controls>
          <IconButton aria-label="previous">
            {theme.direction === 'rtl' ? <SkipNextIcon /> : <SkipPreviousIcon />}
          </IconButton>
          <IconButton aria-label="play/pause">
            <PlayArrowIcon />
          </IconButton>
          <IconButton aria-label="next">
            {theme.direction === 'rtl' ? <SkipPreviousIcon /> : <SkipNextIcon />}
          </IconButton>
        </Controls>
      </Details>
      <CardMedia
        image="/static/images/cards/live-from-space.jpg"
        title="Live from space album cover"
      />
    </Card>
  );
}

const Card = styled(MuiCard)`
  display: flex;
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

const CardContent = styled(MuiCardContent)`
  flex: 1 0 auto;
`

const CardMedia = styled(MuiCardMedia)`
  width: 151px;
`

const Controls = styled.div`
  display: flex;
  align-items: center;
  padding-left: ${props => props.theme.spacing(1)}px;
  padding-bottom: ${props => props.theme.spacing(1)}px;
`

const PlayArrowIcon = styled(MuiPlayArrowIcon)`
  height: 38px;
  width: 38px;
`

๋งˆ์ง€๋ง‰์œผ๋กœ JSS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

css ์†์„ฑ์€ ๋งค์šฐ ํ›Œ๋ฅญํ•˜๊ณ  ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‚ด๊ฐ€ ์–ธ๊ธ‰ํ•œ ๋‹จ์ ์„ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. (copycats form styled-components :D )

๋‘ ๊ฐ€์ง€ ์˜ˆ์˜ ๋น„๊ต์™€ ๊ด€๋ จํ•˜์—ฌ ์ฝ๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š์œผ๋ฉฐ ๊ตฌ์„ฑ ์š”์†Œ ์ˆ˜๊ฐ€ ๋‘ ๋ฐฐ๋กœ ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค.

@lcswillems

ํ•˜๋‚˜์˜ ์†”๋ฃจ์…˜ ๋˜๋Š” ๋‹ค๋ฅธ ์†”๋ฃจ์…˜์— ๋Œ€ํ•ด ๋…ผ์Ÿํ•˜์ง€ ์•Š๊ณ  ๋ช‡ ๊ฐ€์ง€ ์š”์ ์„ ์„ ํƒํ•˜์‹ญ์‹œ์˜ค.

StackOverflow์˜ ์ผ๋ถ€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € JSS๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋งค์šฐ ๊ณ ํ†ต์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

ํ•ญ์ƒ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ CSS๋ฅผ CSS-in-JS๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ VSCode ํ™•์žฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๊ณ ํ†ต์Šค๋Ÿฝ๊ฒŒ ๋ถ€๋ฅด์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ตฌ๋ฌธ ๊ฐ•์กฐ ํ‘œ์‹œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์ด ์ฃผ์žฅ์ด ์ž˜ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. JS ๊ฐœ์ฒด์ผ ๋ฟ์ด๋ฏ€๋กœ ๋ชจ๋“  ํŽธ์ง‘๊ธฐ์˜ ๊ตฌ๋ฌธ ๊ฐ•์กฐ ํ‘œ์‹œ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

image

(ํ•˜์ง€๋งŒ ์•„๋งˆ๋„ ๋‹น์‹ ์€ ๋” ๊ตฌ์ฒด์ ์ธ ๊ฒƒ์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?)

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

styled() ํ˜ธ์ถœ์€ (์ €๋ฅผ ์œ„ํ•ด) JSS ๊ฐ์ฒด๋ณด๋‹ค ์ฝ๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

@powerfulj ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋ณด๋‹ค JSS๋ฅผ ์„ ํ˜ธํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋‘ ๊ฐ€์ง€ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ด์•ผ ํ–ˆ๊ณ  style-components๊ฐ€ ๋‚˜์—๊ฒŒ ๋” ๋‚˜์€ ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

์ €๋Š” Typescript ๊ฐœ๋ฐœ์ž์ด๊ณ  Typescript ๊ฐœ์ฒด์—์„œ ๋ชจ๋“  ๊ฒƒ์„ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ๋‚˜๋Š” ์ŠคํŠธ๋ง์„ ์‹ซ์–ดํ•œ๋‹ค.

์ฐจ์ด์  ๋•Œ๋ฌธ์— CSS ์ฝ”๋“œ๋ฅผ JSS ์ฝ”๋“œ๋กœ ์ „์†กํ•ด์•ผ ํ•˜์ง€๋งŒ ๊ตฌ์กฐ๊ฐ€ ๊ธฐ์กด CSS(ํด๋ž˜์Šค ์ง€ํ–ฅ)์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ์ „ํžˆ JSS ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์ €๊ธฐ์— ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์‚ฌ๋žŒ๋“ค์ด ๊ณผ๊ฑฐ์— Styled-component์— ๋Œ€ํ•œ ๊ฒฝํ—˜์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ์„ ์ฃผ์žฅํ–ˆ๋‹ค๊ณ  โ€‹โ€‹์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. "์šฐ๋ฆฌ์—๊ฒŒ ์ต์ˆ™ํ•˜์ง€๋งŒ ๋šœ๋ ทํ•œ ์ด์ ์ด ์—†๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–จ๊นŒ์š”?"๋ผ๋Š” ๋Š๋‚Œ์„ ์ค๋‹ˆ๋‹ค.

๋‚ด ๊ด€์ ์—์„œ JSS๋Š” ๊ทธ๋ƒฅ ํŽธ๋ฆฌํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชจ๋“  Javascript ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

{
...๊ณต์œ JSS1,
...๊ณต์œ JSS2,
๋ฌด์—‡์ด๋“ 
}

๋˜ํ•œ ์œ ํ˜•๊ณผ ํ†ตํ•ฉ๋œ ๋งค๋„๋Ÿฌ์šด ๋™์  ํ…Œ๋งˆ๊ฐ€ ์žˆ์œผ๋ฉฐ className ๋ฐ css ์œ ํ˜• ๋ชจ๋‘์—์„œ ๋ชจ๋“  ์œ ํ˜• ํžŒํŠธ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ์ž์˜ ๊ฒฝ์šฐ ํŠนํžˆ Typescript ๊ฐœ๋ฐœ์ž๋Š” ๋‹จ์ˆœํžˆ JSS๋ฅผ ์ข‹์•„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

const Wrapper = styled.div`
  display: block;

  .inner {
    flex: 1;
  }
`

...
  <Wrapper>
    <div class="inner">...</div>
  </Wrapper>

์ž์„ธํ•œ ๋‚ด์šฉ์€ https://www.styled-components.com/docs/faqs#can -i-nest-rules๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ฝ”๋”ฉ ์Šคํƒ€์ผ ๊ธฐ๋ณธ ์„ค์ •์— ๋Œ€ํ•œ ํ† ๋ก ์€ ์˜์›ํžˆ ๊ณ„์†๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž ์‹œ ๋™์•ˆ styled-components ๋ฅผ ์‚ฌ์šฉํ•œ ํ›„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ JSS ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋” ๋งˆ์Œ์— ๋“ญ๋‹ˆ๋‹ค.

  • ์Šคํƒ€์ผ์ด ๊ธธ์–ด์ง€๋ฉด ๋ณดํ†ต ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
    styled-components ๋กœ๋„ ๊ทธ๋ ‡๊ฒŒ ํ–ˆ๊ณ  useStyles / makeStyles ๊ฐ€ ์“ฐ๊ธฐ, ์ฝ๊ธฐ ๋ฐ ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๋” ์‰ฝ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ์˜ˆ. import useStyles from './MyComp.styles' vs import {XStyled, YStyled,...} from './MyComp.styles' ... TS์—์„œ ์ž…๋ ฅํ•˜๋Š” ...Styled ๋ณ€ํ˜•์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์€ ์„ฑ๊ฐ€์‹  ์ผ์ž…๋‹ˆ๋‹ค.
  • ์ €๋Š” ์ ์ง„์ ์œผ๋กœ ์ผ์„ ํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋จผ์ € div์™€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ์•ˆ์œผ๋กœ ์‹œ์ž‘ํ•œ ๋‹ค์Œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ฆฌํŒฉํ† ๋งํ•ฉ๋‹ˆ๋‹ค. styled-components ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋‚ด๋ถ€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ(@mbrowne์˜ ์˜ˆ์—์„œ์™€ ๊ฐ™์ด) ๋” ๋งŽ์€ ๋ฆฌํŒฉํ† ๋ง ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” useStyles ์ ‘๊ทผ ๋ฐฉ์‹์ด ํ•ด๋‹น ์›Œํฌํ”Œ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ํ›จ์”ฌ ๋” ํŽธ์•ˆํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.
  • ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด์€ CSS ์ฝ”๋“œ๋ฅผ ๋ถ™์—ฌ๋„ฃ๋Š” ๋ฐ ์ข‹์ง€๋งŒ ํ…Œ๋งˆ/์†Œํ’ˆ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋”์ฐํ•ฉ๋‹ˆ๋‹ค. ๋ถ™์—ฌ๋„ฃ๊ธฐ ์ฝ”๋“œ ๋ฌธ์ œ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด ๋‚ด๋ถ€์˜ ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜๋กœ ํŽธ์ง‘ํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋ฆฌ ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๊ฑด ์ œ ๊ฐœ์ธ์ ์ธ ์ทจํ–ฅ์ด๋‹ˆ ์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ์ทจํ–ฅ์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ํฐ ๋ฏธํ•ด๊ฒฐ ์งˆ๋ฌธ์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•œ classes ์‚ฌ์šฉ์ž…๋‹ˆ๋‹ค.

className ๋ฐ ๋‚ด๋ถ€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์—๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์ด์ „ ์˜๊ฒฌ ์ฐธ์กฐ). $# styled-components ์˜ css ์†Œํ’ˆ์€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์˜ต์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ฐ์ •์˜ css ํ•จ์ˆ˜์™€ ๋‹ฌ๋ฆฌ css ์†Œํ’ˆ์€ ๊ตฌ์„ฑ ์š”์†Œ์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, useStyle/makeStyles/classes ์ฝ”๋“œ ์Šคํƒ€์ผ์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ).

๊ตฌ์„ฑ ์š”์†Œ์— ์Šคํƒ€์ผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์†Œํ•œ ๋””์ž์ธ ๊ฒฐ์ •์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ ๊ทธ๊ฒƒ์€ JSS์˜ ์ข‹์€ ์ ๊ณผ ๋‚˜์œ ์ ์ž…๋‹ˆ๋‹ค. ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ์™€ ๊ฐ์ •์€ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์— ์˜์กดํ•˜๊ณ  SSR์— ๋Œ€ํ•œ ์บ์‹ฑ ๋ฐ ํด๋ž˜์Šค ์ด๋ฆ„ ์ƒ์„ฑ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด React์™€ ์ƒํ˜ธ ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค. JSS์˜ ์ข‹์€ ์ ์€ Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜์œ ๋ถ€๋ถ„์€ JSS์˜ SSR์ด ๋” ๋งŽ์€ ์ž‘์—…์„ ํ•„์š”๋กœ ํ•˜๊ณ  ๊ทธ ์˜์—ญ์—์„œ ๋ณด๊ณ ๋œ ๋ฒ„๊ทธ๋ฅผ ๋ณธ ์ ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

MUI๋กœ ๋Œ์•„๊ฐ€์„œ ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ฑ„ํƒํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์Šคํƒ€์ผ์„ ์‚ฌ์šฉ์ž ์ •์˜ํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ className ๋ฐ ๋‚ด๋ถ€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค๋Š” ์ธ์ƒ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ์Šคํƒ€์ผ์€ ํ”„๋ ˆ์ž„์›Œํฌ ์ „์ฒด์—์„œ ๋”์šฑ ์ผ๊ด€๋ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ className ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•œ styled ๋˜๋Š” css ์†Œํ’ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‚˜์—๊ฒŒ classes ์†Œํ’ˆ์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์€ ๋’ค๋กœ ๋ฌผ๋Ÿฌ๋‚˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์†Œํ’ˆ์€ ๊ฒ€์‚ฌ ์Šคํƒ€์ผ ์‚ฌ์šฉ์ž ์ •์˜๋ฅผ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์ž…๋ ฅํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. styled-components๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ classes ์— ๋Œ€ํ•œ ์ง€์›์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ์ค‘๊ฐ„ ์ง€์ ์„ ์ฐพ๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค(๋‚ด๋ถ€ ํด๋ž˜์Šค ํ•ดํ‚น ํ•„์š” ์—†์ด). ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์— ๋„์›€์ด ๋˜๋Š” styled-components API์—์„œ ์•„๋ฌด ๊ฒƒ๋„ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— JSS์˜ ๊ธฐ์ˆ ์  ๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ํ‰๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ๊ธฐ๊ฐ€ ์ฃผ์š” ๋ฌธ์ œ๋ผ๋ฉด ๊ฐ์ •๋„ ๋Œ€์ค‘ํ™”๋˜๊ณ  ์žˆ์œผ๋ฉฐ(https://2019.stateofcss.com/technologies/css-in-js/#tools-section-overview ์ฐธ์กฐ) makeStyles ๋‹ค์‹œ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

@dfernandez-asapp ์ด fwiw @styled-components๋Š” https://www.styled-components.com/docs/advanced# ๋ฌธ์ž์—ด ๋Œ€์‹  jss์™€ ์œ ์‚ฌํ•œ ๊ฐœ์ฒด ์‚ฌ์šฉ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

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

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

const Wrapper = styled.div`
  display: block;

  .inner {
    flex: 1;
  }
`

...
  <Wrapper>
    <div class="inner">...</div>
  </Wrapper>

์ž์„ธํ•œ ๋‚ด์šฉ์€ https://www.styled-components.com/docs/faqs#can -i-nest-rules๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ด์— ๋Œ€ํ•œ ์ง€์› ์œ ํ˜•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋ชจ๋“  ๊ณณ์— ๋ฌธ์ž์—ด์„ ๋„ฃ์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ์™œ ๊ทธ๋ ‡๊ฒŒ ๋งŽ์€ ๊ณผ๋Œ€ ๊ด‘๊ณ ๊ฐ€ ์žˆ๋Š”์ง€ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ •์งํ•˜๊ฒŒ ํ•œ ๋ฐœ์ง ๋ฌผ๋Ÿฌ๋‚œ ๋Š๋‚Œ์ž…๋‹ˆ๋‹ค. TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” JSS์˜ ์œ ํ˜•์ด ์ง€์ •๋œ CSS ์†์„ฑ์€ ํ›จ์”ฌ ๋” ํŽธ๋ฆฌํ•˜๊ณ  ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๋” ์‰ฌ์šฐ๋ฉฐ JS์˜ ์ผ๋ถ€๋กœ ๊ตฌ๋ฌธ ๊ฒ€์‚ฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹ /๊ตฌ์„ฑ๋œ ํŽธ์ง‘๊ธฐ๋Š” ์˜คํƒ€๊ฐ€ ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ณ  ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ž๋™ ์™„์„ฑ์„ ๋„์™€์ค๋‹ˆ๋‹ค.

ํŽธ์ง‘: ์ž…๋ ฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ South-Paw์˜ ๋‹ต๋ณ€์„ ์ฐธ์กฐํ•˜์„ธ์š”.

@martinjlowm ์ด ๋‚˜์—๊ฒŒ ํƒ€์ดํ•‘์„ ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ?

image

์ฐธ์กฐ: https://styled-components.com/docs/advanced#style -objects

๋‹น์‹ ์€ ๊ณผ๋Œ€ ๊ด‘๊ณ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค๊ณ  ๋งํ•˜์ง€๋งŒ... ์ €๋„ ๊ทธ๊ฒƒ์ด ๋ฐ›๋Š” ๋ชจ๋“  ์ฆ์˜ค๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๐Ÿคทโ€โ™‚

๊ฐ์ • ๋ฐ ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋Š” CSS ์Šคํƒ€์ผ ๊ฐœ์ฒด์— ๋น„ํ•ด ํฌ๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. IMO

@martinjlowm ์ด ๋‚˜์—๊ฒŒ ํƒ€์ดํ•‘์„ ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ?

...

์ฐธ์กฐ: https://styled-components.com/docs/advanced#style -objects

๋‹น์‹ ์€ ๊ณผ๋Œ€ ๊ด‘๊ณ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค๊ณ  ๋งํ•˜์ง€๋งŒ... ์ €๋„ ๊ทธ๊ฒƒ์ด ๋ฐ›๋Š” ๋ชจ๋“  ์ฆ์˜ค๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๐Ÿคทโ€โ™‚

๊ฐ์ • ๋ฐ ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋Š” CSS ์Šคํƒ€์ผ ๊ฐœ์ฒด์— ๋น„ํ•ด ํฌ๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. IMO

๋‚ด๊ฐ€ ์ฐธ์กฐ! ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๊ทธ๋Ÿฐ ๊ฐ์ฒด๋ฅผ ์ง€์›ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ๊ด€์‹ฌ์‚ฌ๋Š” ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด์˜ CSS์™€ ๊ด€๋ จ์ด ์žˆ์ง€๋งŒ ๊ฐœ์ฒด๊ฐ€ ์˜ต์…˜์ด๋ผ๋ฉด ๋ฐ˜๋Œ€ํ•  ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค!

๋ถ„๋ช…ํžˆ JSS๋„ ์™„๋ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์„œ๋ฒ„ ์ƒ์„ฑ ์‹œํŠธ๊ฐ€ โ€‹โ€‹ํ‚ฌ๋Ÿฌ ๊ธฐ๋Šฅ์ด ๋  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์••๋‹ˆ๋‹ค. styled-component๋Š” ์–ด๋–ป๊ฒŒ๋“  ์ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๊นŒ? ์•„๋Š” ์‚ฌ๋žŒ ์žˆ๋‚˜์š”?

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

@martinjlowm ์ด ๋‚˜์—๊ฒŒ ํƒ€์ดํ•‘์„ ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ?
...
์ฐธ์กฐ: https://styled-components.com/docs/advanced#style -objects
๋‹น์‹ ์€ ๊ณผ๋Œ€ ๊ด‘๊ณ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค๊ณ  ๋งํ•˜์ง€๋งŒ... ์ €๋„ ๊ทธ๊ฒƒ์ด ๋ฐ›๋Š” ๋ชจ๋“  ์ฆ์˜ค๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๐Ÿคทโ€โ™‚
๊ฐ์ • ๋ฐ ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋Š” CSS ์Šคํƒ€์ผ ๊ฐœ์ฒด์— ๋น„ํ•ด ํฌ๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. IMO

๋‚ด๊ฐ€ ์ฐธ์กฐ! ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๊ทธ๋Ÿฐ ๊ฐ์ฒด๋ฅผ ์ง€์›ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ๊ด€์‹ฌ์‚ฌ๋Š” ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด์˜ CSS์™€ ๊ด€๋ จ์ด ์žˆ์ง€๋งŒ ๊ฐœ์ฒด๊ฐ€ ์˜ต์…˜์ด๋ผ๋ฉด ๋ฐ˜๋Œ€ํ•  ๊ฒƒ์ด ์—†์Šต๋‹ˆ๋‹ค!

๋ถ„๋ช…ํžˆ JSS๋„ ์™„๋ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์„œ๋ฒ„ ์ƒ์„ฑ ์‹œํŠธ๊ฐ€ โ€‹โ€‹ํ‚ฌ๋Ÿฌ ๊ธฐ๋Šฅ์ด ๋  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์„ ์••๋‹ˆ๋‹ค. styled-component๋Š” ์–ด๋–ป๊ฒŒ๋“  ์ด๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๊นŒ? ์•„๋Š” ์‚ฌ๋žŒ ์žˆ๋‚˜์š”?

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

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

image

@์ขŒ์™„ ํˆฌ์ˆ˜

๊ฐ์ • ๋ฐ ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋Š” CSS ์Šคํƒ€์ผ ๊ฐœ์ฒด์— ๋น„ํ•ด ํฌ๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. IMO

๋‚˜๋Š” ์—ฌ์ „ํžˆ ์–ด๋–ค React ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๊ฒƒ์— ์ฐธ์—ฌํ•˜๋Š”์ง€ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. CSS๋ฅผ ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด์— ๋„ฃ์œผ๋ ค๋ฉด Angular๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  HTML๋„ ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด์— ๋„ฃ์ง€ ์•Š์Šต๋‹ˆ๊นŒ? React์˜ ์žฅ์ ์€ JSX ์š”์†Œ๊ฐ€ ์‹ค์ œ๋กœ๋Š” ๊ฒ€์‚ฌํ•˜๊ณ  ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ์—„์ฒญ๋‚œ ๊ถŒํ•œ์ด ์žˆ๋Š” JS ๊ฐ์ฒด์ด๋ฉฐ JSS๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

JS ์›€์ง์ž„์—์„œ CSS๋ฅผ ์ฃผ๋„ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์€ JS๊ฐ€ ๋™์  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” CSS๋ณด๋‹ค ํ›จ์”ฌ ๋›ฐ์–ด๋‚˜๊ณ  JS ๊ฐ์ฒด์˜ ํž˜์ด ์ž‘์€ ๋ถ€๋ถ„์ด ์•„๋‹ˆ๋ผ๋Š” ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค.

styled-components ๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ง€์›ํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์€ ์ผ์ข…์˜ ๋ถ‰์€ ์ฒญ์–ด์ž…๋‹ˆ๋‹ค.

  • ๊ทธ๊ฒƒ์€ ๊ทธ๊ฒƒ๋“ค์„ ์ง€์›ํ•˜์ง€๋งŒ ์–ด๋–ค ์ด์œ ๋กœ "์ด๊ฒƒ์€ ๊ธฐ์กด ์Šคํƒ€์ผ ๊ฐœ์ฒด๊ฐ€ ์žˆ๊ณ  ์ ์ฐจ์ ์œผ๋กœ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์ด๋™ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์— ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค."๋ผ๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๋ถ„๋ช…ํžˆ ๊ฐ์ฒด๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฐ€์น˜๋ฅผ ๋ณด์ง€ ๋ชปํ•˜๊ณ  ์Šคํƒ€์ผ ๊ฐ์ฒด๊ฐ€ API์—์„œ ํ•ญ์ƒ 2๊ธ‰ ์‹œ๋ฏผ์œผ๋กœ ์ทจ๊ธ‰๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.
  • ๋ฌธ์„œ๋Š” JSS์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‹ค์ œ CSS ์„ ํƒ๊ธฐ๋ฅผ ์ง€์›ํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
{
  color: 'black',
  '&$error': {
    color: 'red'
  }
}

์‹ฌ์ง€์–ด ๊ฐ์ •์€ ์Šคํƒ€์ผ ๊ฐœ์ฒด์˜ ๊ฐ€์น˜๋ฅผ ์กด์ค‘ํ•˜๊ณ  ์ด๋ฅผ ์ผ๋ฅ˜ ์‹œ๋ฏผ์œผ๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

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

@lcswillems ๋‹น์‹ ์€ ์ด ๋ชจ๋“  ์ž‘์€ HOC๋ฅผ ํ•ญ์ƒ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ๋ฒˆ๊ฑฐ๋กœ์šด์ง€ ๊ณผ์†Œํ‰๊ฐ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(๊ทธ๋ฆฌ๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ์ž๋™ ๊ฐ€์ ธ์˜ค๊ธฐ ์‹œ์Šคํ…œ์ด @material-ui/core/Card ๋ฅผ Card ๋กœ ๊ฐ€์ ธ์˜ฌ์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ๋งŒํผ ๋˜‘๋˜‘ํ•˜์ง€ ์•Š๋‹ค๋Š” ์‚ฌ์‹ค) MuiCard (๊ทธ๋ฆฌ๊ณ  ์—ฌ์ „ํžˆ import ๋ฌธ์„ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ์‹œ๊ฐ„์„ ์‹ฌ๊ฐํ•˜๊ฒŒ ๋‚ญ๋น„ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค))

const Card = styled(MuiCard)`
  display: flex;
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

const CardContent = styled(MuiCardContent)`
  flex: 1 0 auto;
`

const CardMedia = styled(MuiCardMedia)`
  width: 151px;
`

์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ์ผ์€ ๊ฐ ๋ž˜ํผ์™€ ๋ž˜ํ•‘๋œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์†์ ์œผ๋กœ ๊ฒฐ์ •ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋”์ฐํ•œ ๊ฒฐ์ • ํ”ผ๋กœ๋ฅผ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด @dfernandez-asapp์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งํ•  ๋•Œ ๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

(์ž ์‹œ ํ›„์— Styled HOC๋ฅผ ์‚ฌ๋ฐฉ์— ๋‘๋Š” ๊ฒƒ์€ ๋งŽ์€ ์ถ”๊ฐ€ ์ž‘์—…์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋‚˜๋Š” ๊ทธ HOC๋ฅผ ์‹ซ์–ดํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค... ์ ์–ด๋„ ๊ทธ๊ฒƒ์€ ์ œ ๊ฐœ์ธ์ ์ธ ๊ฒฝํ—˜์ž…๋‹ˆ๋‹ค)

HOC๋Š” ๊ฑฐ์˜ ์ฃฝ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์‹ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, react-redux ๋Š” connect HOC๋ณด๋‹ค 100๋ฐฐ ๋” ํŽธ๋ฆฌํ•œ useSelector ํ›„ํฌ์™€ ํ•จ๊ป˜ ๋‚˜์™”๊ณ  Apollo๋Š” HOC์—์„œ ํ›„ํฌ๋กœ ์ด๋™ํ–ˆ์œผ๋ฉฐ useStyles ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ withStyles ๋ณด๋‹ค ๋” ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ์€ CSS๋ฅผ JSS๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์€ ํ›จ์”ฌ ๋” ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๊ด€์‹ฌ์ด ์žˆ๋‹ค๋ฉด ์ž๋™ํ™” ๋˜๋Š” ์›น์‚ฌ์ดํŠธ๋ฅผ ์œ„ํ•œ VSCode ํ™•์žฅ์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ด€์‹ฌ์ด ์žˆ๋‹ค๋ฉด ์ž๋™ํ™”๋ฅผ ์œ„ํ•ด VSCode ํ™•์žฅ์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@jedwards1211 paulmolluzzo.convert-css-in-js ๊ฐ€ ์žˆ์ง€๋งŒ JSS์šฉ์œผ๋กœ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ™˜์˜ํ•  ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ํ™•์‹คํžˆ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทœ์น™๊ณผ ์„ ํƒ๊ธฐ๊ฐ€ ์•„๋‹Œ CSS ์†์„ฑ๋งŒ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

@jedwards1211 ๋‚˜๋Š” ๋‹น์‹ ์ด ๋งํ•œ ๊ฒƒ์„ ์ฝ๊ณ  ์ž ์‹œ ์ด ๋ชจ๋“  ๊ฒƒ์—์„œ ํ•œ ๊ฑธ์Œ ๋ฌผ๋Ÿฌ์„œ์„œ ๊ณต๋ฐฑ ์œ„์— ํƒญ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๋…ผ์Ÿํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์˜ ๋Œ“๊ธ€์„ ์ƒ๊ฐ๋‚˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š” ๋งˆ์ง€๋ง‰์— ์œ ์šฉํ•œ ์ œํ’ˆ์„ ์ƒ์‚ฐํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฌด์—‡์„ ์‚ฌ์šฉํ•˜๋“  ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

Twitter ๋˜๋Š” Reddit์— ์˜๊ฒฌ/ํ•ซ ํ…Œ์ดํฌ๋ฅผ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ๊ฑฐ๊ธฐ์„œ ํ† ๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด๊ณผ CSS ๊ฐœ์ฒด์— ๋Œ€ํ•œ ๋ฌด์˜๋ฏธํ•œ ๋ถˆ๊ฝƒ ์ „์Ÿ์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ๊ณ„์† ํƒˆ์„ ์‹œํ‚ค์ง€ ๋ง์ž... ์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ๋” ๋‚ซ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋ณด๋‹ค ๐Ÿ˜„

MUI์—์„œ ํ˜„์ƒ ์œ ์ง€๋ฅผ ๋ณ€๊ฒฝํ•  ๊ฐ€์น˜๊ฐ€ ์—†๋‹ค๋Š” ์ ์„ ์ง€์ ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜‰

๋‚ด ์ฃผ์š” ๊ด€์‹ฌ์‚ฌ๋Š” ๋‚ด webpack ๋ฒˆ๋“ค์ด styled-components ์ฝ”๋“œ์™€ JSS ์ฝ”๋“œ์˜ ํ˜ผํ•ฉ์œผ๋กœ ๋ถ€ํ’€์–ด ์˜ค๋ฅด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์•ฑ์— ๊ธฐ์กด JSS๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์„œ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋Œ€์ฒดํ•˜๊ฑฐ๋‚˜ ๋นผ๋‚ด๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์–ด์จŒ๋“  ์šฐ๋ฆฌ ์Šคํƒ€์ผ์„ ์œ„ํ•œ JSS.

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

@jedwards1211 ๊ฐ•์ œ๋กœ Styled Components๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ v4 ์— ๋„์ž…๋œ ๋Œ€์ฒด css prop ๊ตฌ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ(MuiCard, StyledCard ๋“ฑ)์— ์ ‘๋‘์‚ฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

import { Avatar } from '@material-ui/core';

// CSS is separate from the markup ๐Ÿ‘
const avatarStyle = css`
  width: 32px;
  height: 32px;
  border-radius: 50%
`;

// No wrappers, prefixes in the markup (such as <MuiAvatar>, <StyledAvatar> etc.) ๐Ÿ‘
function SomeComponent(props) {
  return <div> ... <Avatar css={avatarStyle} /> ... </div>
}

@jedwards1211 ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์˜ˆ์ œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹จ์ˆœํ™”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

const Card = styled(MuiCard)`
  display: flex;

  ${MuiCardContent} {
    flex: 1 0 auto;
  }

  ${MuiCardMedia} {
    width: 151px;
  }
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

@koistya css ์†Œํ’ˆ์€ ๋ฉ‹์ง„ ํŽธ์ด์ง€๋งŒ, ์ค‘์š”ํ•œ ์ฃผ์˜ ์‚ฌํ•ญ์€ ์ด๊ฒƒ์ด Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ๋ชจ๋“  ์‚ฌ๋žŒ, ํŠนํžˆ tsc๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ tsx ํŒŒ์ผ์„ ์ปดํŒŒ์ผํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋˜ํ•œ TypeScript ๋˜๋Š” ์ ์–ด๋„ Flow๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ์— css ์†Œํ’ˆ์ด ์—†๋‹ค๊ณ  ๋ถˆํ‰ํ•˜๊ฒŒ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ๋‚ด ์•ฑ์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ž ์žฌ์ ์ธ ์ค‘๋‹จ์— ๋Œ€ํ•ด ์ฃผ๋กœ ๋ถˆํ–‰ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. @oliviertassinari ๋Š” ์ „์— MUI v5์—์„œ styled-components ๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ์„ ํƒ ์‚ฌํ•ญ์ด๊ธธ ๋ฐ”๋ผ๊ณ  JSS๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๊ทธ๋“ค์ด ๊ทธ๊ฒƒ์„ ํ•ด๋‚ผ ์ˆ˜ ์žˆ๋Š”์ง€ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์ถฉ๊ฒฉ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ „์ฒด ์‚ฌ์šฉ์ž ๊ธฐ๋ฐ˜์˜ ์„ ํ˜ธ๋„์— ๋Œ€ํ•œ ์ฒ ์ €ํ•œ ๊ตญ๋ฏผ ํˆฌํ‘œ๊ฐ€ ์‹ค์ œ๋กœ ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ? ์ง€๊ธˆ์€ ํ›จ์”ฌ ๋” ๋Œ€์ค‘์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜๋Š” ๊ฐ์ •์„ ๊ธฐ๋Œ€ํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ TypeScript ๋˜๋Š” ์ ์–ด๋„ Flow๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ์— CSS ์†Œํ’ˆ์ด ์—†๋‹ค๊ณ  ๋ถˆํ‰ํ•˜๊ฒŒ ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ „์ฒด ์‚ฌ์šฉ์ž ๊ธฐ๋ฐ˜์˜ ์„ ํ˜ธ๋„์— ๋Œ€ํ•œ ์ฒ ์ €ํ•œ ๊ตญ๋ฏผ ํˆฌํ‘œ๊ฐ€ ์‹ค์ œ๋กœ ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ?

์ด๊ฑด ๋ถˆ๊ฐ€๋Šฅ ํ•ด. GitHub์— ์ฐธ์—ฌํ•˜๋Š” ์‚ฌ๋žŒ๋“ค์ด "์šฐ๋ฆฌ" ์‚ฌ์šฉ์ž๋ผ๊ณ  ๊ฐ€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ง„ ๊ฐ€์žฅ ๋งŽ์€ ํˆฌํ‘œ ๋ฅผ ๋ฐ›์€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ ํ›จ์”ฌ ๋” ๋Œ€์ค‘์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜๋Š” ๊ฐ์ •์„ ๊ธฐ๋Œ€ํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ธ๊ธฐ๋„๋Š” ์–ด๋–ป๊ฒŒ ์ธก์ •ํ–ˆ๋‚˜์š”?

โš ๏ธ ๊ฐ์ •์€ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ณด๋‹ค ๊ฐœ๋ฐœ์ž๊ฐ€ ํ›จ์”ฌ ๋œ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค(์ œ ๊ธฐ์–ต์œผ๋กœ๋Š” /6). npm์—์„œ์˜ ๋‹ค์šด๋กœ๋“œ๋ฅผ ๊ณ ๋ คํ•œ๋‹ค๋ฉด ์Šคํ† ๋ฆฌ๋ถ์„ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜์‘ ์„ ํƒ ๋‹ค์šด๋กœ๋“œ ์ˆ˜(์—„์ฒญ๋‚œ ์ˆ˜)๋ฅผ ์„ ํƒํ•˜์‹ญ์‹œ์˜ค.

@eps1lon ์€ ๋‚ด๊ฐ€ ๋ณด๊ณ  ์žˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค: https://2019.stateofcss.com/technologies/css-in-js/

๋‚ด๊ฐ€ ํ‹€๋ ธ์ง€๋งŒ ๋ถˆํ–‰ํžˆ๋„ ์ด๊ฒƒ์ด ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ์ธ๊ธฐ์žˆ๋Š” ์ฐจํŠธ๋Š” ์•„๋‹ˆ์ง€๋งŒ (๋งค์šฐ ์˜์‹ฌ์Šค๋Ÿฌ์šด ์ฐจํŠธ ๋””์ž์ธ) ์ƒ์Šน ์ถ”์„ธ ๋งŒ ๊ธฐ์–ตํ–ˆ์Šต๋‹ˆ๋‹ค.
image

๊ตฌ์„ฑ ๊ฐ€๋Šฅ

์‹ค์ œ๋กœ TypeScript๊ฐ€ ๋ชจ๋“  JSX ์š”์†Œ๊ฐ€ css ์†Œํ’ˆ์„ ์ง€์›ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๊ฒŒ ํ•˜๋„๋ก Flow๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํŽธ์ง‘ : ๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„ TypeScript์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์ง€๋งŒ Flow์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ฐ€์ง„ ๊ฒƒ ์ค‘ ๊ฐ€์žฅ ๋งŽ์€ ํˆฌํ‘œ๋ฅผ ๋ฐ›์€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ฐธ์กฐ. ํ•œ์ˆจ์„ ์‰ฌ๋‹ค

styled-components ์˜ ์ฃผ์š” ๊ธฐ์—ฌ์ž ์ค‘ ํ•˜๋‚˜์ธ FWIW๋Š” ์œ ํ˜• ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด ๋น„์šฐํ˜ธ์ ์ธ ํƒœ๋„๋ฅผ ๋ณด์ด๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

https://github.com/styled-components/styled-components/issues/3012#issuecomment -583878486

์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ TS/Flow ์‚ฌ์šฉ์ž์˜ ๊ฐœ๋ฐœ ๊ฒฝํ—˜์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค๋ฉด ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ์•„์ด๋””์–ด์— ๋Œ€ํ•ด ํ›จ์”ฌ ๋” ์•ˆ์‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค...

@jedwards1211 ๋„์›€์ด๋œ๋‹ค๋ฉด css ์— ๋Œ€ํ•œ Babel ๋งคํฌ๋กœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ css/scss/less์—์„œ ๋‚˜์˜ค๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์ด "์Šคํƒ€์ผ๋ง๋œ" ๋ฐฉ์‹์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ชฉํ‘œ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์„ฑ๋Šฅ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด ์ผ๋ถ€ ์‹œ์Šคํ…œ์€ ์›์ž CSS๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Tailwinds์—์„œ ์ œ๊ณตํ•˜๋ฏ€๋กœ ํ›จ์”ฌ ๋” ๊นจ๋—ํ•˜๊ณ  ๋นจ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@hc-codersatlas packages/material-ui-benchmark ์—์„œ ๋ช‡ ๊ฐ€์ง€ ๋ฒค์น˜๋งˆํฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@koistya ์ œ๋Œ€๋กœ ์ฝ์œผ๋ฉด ๊ฐ์ •์ด ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋นจ๋ฆฌ ๋ณด์ž…๋‹ˆ๋‹ค.

@oliviertassinari ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹ค์ œ๋กœ ์ด ์„ ํƒ์„ "์„ ํƒ"ํ•ฉ๋‹ˆ๊นŒ? react-select ๋ฐ ์Šคํ† ๋ฆฌ๋ถ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์–ธ๊ธ‰์— ๋”ฐ๋ผ ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๋Š” UI ๊ตฌ์„ฑ ์š”์†Œ์™€ ํ•จ๊ป˜ ๋ฒˆ๋“ค๋กœ ์ œ๊ณต๋˜๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋ฉฐ material-ui๊ฐ€ ํฐ 1์ด ๋ฉ๋‹ˆ๋‹ค. UI ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ด๋ฏธ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ ์™ธ์— ๋‹ค๋ฅธ ์‹œ์Šคํ…œ์œผ๋กœ ๋” ๋งŽ์€ ๋…ธ๋ ฅ์„ ๊ธฐ์šธ์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ UI ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋Œ€๋ถ€๋ถ„์€ ๋Œ€๊ธฐ์—…์—์„œ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์†Œ์ˆ˜์˜ ์‚ฌ๋žŒ๋“ค์ด ์‹ค์ œ๋กœ ์ด "์„ ํƒ"์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๊ทธ๋กœ๋ฐ‹์€ ๋งŽ์€ ํšŒ์‚ฌ๋“ค์ด 1ํฌ์ธํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋˜ styled-components๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋ฉ”๋ชจ์—์„œ npm ๋‹ค์šด๋กœ๋“œ๋Š” ๋ฌด์—‡์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ? ํšŒ์‚ฌ ์‚ฌ์šฉ์€ ๋ฐฉํ™”๋ฒฝ ๋ฐ ๋‚ด๋ถ€ npm ์บ์‹ฑ์„ ์˜๋ฏธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์ด๋Ÿฌํ•œ ๋ฉ”ํŠธ๋ฆญ์„ ์™œ๊ณกํ•ฉ๋‹ˆ๋‹ค.

๋ณ€ํ™”๊ฐ€ ์žˆ๋‹ค๋ฉด ์ธ๊ธฐ๋ณด๋‹ค๋Š” ๊ธฐ์ˆ ์ ์ธ ๋ฉด์—์„œ ๋ฒ ์ŠคํŠธ 1๋กœ ๋ฐ”๊ฟ”์ฃผ์„ธ์š”. ๋‚˜๋Š” material-ui๊ฐ€ ์–ด๋–ค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋“  mui ์ž์ฒด๊ฐ€ ๊ฐ€์žฅ ์ธ๊ธฐ ์žˆ๋Š” ui ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ํ•˜๋‚˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์ธ๊ธฐ ์žˆ๋Š” 1์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ธกํ•ฉ๋‹ˆ๋‹ค.

image

@South-Paw ์ œ์•ˆํ•œ ๋‹จ์ˆœํ™”๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. MuiCardContent ๋Š” ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์ œ์—์„œ ${MuiCardContent} ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

https://styled-components.com/docs/advanced#referring -to-other-components

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ๊ฐœ๋ณ„ HoC ๋ž˜ํผ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ๋™์•ˆ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•œ ํ›„์— JSS๋กœ ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋™์ผํ•œ ์–‘์˜ ํƒ€์ดํ•‘/๋„ค์ด๋ฐ ๊ฒฐ์ •์ด๋ผ๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

@mbrookes @oliviertassinari ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๊ณผ ๋‚ด๋ถ€ ๊ตฌ์„ฑ ์š”์†Œ ์Šคํƒ€์ผ์€ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๊นŒ?
์˜ˆ๋ฅผ ๋“ค์–ด styled-components ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

// conditional class name
<MenuItem classes={{selected: classes.selectedItem}}>...</MenuItem>

// inner component class name
<Dialog classes={{paper: classes.dialogPaper}}>...</Dialog>

styled-components ๋กœ์˜ ์ „ํ™˜ ์•„์ด๋””์–ด์— ๋Œ€ํ•ด ์ง„์ •ํ–ˆ์ง€๋งŒ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ™•์‹คํ•œ ๊ณ„ํš์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. API๊ฐ€ ๋งค์šฐ ๋‹ค๋ฅด๊ฑฐ๋‚˜ ์˜์กดํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. BEM ์Šคํƒ€์ผ ํด๋ž˜์Šค ์ด๋ฆ„์—.

@jedwards1211 ์•„ ์ œ ์‹ค์ˆ˜์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์˜ˆ์ œ ๊ฐ€ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ์ธ ๊ฒฝ์šฐ๋ผ๋Š” ์ธ์ƒ์„ ๋ฐ›์•˜์ง€๋งŒ ์‹ค์ œ๋กœ ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ๐Ÿ‘

@ jedwards1211 clsx ๋Š” ๊ณผ๊ฑฐ์— ์กฐ๊ฑด๋ถ€ ํด๋ž˜์Šค์— ๋Œ€ํ•ด ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ์™€ ์ง์„ ์ด๋ฃจ๋Š” ๊ฒƒ์„ ๋ณธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์ข…๋ฅ˜์˜ ์˜๋ฏธ์ž…๋‹ˆ๊นŒ?

ํ˜„์žฌ ํ•˜๊ณ  ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๋Š” ํ•„์š”์— ๋”ฐ๋ผ MUI ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” styled-components๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ MUI ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

@South-Paw (๋˜๋Š” classnames )๋Š” ์†”๋ฃจ์…˜์˜ ๋‚ด๋ถ€ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด ๋  ์ˆ˜ ์žˆ์ง€๋งŒ styled-components ๋ž˜ํผ๋Š” ๋‹จ์ผ className AFAICT๋งŒ ์ฃผ์ž…ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด ๋ง์€ ์‹ค์ œ๋กœ ์—ฌ๋Ÿฌ ์žฌ์ •์˜ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๊ตฌ์„ฑ ์š”์†Œ์— ์ „๋‹ฌํ•˜๋Š” ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋Œ€์‹  <Dialog Paper={StyledPaper}>...</Dialog> ์™€ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์„ ํƒํ•œ MenuItem ํด๋ž˜์Šค ์˜ˆ์ œ์˜ ๊ฒฝ์šฐ์—๋Š” ๋ฌด์—‡์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

@jedwards1211 ์„ค๋ช…ํ•˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ๋ฌด์—‡์ด๋ฉฐ ๋ฌธ์ œ๊ฐ€ ์–ด๋””์— ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”์ง€ ๋” ์ž˜ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ„๋‹จํ•œ ์˜ˆ๋ฅผ ๋“ค์–ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์†”๋ฃจ์…˜์— ๋Œ€ํ•œ ๋„์›€์„ ๋ฐ›๊ณ  ์‹ถ์ง€๋งŒ ์ด๊ฒƒ์ด ์•„์ง ๋ฌด์—‡์— ์ ์šฉ๋˜๋Š”์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜„

๋„ค, ์˜ค๋Š˜์€ ์‹œ๊ฐ„์ด ์—†์ง€๋งŒ ๋‚ด์ผ์€ ํ• ๊ฒŒ์š”.
๋˜ํ•œ jss-codemorphs ์— ๋Œ€ํ•œ ์ž‘์—…์ด ์ง„ํ–‰ ์ค‘์ด๋ฉฐ, ๊ถ๊ทน์ ์œผ๋กœ ๋ถ™์—ฌ๋„ฃ์€ CSS๋ฅผ JSS๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ VSCode ํ™•์žฅ์„ ๋งŒ๋“ค ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

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

Facebook์ด CSS-in-JS ์†”๋ฃจ์…˜๋„ ์˜คํ”ˆ์†Œ์‹ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฝ์—ˆ๋‹ค๋Š” ์ ์€ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋„ ๋‚˜์™”์„ ๋•Œ ํ•œ ๋ฒˆ ์‚ดํŽด๋ณด๋Š” ๊ฒƒ๋„ ์˜๋ฏธ๊ฐ€ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‹น๋ฉดํ•œ ์‹ค์ œ ์ฃผ์ œ์— ๋Œ€ํ•ด. ๋‚˜๋Š” Typescript ๊ฒฝํ—˜์ด ์ข‹์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— styled-components๋ฅผ ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค. ์œ ํ˜•์€ ์ข…์ข… ๋•๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ํ•ด๋ฅผ ๋ผ์นฉ๋‹ˆ๋‹ค. ๋Š๋ฆฐ ์ปดํŒŒ์ผ ์‹œ๊ฐ„, ๋ฏธ์นœ ์ธํ„ฐํŽ˜์ด์Šค(์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ์ดํ•ดํ•˜๋ ค๋Š” ์‹œ๋„๋Š” ์ค‘์ฒฉ๋œ Pick ๋งˆ๋ฒ•์œผ๋กœ ์ธํ•ด ์•…๋ชฝ์ž…๋‹ˆ๋‹ค). styled-components์— ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ DX๊ฐ€ ์žˆ๋Š” ํ•œ material-ui๊ฐ€ ์ด๋ฅผ ์ฑ„ํƒํ•˜๋Š” ๊ฒƒ์€ ํ•œ ๋ฐœ์ง ๋’ค๋กœ ๋ฌผ๋Ÿฌ๋‚œ ๊ฒƒ์ฒ˜๋Ÿผ ๋Š๊ปด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Facebook์ด CSS-in-JS ์†”๋ฃจ์…˜๋„ ์˜คํ”ˆ์†Œ์‹ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ฝ์—ˆ๋‹ค๋Š” ์ ์€ ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค.

@venikx ๊ทธ๋Ÿด ๊ฐ€๋Šฅ์„ฑ์€ ์–ผ๋งˆ๋‚˜ ๋ฉ๋‹ˆ๊นŒ? ๋‚ด๊ฐ€ ๋งˆ์ง€๋ง‰์œผ๋กœ https://reactpodcast.simplecast.fm/75 ์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•”์‹œํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌด์–ธ๊ฐ€์— ๋Œ€ํ•ด ๋“ค์—ˆ์„ ๋•Œ 5๋…„ ๋™์•ˆ์˜ ๋ชฉํ‘œ์ธ ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

์˜ค ์ •๋ง? ๋‚˜๋Š” ๊ทธ๋“ค์ด ์ด๋ฏธ "ํƒ€์ž„ ๋ผ์ธ"์„ ์ œ๊ณตํ–ˆ๋Š”์ง€ ๋ชฐ๋ž์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์ด์œ ๋กœ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋™์‹œ ๋ชจ๋“œ์™€ ๊ฐ™์€ ์‹œ๊ธฐ์— ์˜ฌ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๋‚˜๋น .

ํ•˜์ง€๋งŒ styled-components์— ๋Œ€ํ•œ ์ œ ์š”์ ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์œ ํšจํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” styled-components๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ์ˆœ์ˆ˜ material-ui์˜ ์Šคํƒ€์ผ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. styled-components์˜ ํƒ€์ดํ•‘์€ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ด์ง€ ๋ฌธ์„œ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

Material-ui api๋Š” ์ˆœ๊ฐ„ ์ •๋ง ๊นจ๋—ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” Typescript ๊ฒฝํ—˜์ด ์ข‹์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— styled-components๋ฅผ ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ง€๊ธˆ๊นŒ์ง€ ์ ์–ด๋„ 4๊ฐœ์˜ ๋Œ€ํ˜• ํ”„๋กœ์ ํŠธ์—์„œ styled-components์™€ Typescript๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ–ˆ์œผ๋ฉฐ ์œ ํ˜•์— ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. - ์†Œ๋น„์ž ์ชฝ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋Š๋ฆฐ ์ปดํŒŒ์ผ ์‹œ๊ฐ„

๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋–ค ํ”„๋กœ์ ํŠธ์—์„œ๋„ ์ด๊ฒƒ์„ ๊ฒฝํ—˜ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”์— ๋Œ€ํ•œ ์˜ˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ฏธ์นœ ์ธํ„ฐํŽ˜์ด์Šค (์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ์ดํ•ดํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” ๊ฒƒ์€ ๋ชจ๋“  ์ค‘์ฒฉ๋œ Pick ๋งˆ๋ฒ•์œผ๋กœ ์ธํ•ด ์•…๋ชฝ์ž…๋‹ˆ๋‹ค)

์–ด๋–ป๊ฒŒ๋“  ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค๋ฉด @types ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌํ•˜๋Š” ๊ฒƒ๋„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๋ณด๋‹ค ๊ฐœ์„ ๋œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๋ชจ๋‘๊ฐ€ ๊ฐ์‚ฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค!

์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ์— ํ•ด๋‹น ๋…ผ๋ฆฌ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค className์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์„ ๋งค์šฐ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค.

styled-components์™€ ํ•จ๊ป˜ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.

const Box = styled.div`
  height: 160px
  width: 160px;
  background-color: black;

  .red {
    background-color: red;
  }
`;

// simple usage
<Box className="red" />

// get more complex with conditionals and using something like clsx (https://www.npmjs.com/package/clsx)
const isRed = true;
<Box className={clsx({ red: isRed })} />

๋‹ค๋ฅธ ์˜๊ฒฌ์„ ์ฃผ์žฅํ•˜๋Š” ์ผ๋ถ€ ๋Œ“๊ธ€์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ƒ์œ„ ๋ฌธ์ œ์—๋Š” 150 ๐Ÿ‘ ๋ฐ 27 ๐ŸŽ‰๊ฐ€ ์žˆ๊ณ  18 ๐Ÿ‘Ž ๋ฐ 9 ๐Ÿ˜•๋งŒ ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ† ๋ก ์„ ์‹ซ์–ดํ•˜๋Š” ๋ชฉ์†Œ๋ฆฌ๊ฐ€ ์†Œ์ˆ˜์ด๊ณ  ๊ธ์ •์ ์ธ ์กฐ์น˜๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๋‹ค์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค ๐Ÿคทโ€โ™‚

@South-Paw ํˆฌํ‘œ์˜ ๋ฌธ์ œ๋Š” ์œ ์ผํ•œ ์„ ํƒ์ด JSS ๋Œ€ styled-components๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ณด์ปฌ ๋ถ€๋ถ„์€ ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ข‹์•„ํ•˜์ง€ ์•Š๊ณ  JSS๋ฅผ ์ข‹์•„ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋งˆ ํˆฌํ‘œํ•˜๋ฉด

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

๋…ผ์Ÿ์˜ ์Šน์ž๋ฅผ ๋ณด๊ธฐ ์œ„ํ•ด ์„œ๋กœ ์‹ธ์šฐ๋Š” ์‚ฌ๋žŒ๋“ค์— ๋Œ€ํ•œ ์†Œ์Œ์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์ฑ„์šฐ์ง€ ์•Š๋Š” Spectrum ์ฑ„ํŒ…์ด๋‚˜ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ•ต์‹ฌ ํŒ€์—์„œ ์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ํ† ๋ก ์„ ์œ„ํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ํŒ”๋กœ์šฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌํŒ€์˜ ํŒ๋‹จ์„ ๊ณผ์†Œํ‰๊ฐ€ํ•˜๊ณ  ๊ณ„์‹  ๊ฒƒ ๊ฐ™์€๋ฐ, ๊ฐœ์ธ์ ์œผ๋กœ ์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ๋…ผ์Ÿ์€ ๊ทธ๋งŒํ•˜๊ณ  ํ•ต์‹ฌํŒ€์„ ๋” ๋ฏฟ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ๋จธํ‹ฐ๋ฆฌ์–ผ UI์˜ ๋ฐฉํ–ฅ์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์€ ์ฝ”์–ด ํŒ€์˜ ๋ชซ์ž…๋‹ˆ๋‹ค.

๋งŒ์•ฝ ๋‹น์‹ ์ด ์ •๋ง๋กœ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๊ฐ•ํ•œ ์˜๊ฒฌ์„ ๊ฐ–๊ณ  ์žˆ๋‹ค๋ฉด, Material UI๋Š” ๋†€๋ž๊ฒŒ๋„ MIT ๋ผ์ด์„ ์Šค๋ฅผ ๋ฐ›์•˜๊ณ , ๊ทธ๊ฒƒ์„ ํฌํฌํ•˜๊ณ , ๋‹น์‹ ์ด ๊ฐ€์ง„ ๋น„์ „์„ ๊ณ„์† ์œ ์ง€ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๊ธฐ๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์šฐ๋ฆฌ๋Š” ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์—์„œ ๋ฏธ๋ž˜์— ๋ฐฐ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ์ œ๋ฐœ, ํ•ต์‹ฌ ํŒ€์ด ๊ทธ๋“ค์˜ ์ผ์„ ํ•˜๊ฒŒ ํ•˜๊ณ , ๊ทธ๋“ค์„ ๋ฏฟ์œผ์‹ญ์‹œ์˜ค. ๊ทธ๋“ค์€ ๋†€๋ผ์šด ๊ธฐ์ˆ ์„ ๊ฐ€์ง„ ์ •๋ง ์œ ๋Šฅํ•œ ์‚ฌ๋žŒ๋“ค์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ๋ณผ ์ˆ˜์žˆ๋Š” ์•„๋ฆ„๋‹ค์šด ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค

image

๊ฒฐ๊ตญ JSS๋ณด๋‹ค ๋‚˜์€ ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฑด ์˜ค๋ž˜ ๋ฌ์–ด.

@hc-codersatlas old == ์„ฑ์ˆ™ํ•œ -- ๊ทธ๊ฒƒ์ด ์™œ ๋ฌธ์ œ์ธ์ง€ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์ข‹์•„, ๋œจ๊ฑฐ์šด ๋ฌธ์ œ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๋ˆ„๊ตฐ๊ฐ€ ์ด ๊ฐ„๋‹จํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•ด ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํ˜„์žฌ Mui ๋ฒ„์ „(4 ๋˜๋Š” 5)์—์„œ CSS์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋œ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด๊ณผ ํ•จ๊ป˜ styled-components ์™€ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ?
์ด ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ์˜ˆ ๋˜๋Š” ์•„๋‹ˆ์˜ค ๋Œ€๋‹ต์„ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ๊ธฐ๋ณธ ๊ธฐ์ˆ ์— ๋Œ€ํ•ด์„œ๋Š” ๋ณ„๋กœ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๊ณ  ๊ฐœ๋ฐœ์ž์˜ ํŽธ์˜์—๋งŒ ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. InVision์—์„œ CSS๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ๋Š” ๊ฒƒ์€ ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

https://material-ui.com/guides/interoperability/

JSS๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๋ฐฉ๊ธˆ ๋งค์šฐ ํฌ๊ด„์ ์ธ CSS์—์„œ JSS๋กœ์˜ ๋ณ€ํ™˜๊ธฐ ๊ตฌํ˜„์„ ๋งˆ์ณค์Šต๋‹ˆ๋‹ค.

CSS๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ JSS ์Šคํƒ€์ผ์— ๋ถ™์—ฌ๋„ฃ๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์—†๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@jedwards1211 ์ด๊ฑฐ ๋ด
https://css2js.dotenv.dev/

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

์ด ๋‹ต๋ณ€์„ ์–ด๋”˜๊ฐ€์—์„œ ๋†“์ณค์„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์–ด์จŒ๋“  ๊ทธ๊ฒƒ์„ ๋†’์ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. Material UI ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๊ณ  ์Šคํƒ€์ผ๋ง ์†”๋ฃจ์…˜( less vs makeStyles vs styled-components )์„ ํ‰๊ฐ€ํ•˜๋Š” ์ค‘์ด๋ฉฐ ๋Œ€๋ถ€๋ถ„์˜ ์Šคํƒ€์ผ๋ง์€ ๋‹ค์Œ์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ๊ณผ ๋Œ€๋ถ€๋ถ„์˜ ์ƒˆ๋กœ์šด MUI ์ฝ”๋“œ๋Š” makeStyles ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช…ํ™•ํžˆ ์•Œ๊ณ  ์‹ถ์€ ๊ฒƒ์€ ์ด๊ฒƒ์ด v5์˜ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์Šคํƒ€์ผ๋ง๊ณผ ๊ด€๋ จ๋œ ๊ธฐ์ˆ ์ ์ธ ๋ถ€์ฑ„๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

  1. v5์— makeStyles ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? styled-components ๋ฐ ํ…Œ๋งˆ์™€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด styled-components ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
const useStyles = makeStyles((theme) => ({
  paper: {
    padding: theme.spacing(2),
    textAlign: 'center',
    color: theme.palette.text.secondary,
  },
}));
  1. (v4) ์ด๋ณด๋‹ค ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด์—์„œ theme ๊ฐœ์ฒด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฏ€๋กœ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
const StyledContainer = styled.div`
  color: ${({ theme }) => theme.palette.primary.main};
  padding: ${({ theme }) => theme.spacing(1)};
  background-color: ${({ theme }) => theme.palette.background.paper};
`;
  1. makeStyles ๊ฐ€ v5์— ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋Œ€๊ทœ๋ชจ ์ฝ”๋“œ๋ฒ ์ด์Šค์— ๋Œ€ํ•ด styled-components ํ…Œ๋งˆ ์ œ๊ณต์ž์™€ Material UI ํ…Œ๋งˆ ์ œ๊ณต์ž๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์˜ˆ์ƒํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

Material UI ์‚ฌ์šฉ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ˆ˜๊ณ ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

@egilsster

  1. ์˜ˆ, @material-ui/styles ๋˜๋Š” react-jss์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ์˜ˆ https://material-ui.com/guides/interoperability/#theme ,
const StyledContainer = styled.div`
  ${({ theme }) => `
  color: ${theme.palette.primary.main};
  padding: ${theme.spacing(1)};
  background-color: ${theme.palette.background.paper};
  `}
`;
  1. ์ฃผ์š” ๋ฌธ์ œ๋Š” 1. ๊ตฌ์„ฑ ์˜ค๋ฒ„ํ—ค๋“œ, 1ํšŒ ๋น„์šฉ, 2. Sentry๋ฅผ ํฌํ•จํ•˜์—ฌ ~15kB gzipped ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์žˆ๋Š” ๋‘ ๊ฐœ์˜ CSS-in-JS ๋Ÿฐํƒ€์ž„ ๋กœ๋“œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Sentry: https://bundlephobia.com /result?p=@sentry/browser.

๋น ๋ฅธ ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

  1. ์˜ˆ material-ui.com/guides/interoperability/#theme

์ด๊ฒƒ์€ ๊ฝค ๋ฉ‹์ง€๋‹ค. ๋„๊ตฌ์— ๋Œ€ํ•œ ์ผ๋ถ€ ์ž‘์—…์€ ์•„๋งˆ๋„ ์ด๊ฒƒ์„ ๋”ฐ๋ฅผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋Š” TS๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์ง€๋งŒ VSCode/์–ธ์–ด ์„œ๋ฒ„๋Š” ์ด ๊ฒฝ์šฐ theme ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ „ํ˜€ ๋ชจ๋ฅด๋Š” ๊ฒƒ ๊ฐ™๊ณ  styled-components ๋ฅผ ์žƒ์Šต๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ ๊ฐ•์กฐ๋„.

๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐœ๋ฐœ์„ ๊ณ„์†ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@oliviertassinari ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์žˆ๋Š” ๊ฒฝ์šฐ <ListItem classes={{ selected: myCustomClassName}}> ์™€ ๊ฐ™์€ CSS API์— ๋” ์ด์ƒ ์˜์กดํ•  ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

@jedwards1211 classes API๋Š” ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

๊ดœ์ฐฎ์•„. styled-components๋Š” ๋ฃจํŠธ ์š”์†Œ์— ๋‹จ์ผ ํด๋ž˜์Šค๋งŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— MUI๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ styled-components๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์•ฝ๊ฐ„ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

const MyRoot = styled('div')`
  // some nice styles
`;

const MyAwesomeChild = styled('div')`
  // some nice styles
`;

export function AwesomeRoot(props) {
  return (
    <MyRoot className={props.classes?.root}>
      <MyAwesomeChild className={props.classes?.child}/>
      {props.children}
    </MyRoot>
  );
}

@jedwards1211 ์ด ๋ง์ด ๋˜๋‚˜์š”?

@yordis ๊ฐ„๋‹จํ•ด ๋ณด์ด์ง€๋งŒ https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Button/Button.js ์™€ ๊ฐ™์€ ๋ณตํ•ฉ ์„ ํƒ๊ธฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฆฌํŒฉํ† ๋งํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

styled-components ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ธฐ์กด ๋™์ž‘์„ ๋ณด์กดํ•  ๋ฐฉ๋ฒ•์ด ์ƒ๊ฐ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ๋žŒ๋“ค์ด ์˜ˆ์ƒํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋งŽ์€ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  outlined: {
    '&$disabled': {
      border: `1px solid ${theme.palette.action.disabledBackground}`,
    },
  },

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

์•„๋งˆ๋„ ์ด๊ฒƒ์€? ์ด๊ฒƒ์ด ๋‚˜์—๊ฒŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋Š๊ปด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋ผ๊ฐˆ์ง€ ํ™•์‹ ์ด ์„œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ผ๋ถ€ ์ปจํ…์ŠคํŠธ ๋ฐ/๋˜๋Š” ์ •๋ณด๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

const MyOutlinedComponent = styled('div')`
  ${props.disabled && `
      border: `1px solid ${({ theme }) => theme.palette.action.disabledBackground}`,
  `}
`;

<MyOutlinedComponent disabled/>

@yordis ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด ์‚ฌ๋žŒ๋“ค์€ ์ด๊ฒƒ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ดˆ๋ž˜ํ•  ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์ €๋Š” ๊ทธ ์˜ˆ๊ฐ€ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐฉ์ง€ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‹ค์ œ ์‚ฌ๋ก€์™€ ์‹ค์ œ ์ž ์žฌ์ ์ธ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ณต์œ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

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

@oliviertassinari ํ…Œ๋งˆ ์žฌ์ •์˜๊ฐ€ v5์—์„œ ์ˆ˜์ • ์—†์ด ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? ๋‹ค์Œ ์žฌ์ •์˜ ์˜ˆ์ œ๊ฐ€ ์ž‘๋™ํ•˜๋ ค๋ฉด MUI๊ฐ€ styled-components ์ƒ์„ฑ ๋ฃจํŠธ ํด๋ž˜์Šค ์ด๋ฆ„ ์™ธ์— JSS ์ƒ์„ฑ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

const theme = createMuiTheme({
  overrides: {
    MuiButton: {
      root: {
        '&$disabled': {
          color: myCustomColor,
        },
      },
    },
  },
});

@yordis ๋Š” ๋” ์ƒ๊ฐํ•ด ๋ณธ ๊ฒฐ๊ณผ classes prop์„ ํ†ตํ•ด ์ „๋‹ฌ๋œ ์Šคํƒ€์ผ์— ๋Œ€ํ•œ ๋ณตํ•ฉ ์„ ํƒ๊ธฐ๊ฐ€ ์šด ์ข‹๊ฒŒ๋„ ์—ฌ์ „ํžˆ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. ํ…Œ๋งˆ ์žฌ์ •์˜ ์Šคํƒ€์ผ์— ๋Œ€ํ•ด์„œ๋Š” ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

style={object}์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ์ผ๋ฐ˜ MUI์™€ ํ•จ๊ป˜ MUI๋ฅผ ํ†ตํ•ด ๋‘ ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ์จ์„ ๋ˆ„๋ ธ์Šต๋‹ˆ๋‹ค.

๊ฐ๊ฐ ๋ฏธ๋””์–ด ์บ๋Ÿฌ์…€, ์ •๋ณด, ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ, ๋ฒ„ํŠผ ๋“ฑ์ด ์žˆ๋Š” 50๊ฐœ์˜ ์นด๋“œ๊ฐ€ ํฌํ•จ๋œ ๊ฒฐ๊ณผ ๋ชฉ๋ก ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ Œ๋”๋ง ์‹œ๊ฐ„์— ๊ฑฐ์˜ 0.5์ดˆ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. const useStyles = makeStyles ๋˜๋Š” style={object}์— ๋น„ํ•ด.

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

@Icehunter ์‚ฌ๋žŒ๋“ค์ด ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๊ฒฐ๊ณผ์™€ ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ๋ฅผ ์˜จ๋ผ์ธ์— ๊ฒŒ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@Icehunter ์‚ฌ๋žŒ๋“ค์ด ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๊ฒฐ๊ณผ์™€ ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ๋ฅผ ์˜จ๋ผ์ธ์— ๊ฒŒ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

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

๊ฐ๊ฐ ๋ฏธ๋””์–ด ์บ๋Ÿฌ์…€, ์ •๋ณด, ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ, ๋ฒ„ํŠผ ๋“ฑ์ด ์žˆ๋Š” 50๊ฐœ์˜ ์นด๋“œ๊ฐ€ ํฌํ•จ๋œ ๊ฒฐ๊ณผ ๋ชฉ๋ก ํŽ˜์ด์ง€๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

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

styled() / styled.div API๋Š” _๋ชจ๋“ _ ์š”์†Œ์˜ ๋ Œ๋”๋ง์— ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฏ€๋กœ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์บ์‹ฑํ•˜๋”๋ผ๋„ ์†๋„๊ฐ€ ๋Š๋ ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. makeStyles ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํƒ€์ผ ๊ทธ๋ฃน์„ ํ•œ ๋ฒˆ ์ฒจ๋ถ€ํ•œ ๋‹ค์Œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ˆ˜๋™์œผ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ข…์ข… ํ›จ์”ฌ ๋” ๋น ๋ฆ…๋‹ˆ๋‹ค.

์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ styled ์— ์˜์กดํ•˜๋Š” ์†”๋ฃจ์…˜์ด MUI makeStyles ๋ณด๋‹ค 3-4๋ฐฐ ๋Š๋ฆด ์ˆ˜ ์žˆ์Œ์„ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด CodeSandbox ์˜ˆ์ œ ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.
image

styled API๋Š” ํŽธ์˜์ƒ ํ›Œ๋ฅญํ•˜์ง€๋งŒ ๋ชฉ๋ก/ํ…Œ์ด๋ธ”์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋  ๋•Œ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” @Icehunter ์˜ ์˜๊ฒฌ์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. makeStyles ์„ ๋ฐฑ์—…์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

@schnerd ์ด๋Ÿฌํ•œ ์˜ˆ๋ฅผ ์กฐํ•ฉํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์ œ๋Š” ์šฐ๋ ค ์‚ฌํ•ญ์„ ์ •๋ง ์ž˜ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ๊ฒŒ์‹œ๋ฌผ ์•ž์— "๋ณด๊ธฐ๊ฐ€ ์–ด๋ ต์ง€ ์•Š์Šต๋‹ˆ๋‹ค..."๋Š” ์ผ์ข…์˜ ๊ฒฝ๋ฉธ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‹ค๋ฅธ ํ›Œ๋ฅญํ•œ ์˜ˆ์— ์‹ค์ œ๋กœ ์ถ”๊ฐ€๋˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค.

@tuxracer ์‚ฌ๊ณผ โ€“ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@Icehunter ๋ฌด์Šจ ๋ง์ธ์ง€ ์ดํ•ด๊ฐ€ ์•ˆ ๊ฐ€๋Š”๋ฐ SC๋‚˜ JSS์—์„œ ๊ณตํ†ต ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•˜์…จ๋‚˜์š”?

@Icehunter ๋ฌด์Šจ ๋ง์ธ์ง€ ์ดํ•ด๊ฐ€ ์•ˆ ๊ฐ€๋Š”๋ฐ SC๋‚˜ JSS์—์„œ ๊ณตํ†ต ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•˜์…จ๋‚˜์š”?

๋‘˜ ๋‹ค ์‚ฌ์‹ค. ์šฐ๋ฆฌ๋Š” ๊ฒฐ๊ตญ makeStyles๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ styled={object}๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋™์ผํ•œ ์„ฑ๋Šฅ ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

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

ํ˜„๋ช…ํ•œ ์Šคํƒ์€ nextjs๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ช…ํ™•ํ•˜๊ฒŒ(ํŽธ์ง‘):

SC๋ฅผ ์˜๋„ํ•œ ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์—ฌ mui ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ž˜ํ•‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ๋Š๋ฆฌ๊ฒŒ ๋ฐํ˜€์กŒ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ณต์œ  ํŒŒ์ผ ์„ค์ •์—์„œ makeStyles ๋ฐ/๋˜๋Š” style={object} ๋ฐ ๋กœ์ปฌ(์‹œ๋ฎฌ๋ ˆ์ดํŠธ๋œ ๊ณ„๋‹จ์‹)์„ ์‚ฌ์šฉํ•˜์—ฌ mui ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ํ›จ์”ฌ ๋” ๋น ๋ฆ…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ์•„์ด๋””์–ด๋ฅผ ์ „ํ˜€ ์ฐจ๋‹จํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ๋ณธ๊ฐ’์ธ ๊ฒฝ์šฐ; ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ „์—ญ์ ์œผ๋กœ ํ•˜ํ–ฅ์‹ ๊ธฐ๋ณธ ์„ ํƒ์„ ์žฌ์ •์˜ํ•˜๊ณ  ์ž์ฒด์ ์œผ๋กœ dep ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ์ด๊ฒƒ์€? ์ด๊ฒƒ์ด ๋‚˜์—๊ฒŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋Š๊ปด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋ผ๊ฐˆ์ง€ ํ™•์‹ ์ด ์„œ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ผ๋ถ€ ์ปจํ…์ŠคํŠธ ๋ฐ/๋˜๋Š” ์ •๋ณด๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

const MyOutlinedComponent = styled('div')`
  ${props.disabled && `
      border: `1px solid ${({ theme }) => theme.palette.action.disabledBackground}`,
  `}
`;

<MyOutlinedComponent disabled/>

์ด ๊ฒŒ์ž„์— ๋Šฆ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ @jedwards1211 ์€ ์ด๊ฒƒ์„ SC๋กœ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. https://codesandbox.io/s/magical-snow-5bzd8

๋‚˜๋Š” ๋‚ด ์ž์‹ ์ด ์–ด๋–ค ๊ณณ์—์„œ ์ด๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๋‚ ์ด ์˜ค๋ฉด v5๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ„๋‹จํ•˜๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‚ฌ์‹ค ์Šคํƒ€์ผ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด์™€ ๊ฐ™์€ ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋จธํ‹ฐ๋ฆฌ์–ผ UI๊ฐ€ ๋ฏธ๋ž˜์— Typography ์˜ ๊ธฐ๋ณธ ๋ณ€ํ˜• ์žฌ์ •์˜๋ฅผ ์ง€์›ํ•œ๋‹ค๋ฉด JSS๊ฐ€ styled-components๋ณด๋‹ค ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@heb-mm ์—ฌ๊ธฐ์— @oliviertassinari ๊ฐ€ 3์›” 7์ผ์— ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์–ธ๊ธ‰ํ•œ ์ž์„ธํ•œ RFC ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„๋กœ ์Šคํฌ๋กคํ•˜์—ฌ ์–ธ๊ธ‰์„ ๋ณด๋Š” ๋ฐ 1๋ถ„ ๋ฏธ๋งŒ์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.

ํŽธ์ง‘: ๊ถ๊ธˆํ•˜์‹  ๋ถ„๋“ค์„ ์œ„ํ•ด heb-mm์ด ์ง€๊ธˆ ๋Œ“๊ธ€์„ ์‚ญ์ œํ–ˆ์Šต๋‹ˆ๋‹ค.

์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ styled ์— ์˜์กดํ•˜๋Š” ์†”๋ฃจ์…˜์ด MUI makeStyles ๋ณด๋‹ค 3-4๋ฐฐ ๋Š๋ฆด ์ˆ˜ ์žˆ์Œ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด CodeSandbox ์˜ˆ์ œ ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

@schnerd styled-components ๋ฅผ ๋ชจ๋ฐฉํ•ด์•ผ ํ•˜๋Š” Material-UI inhouse styled API๋ฅผ ํฌํ•จํ•˜๋„๋ก ๋ฒค์น˜๋งˆํฌ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์˜ต์…˜์— ๋น„ํ•ด ์—„์ฒญ๋‚˜๊ฒŒ ๋Š๋ฆฐ ๊ฒƒ์„ ๋ณด๊ณ  ๋†€๋ž์Šต๋‹ˆ๋‹ค. https://codesandbox.io/s/css-in-js-comparison-ljtjz?file=/src/App.js ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

image

@emotion/styled (๊ธฐ๋ณธ์ ์œผ๋กœ styled-component์™€ ๋™์ผํ•œ API๋ฅผ ๊ฐ€์ง)๊ฐ€ ๋˜‘๊ฐ™์ด ๋Š๋ฆด์ง€ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ตฌํ˜„์— ๋Œ€ํ•ด ๋” ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

@emotion/styled (๊ธฐ๋ณธ์ ์œผ๋กœ styled-component์™€ ๋™์ผํ•œ API๋ฅผ ๊ฐ€์ง)๊ฐ€ ๋˜‘๊ฐ™์ด ๋Š๋ฆด์ง€ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ตฌํ˜„์— ๋Œ€ํ•ด ๋” ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

https://codesandbox.io/s/css-in-js-comparison-sej1m

image

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

ํ , ์ด๊ฒƒ์€ MUI๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ณ„ํš์— ์ƒ๋‹นํ•œ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ˜„์žฌ CSS, ํ…Œ๋งˆ ๋ฐ ์„ฑ๋Šฅ์„ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ๋งŽ์€ ๋ฌธ์ œ๋ฅผ ๊ฒช์€ ํ›„ Material UI ์Šคํƒ€์ผ๋ง ์‹œ์Šคํ…œ์„ ์œ„ํ•ด styled-components ์—์„œ ๋ฉ€์–ด์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. styled components ์ฒ˜์Œ์—๋Š” ๊ดœ์ฐฎ์•˜๊ณ  ๊ทธ ์œ„์— ์ž์ฒด ํ…Œ๋งˆ ์†”๋ฃจ์…˜์„ ๊ตฌ์ถ•ํ–ˆ์ง€๋งŒ UI๊ฐ€ ์ปค์ง€๋ฉด์„œ CSS๋„ ์ปค์กŒ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์ธ๋ผ์ธ CSS ๋ฌธ์ž์—ด ๋Œ€์‹  JS ๊ฐœ์ฒด๋ฅผ ์‰ฝ๊ฒŒ ๋ฆฌํŒฉํ† ๋งํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ํฐ ์žฅ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜•

๊ทธ๋ž˜์„œ ์ €๋Š” Material UI๋ฅผ ์ฒ˜์Œ ์ ‘ํ–ˆ๊ณ  v5์˜ ์•ŒํŒŒ ๋ฆด๋ฆฌ์Šค๋„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. @ ldiego08 ๋‹น์‹ ์€ ๋งํ–ˆ๋‹ค :

์šฐ๋ฆฌ๋Š” ํ˜„์žฌ Material UI ์Šคํƒ€์ผ๋ง ์‹œ์Šคํ…œ์„ ์œ„ํ•ด styled-components์—์„œ ๋ฉ€์–ด์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ˜์‘์œผ๋กœ ์ž‘์—…ํ•  ๋•Œ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋จธํ‹ฐ๋ฆฌ์–ผ UI ์Šคํƒ€์ผ๋ง ์‹œ์Šคํ…œ์ด๋ž€ ๋ฌด์—‡์ด๋ฉฐ, ์•ž์œผ๋กœ ๋จธํ‹ฐ๋ฆฌ์–ผ UI์—์„œ ์Šคํƒ€์ผ๊ณผ CSS๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ถŒ์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ธ๊ฐ€์š”? ๋‚˜๋Š” ์ด ํŽ˜์ด์ง€๋ฅผ ์ฝ์—ˆ๊ณ  CSS-IN-JS์— ์ฐฌ์„ฑํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: https://material-ui.com/system/basics/. ์ €๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ์ฒด ๊ตฌ๋ฌธ์ด ์•„๋‹Œ CSS๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๋ฉฐ "์ผ๋ฐ˜ CSS ๊ตฌ๋ฌธ"์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— CSS-IN-JS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ์„ ๋ˆ„๋ ธ์ง€๋งŒ ์†์— JS์˜ ํž˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

styled-components API๊ฐ€ ์™œ ๊ทธ๋ ‡๊ฒŒ ์ธ๊ธฐ๊ฐ€ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋” ๋Š๋ฆฌ๋ฏ€๋กœ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹  ๋ชจ๋“  ๊ฒƒ์„ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ž˜ํ•‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋œ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ์ž์—ด๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋‚ซ๊ธฐ ๋•Œ๋ฌธ์— CSS ํŒŒ์ผ์— CSS๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. :D ๊ฐ์ฒด ๊ตฌ๋ฌธ์€ ๊ตฌ์„ฑ ๋ฐ ๋ฆฌํŒฉํ† ๋ง ๋“ฑ์˜ ๊ฒฝ์šฐ ํ›จ์”ฌ ๋” ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์ €์—๊ฒŒ๋Š” CSS ๊ฐ์ฒด๋ฅผ ์ทจํ•˜๊ณ  ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ‰๋ฒ”ํ•œ ๊ฐ์ • css ๋ฐ cx ํ•จ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ API์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹จ์ˆœํžˆ ๊ฐ์ •์ด ํฌํ•จ๋œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ƒ์„ฑํ•˜๊ณ  ํด๋ž˜์Šค API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์™œ "๋” ํŽธ๋ฆฌํ•œ ๊ฐœ๋ฐœ์ž API"๋ฅผ ์œ„ํ•ด ์„ฑ๋Šฅ๊ณผ ์œ ์—ฐ์„ฑ์„ ๊ตํ™˜ํ•˜๋Š”์ง€ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(์–ด๋–ค ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ๋”์ฐํ•œ API์ž…๋‹ˆ๋‹ค).

styled-components API๊ฐ€ ์™œ ๊ทธ๋ ‡๊ฒŒ ์ธ๊ธฐ๊ฐ€ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋” ๋Š๋ฆฌ๋ฏ€๋กœ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹  ๋ชจ๋“  ๊ฒƒ์„ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ž˜ํ•‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋œ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ์ž์—ด๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋‚ซ๊ธฐ ๋•Œ๋ฌธ์— CSS ํŒŒ์ผ์— CSS๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. :D ๊ฐ์ฒด ๊ตฌ๋ฌธ์€ ๊ตฌ์„ฑ ๋ฐ ๋ฆฌํŒฉํ† ๋ง ๋“ฑ์˜ ๊ฒฝ์šฐ ํ›จ์”ฌ ๋” ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์ €์—๊ฒŒ๋Š” CSS ๊ฐ์ฒด๋ฅผ ์ทจํ•˜๊ณ  ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ‰๋ฒ”ํ•œ ๊ฐ์ • css ๋ฐ cx ํ•จ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ API์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹จ์ˆœํžˆ ๊ฐ์ •์ด ํฌํ•จ๋œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ƒ์„ฑํ•˜๊ณ  ํด๋ž˜์Šค API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์™œ "๋” ํŽธ๋ฆฌํ•œ ๊ฐœ๋ฐœ์ž API"๋ฅผ ์œ„ํ•ด ์„ฑ๋Šฅ๊ณผ ์œ ์—ฐ์„ฑ์„ ๊ตํ™˜ํ•˜๋Š”์ง€ ์ดํ•ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(์–ด๋–ค ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋Š” ๋”์ฐํ•œ API์ž…๋‹ˆ๋‹ค).

๋‚˜๋Š” ๊ฐ™์€ ์šฐ๋ ค๋ฅผ ๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค :) ์•„๋งˆ๋„ ์ƒํ™ฉ์ด ์กฐ๊ธˆ ์ •๋ฆฌ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
https://github.com/mui-org/material-ui/issues/6115#issuecomment -580449539

@martinjlowm ๋„ค, ์šฐ๋ฆฌ๋Š” ๊ฐ™์€ ํŽ˜์ด์ง€์— ์žˆ์Šต๋‹ˆ๋‹ค :) ๋จธํ‹ฐ๋ฆฌ์–ผ UI ํŒ€์œผ๋กœ ๊ฐ€๋Š” ๊ฐ€์žฅ ํ˜„๋ช…ํ•œ ๋ฐฉ๋ฒ•์€ ์ผ์ข…์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ฐ€๋Šฅํ•œ ์†”๋ฃจ์…˜์„ ๊ตฌํ˜„ํ•˜๊ณ  js ์†”๋ฃจ์…˜์˜ CSS์™€ ๊ฒฐํ•ฉํ•˜์ง€ ์•Š๊ณ  ์‚ฌ๋žŒ๋“ค์ด ๋ฌด์—‡์„ ์‚ฌ์šฉํ• ์ง€ ์„ ํƒํ•˜๊ฒŒ ํ•˜๊ณ  ๊ทธ๋Ÿฐ ์‹์œผ๋กœ ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์ €์žฅํ•˜์‹ญ์‹œ์˜ค. ๋˜ํ•œ ํด๋ž˜์Šค์™€ createMuiTheme API๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ €์—๊ฒŒ js์˜ css๋Š” ๊ตฌ์„ฑ ์š”์†Œ ์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ์†์‰ฌ์šด ๋™์  ์Šคํƒ€์ผ, CSS ๋˜๋Š” ์ „์ฒด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ๋•Œ์˜ ์ž์‹ ๊ฐ(๊ฐ์ฒด ์ ‘๊ทผ ๋ฐฉ์‹์ด ์šฐ์ˆ˜ํ•œ ๊ณณ), ์„ฑ๋Šฅ(์™ธ๋ถ€ ์Šคํƒ€์ผ์‹œํŠธ์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์Šคํƒ€์ผ์„ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ์•Š์Œ)์— ๊ด€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. , ๋“ฑ๋“ฑ. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ, ๋‚˜๋Š” ์™œ ์‚ฌ๋žŒ๋“ค์ด ์ผ๋ถ€ ํŽธ์ง‘๊ธฐ ๊ฐ•์กฐ ํ‘œ์‹œ์™€ ํ•จ๊ป˜ ๋ฌธ์ž์—ด์„ ์“ฐ๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ปจํ…์ŠคํŠธ์—์„œ props์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ${}๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ๊ฒฝ od div ์š”์†Œ๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋ณต์žกํ•œ ๊ฒฝ์šฐ ๊ทธ ์ ‘๊ทผ ๋ฐฉ์‹์€ ์ง€์ €๋ถ„ํ•˜๊ณ  ๋‚ด ์˜๊ฒฌ์œผ๋กœ๋Š” ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๊ฐ•ํƒ€ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‹จ์ง€ ๋‚ด ์ƒ๊ฐ์„ ๋งํ•˜๊ณ  ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๊ฐ€ ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ข‹์•„ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์ฆ๋ช…ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๊ทธ๋ ‡๋‹ค๊ณ  ํ•˜๋”๋ผ๋„ ์„ฑ๋Šฅ๊ณผ ์œ ์—ฐ์„ฑ์„ ๊ตํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์ข‹์€ ๊ฑฐ๋ž˜์ธ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. :)

@vdjurdjevic ์‹ค์ œ๋กœ js ์†”๋ฃจ์…˜์—์„œ material-ui๋ฅผ ํ•˜๋‚˜์˜ css์— ๊ฒฐํ•ฉํ•˜๋Š” ๊ฒƒ์€ css-in-js ๊ด€ํ–‰์ด ๋ถˆ๊ฐ€ํ”ผํ•˜๊ฒŒ ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์œผ๋กœ ์„ฑ์žฅํ•  ๋•Œ ์ถฉ๋Œ์— ๋Œ€ํ•œ ๊ฑฐ์˜ ๋ณด์žฅ๋œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

ํŠน์ • css-in-js ๊ณต๊ธ‰์ž๋กœ ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ ํŒจํ„ด์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ์Šคํƒ€์ผ ์ž์ฒด๋Š” material-ui ํŒจํ‚ค์ง€ ๋‚ด์—์„œ ์ผ๊ด€๋œ ํ˜•์‹์œผ๋กœ ์ •์˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ์–ด๋Œ‘ํ„ฐ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์ˆ˜ํ–‰๋˜๋Š” ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

import {EmotionAdapter, StyledComponentAdapter, ThemeProvider} from "@material-ui/core/styles";
...
return 
    (<ThemeProvider theme={theme} adapter={EmotionAdapter}>
        ...
    </ThemeProvider>)

@vdjurdjevic https://github.com/mui-org/material-ui/issues/6115#issuecomment -652762320์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์ƒ๊ฐ์— ๊ฑฐ์˜ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์ตœ๊ทผ์— https://github.com/mui-org/material-ui/issues/16947#issuecomment -653797178์—์„œ ๊ณต์œ ํ•œ ๋ฐฉํ–ฅ์— ๋Œ€ํ•œ ์š”์•ฝ์ด ๋งˆ์Œ์— ๋“œ์‹ค ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์™œ ์‚ฌ๋žŒ๋“ค์ด ์ผ๋ถ€ ํŽธ์ง‘๊ธฐ ๊ฐ•์กฐ ํ‘œ์‹œ๋กœ ๋ฌธ์ž์—ด ์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ๊ด€์ ์—์„œ ๋ช‡ ๊ฐ€์ง€ ์ด์œ :

  • React.createElement('div', {}) ๋ฅผ ์“ฐ์ง€ ์•Š๋Š” ์ด์œ ์— ๊ฐ€๊น์Šต๋‹ˆ๋‹ค.
  • ์›น ๊ฐœ๋ฐœ ๊ฒฝํ—˜์ด ์ œํ•œ์ ์ธ ์‚ฌ๋žŒ๋“ค(๋งŽ์Œ)์€ JavaScript API๋ฅผ ๋ฐฐ์šฐ๋Š” ๋ฐ ์–ด๋ ค์›€์„ ๊ฒช์Šต๋‹ˆ๋‹ค. CSS ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค. ๋””์ž์ด๋„ˆ๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด ํŒ€์›๋“ค์—๊ฒŒ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜๋Š”์ง€ ๋ฌผ์–ด๋ณด์„ธ์š”. :)
  • ๊ฐœ๋ฐœ ๋„๊ตฌ์™€ ์†Œ์Šค ๊ฐ„์— ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(๋‚˜๋Š” ์ด๊ฒƒ์„ ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค).

@oliviertassinari ์ข‹์•„, ์ด๊ฒƒ๋“ค์€ ๋ช‡ ๊ฐ€์ง€ ํ™•์‹คํ•œ ์š”์ ์ž…๋‹ˆ๋‹ค. ์ €๋„ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. :) ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ์ €์—๊ฒŒ(๋””์ž์ด๋„ˆ, ์ดˆ์‹ฌ์ž, ์„ ์ž„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹˜) ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ์™€ ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋œ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด์€ ์ ˆ๋Œ€ ์„ ํƒ ์‚ฌํ•ญ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ๊ฐœ๋ฐœ ๋ฐฉํ–ฅ์— ๋Œ€ํ•œ ์š”์•ฝ์„ ์ฝ์—ˆ์œผ๋ฉฐ CSS ์—”์ง„์ด ์„ ํƒ ์‚ฌํ•ญ์ด๋ผ๋Š” ์†Œ์‹์„ ๋“ฃ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ styled-components๋ฅผ ๊ธฐ๋ณธ๊ฐ’(๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๊ฐ€ ์ข‹์•„ํ•˜๋Š” ๊ฒฝ์šฐ)์œผ๋กœ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์†”์งํžˆ ๋งํ•ด์„œ ๋‹ค์Œ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•ด v4์—์„œ JSS๋ฅผ ๊ณ ์ˆ˜ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฉ‹์ง„ ๊ธฐ๋Šฅ(์˜ˆ: ํ™•์žฅ ๋ฐ ๊ตฌ์„ฑ ํ”Œ๋Ÿฌ๊ทธ์ธ)์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ •์„ ์œ„ํ•ด ์Šคํƒ€์ผ๋ฆฌ์Šค ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ž‘์„ฑํ•ด์•ผ ๋น„์Šทํ•œ ๊ฒƒ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

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

@oliviertassinari https://github.com/mui-org/material-ui/issues/6115#issuecomment -643398897์— ์–ธ๊ธ‰๋œ ๋Œ€๋กœ ์ง„ํ–‰ ์ค‘์ธ ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ์— ๋”ฐ๋ผ ๋จธํ‹ฐ๋ฆฌ์–ผ ํŒ€์ด ์ธ๊ธฐ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋Š๋ฆฝ๋‹ˆ๋‹ค. ํ•ญ์ƒ ๊ทธ๋ž˜์™”๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ CSS์˜ JS ํ‘œ๊ธฐ๋ฒ• ๊ฐ™์€ ๊ฒƒ์„ ๋ฐฐ์›Œ์•ผ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๋Š” ์š”์ ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ์ž‘์—…์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž์˜ ์‚ถ์„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ํŒจํ‚ค์ง€ ์œ ์ง€ ๊ด€๋ฆฌ์ž๋กœ์„œ ์šฐ๋ฆฌ๊ฐ€ ํ•˜๋Š” ์ผ์˜ ์ผ๋ถ€์ด์ง€๋งŒ(๋‚ด ํ”„๋กœ์ ํŠธ์˜ ๊ฒฝ์šฐ) ์ด๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ๊ณผ ์„ฑ๋Šฅ์„ ๋†’์ด๋Š” ๊ฒƒ ์‚ฌ์ด์—๋Š” ์„ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋‚ด๊ฐ€ makeStyles๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ๋„์ž…๋œ ์ดํ›„๋กœ ํ•ญ์ƒ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

๋‚ด ๋งˆ์ง€๋ง‰ ํŒ€ ๊ฑด์ถ•๊ฐ€๋Š” ๋“ฃ์ง€ ์•Š๊ณ  ์Šคํƒ€์ผ์ด ์ง€์ •๋œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€๊ธˆ ์‚ฌ์ดํŠธ๊ฐ€ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ๋ธŒ๋žœ์น˜์—์„œ makeStyles๋กœ ์ „ํ™˜ํ•˜์—ฌ ๋ชจ๋ฐ”์ผ ์žฅ์น˜์˜ TTI์—์„œ 50%(10์ดˆ)๋ฅผ ์ ˆ์•ฝํ–ˆ์ง€๋งŒ, ๊ทธ ๋Œ“๊ธ€์—์„œ ๋งํ–ˆ๋“ฏ์ด JS ํ‘œ๊ธฐ๋ฒ•์€ ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ์•Œ๋ ค์ ธ ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ›์•„๋“ค์—ฌ์ง€์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋‚ด๋ถ€์ ์œผ๋กœ ์žฌ๋ฃŒ๋Š” ์›ํ•˜๋Š” ๋Œ€๋กœ ์„ ํƒํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ฑ๋Šฅ์„ ๋ฐœํœ˜ํ•˜๋„๋ก ํ•˜์‹ญ์‹œ์˜ค.

[์งˆ๋ฌธ์ด StackOverflow๋กœ ์ด๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.]

@haysclark ์ง€์› ์งˆ๋ฌธ์— ๋Œ€ํ•ด์„œ๋Š” RFC์— ๋‹ตํ•˜์ง€ ๋ง๊ณ  StackOverflow๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

@haysclark ์ง€์› ์งˆ๋ฌธ์— ๋Œ€ํ•ด์„œ๋Š” RFC์— ๋‹ตํ•˜์ง€ ๋ง๊ณ  StackOverflow๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

@mbrooks ๋ฏธ๋ฆฌ ์•Œ๋ ค ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@emotion/styled (๊ธฐ๋ณธ์ ์œผ๋กœ styled-component์™€ ๋™์ผํ•œ API๋ฅผ ๊ฐ€์ง)๊ฐ€ ๋˜‘๊ฐ™์ด ๋Š๋ฆด์ง€ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ตฌํ˜„์— ๋Œ€ํ•ด ๋” ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

https://codesandbox.io/s/css-in-js-comparison-sej1m

image

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

Box ์ปดํฌ๋„ŒํŠธ์˜ ์„ฑ๋Šฅ์ด ๋‹น์‹ ์˜ ํ”„๋กœํŒŒ์ผ๋ง๊ณผ ๋น„๊ต๋ ์ง€ ๊ถ๊ธˆํ•ด์„œ Chakra-UI์˜ Box๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ข‹์€ ์ธก์ •์„ ํ–ˆ๊ณ  ๊ฒฐ๊ณผ๋Š”... ์˜์™ธ์˜€์Šต๋‹ˆ๋‹ค :P
https://codesandbox.io/s/css-in-js-comparison-forked-mg3gx?file=/src/App.js

image

@Nvveen Chakra-UI v1์„ ์‚ฌ์šฉํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? ๋‹ค์‹œ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ์ž˜๋งŒ๋˜๋ฉด ๋” ๋‚˜์•„์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„์ง ๋ฒ ํƒ€ ๋ฒ„์ „์ด์ง€๋งŒ ๊ฐ์ • v11๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@Nvveen Chakra-UI v1์„ ์‚ฌ์šฉํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? ๋‹ค์‹œ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ์ž˜๋งŒ๋˜๋ฉด ๋” ๋‚˜์•„์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„์ง ๋ฒ ํƒ€ ๋ฒ„์ „์ด์ง€๋งŒ ๊ฐ์ • v11๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  RC๋กœ ๋ฐฉ๊ธˆ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๋ˆˆ์— ๋„๋Š” ์ฐจ์ด๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ ์ผ๋ฐ˜ SC๋ณด๋‹ค ์•ฝ 1.5~2๋ฐฐ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ ๊ฐ€์žฅ ํฐ ์งˆ๋ฌธ์€ MUI Box๊ฐ€ ์™œ ๊ทธ๋ ‡๊ฒŒ ๋Š๋ฆฐ๊ฐ€์ž…๋‹ˆ๋‹ค.

@Nvveen Chakra-UI v1์„ ์‚ฌ์šฉํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? ๋‹ค์‹œ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ์ž˜๋งŒ๋˜๋ฉด ๋” ๋‚˜์•„์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„์ง ๋ฒ ํƒ€ ๋ฒ„์ „์ด์ง€๋งŒ ๊ฐ์ • v11๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  RC๋กœ ๋ฐฉ๊ธˆ ์‹œ๋„ํ–ˆ์ง€๋งŒ ๋ˆˆ์— ๋„๋Š” ์ฐจ์ด๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ ์ผ๋ฐ˜ SC๋ณด๋‹ค ์•ฝ 1.5~2๋ฐฐ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ ๊ฐ€์žฅ ํฐ ์งˆ๋ฌธ์€ MUI Box๊ฐ€ ์™œ ๊ทธ๋ ‡๊ฒŒ ๋Š๋ฆฐ๊ฐ€์ž…๋‹ˆ๋‹ค.

Jss๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. SC๋Š” ์ ์–ด๋„ ๋‹ค์†Œ ๋‚ซ์Šต๋‹ˆ๋‹ค.

๋‚ด ์ปดํ“จํ„ฐ์—์„œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์‹คํ–‰๋˜๋Š” ์ˆœ์„œ๋Š” ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ๋น„๊ตํ•˜๋‹ค

  1. ์ƒ์ž ๋จผ์ € https://codesandbox.io/s/css-in-js-comparison-forked-tqlg1?file=/src/App.js
    Capture dโ€™eฬcran 2020-08-16 aฬ€ 19 49 55

  2. ๋งˆ์ง€๋ง‰ ์ƒ์ž https://codesandbox.io/s/css-in-js-comparison-forked-js6th?file=/src/App.js
    Capture dโ€™eฬcran 2020-08-16 aฬ€ 19 49 45

@oliviertassinari ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘ ๋ฐ v8์˜ jit๊ฐ€ ์›์ธ์ž…๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ๋ถ„๋ฆฌ/๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘ ํ…Œ์ŠคํŠธ๋Š” ๋” ๋‚˜์€ ์ง€ํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ ๋•Œ๋•Œ๋กœ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์ •, SC ๋ฐ ์ฐจํฌ๋ผ๋Š” ๊ฐ๊ฐ์˜ ์ž‘์€ ๊ตฌ์„ฑ ์š”์†Œ์— ์žฅ์ฐฉํ•  ๊ณ ์œ ํ•œ ์Šคํƒ€์ผ์ด ์žˆ๊ณ  MUI ์Šคํƒ€์ผ์ด ์•„์ง ์™„์ „ํžˆ ์ตœ์ ํ™”๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ด๋ก ์ ์ธ ์ตœ๋Œ€ ์„ฑ๋Šฅ์— ๊ทผ์ ‘ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. makeStyles/pure CSS์—์„œ์™€ ๊ฐ™์ด ์ „์ฒด ๊ตฌ์„ฑ ์š”์†Œ ํŠธ๋ฆฌ์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ์Šคํƒ€์ผ ์‹œํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ฐ์ •, SC ๋“ฑ์„ ์œ„ํ•œ ์ถ”๊ฐ€ 30ms๋Š” ์Šคํƒ€์ผ์ด ๋งˆ์šดํŠธ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•˜๋Š” ๊ฐ ์ž‘์€ ๊ตฌ์„ฑ ์š”์†Œ์˜ ํ”ผํ•  ์ˆ˜ ์—†๋Š” ์˜ค๋ฒ„ํ—ค๋“œ์ž…๋‹ˆ๋‹ค.

@jedwards1211 dx๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด๋ผ๋ฉด Atlassian์€ ์ด๋ฅผ css๋กœ ์ปดํŒŒ์ผ ํ•˜๋Š” lib๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

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