๐ŸŽ„ ์„ฑ์žฅ์ผ์ง€ 4.0

์ฑ… ํ–‰๋ณตํ•œ ์ด๊ธฐ์ฃผ์˜์ž(์›จ์ธ ๋‹ค์ด์–ด)์˜ ๋‚ด์šฉ์— ์ž๊ทน๋ฐ›์•„ ์‹œ์ž‘ํ•˜๋Š” ์†Œ๋ฐ•ํ•œ ์„ฑ์žฅ๊ธฐ๋ก

์‚ด์•„์žˆ๋Š” ๊ฝƒ๊ณผ ์ฃฝ์€ ๊ฝƒ์€ ์–ด๋–ป๊ฒŒ ๊ตฌ๋ณ„ํ•˜๋Š”๊ฐ€?
์„ฑ์žฅํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์‚ด์•„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
์ƒ๋ช…์˜ ์œ ์ผํ•œ ์ฆ๊ฑฐ๋Š” ์„ฑ์žฅ์ด๋‹ค!

๐ŸŒณ (1.0)ํ‚ค์›Œ๋“œ
์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌ, ์ถ”ํ›„์— ๋ณด๋ฉด์„œ ์Šค์Šค๋กœ ์„ค๋ช…
๐Ÿ‰ (2.0)๊ฒฝํ—˜ ์œ„์ฃผ๋กœ
๋‹จ์ˆœ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ๋ณด๋‹ค ๋ฌด์—‡์„ ๋ฐฐ์› ๊ณ  ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€ ์งง๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž‘์„ฑ
โ„๏ธ (3.0)์ •ํ•ด์ง„ ํ…œํ”Œ๋ฆฟ์— ๋งž์ถฐ์„œ
ํ‚ค์›Œ๋“œ, ๊ฒฝํ—˜ ๋ชจ๋‘ ์ข‹๋‹ค. ๋‹ค๋งŒ ๋งค์ผ ์ž‘์„ฑํ•˜๊ธฐ๋กœ ๋งˆ์Œ ๋จน์€๋งŒํผ ํ•ต์‹ฌ๋งŒ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ…œํ”Œ๋ฆฟ์„ ์ž‘์„ฑ
(3.1)230102๋ถ€ํ„ฐ ์‹œ์ž‘๋˜๋Š” ํ•™์Šต์— ๊ด€ํ•œ ๋‚ด์šฉ ์ถ”๊ฐ€
(3.2)230313๋ถ€ํ„ฐ ์ข€๋” ๊ฒฝํ—˜, ๊ฐ์ • ์œ„์ฃผ์˜ ๋‚ด์šฉ๋„ ๋‹ด๊ธฐ!
๐ŸŒพ (4.0)ํ•™์Šต ํ‚ค์›Œ๋“œ์—์„œ ์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์ •๋ณด ์ œ๊ณต, ๊ณ ๋ฏผ์—์„œ ๋‚ด ๊ฒฝํ—˜์„ ์ž์„ธํžˆ ์ ์ž!

๐Ÿ”‘ ์˜ค๋Š˜์˜ ํ•™์Šต ํ‚ค์›Œ๋“œ

styled-components

์ด๋ฒˆ์— ์ƒˆ๋กญ๊ฒŒ ์‹œ์ž‘๋˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋Œ€ํ‘œ์ ์ธ CSS in JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ styled components๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค. ์‚ฌ์‹ค ๋‚ด๊ฐ€ ์ข‹์•„ํ•˜๋Š” TailwindCSS์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ ์„ฑ๋Šฅ๋ฉด์—์„œ ์ข‹์ง€ ์•Š๋‹ค๊ณ  ํ•˜์—ฌ ๊ฐ€๋Šฅํ•˜๋ฉด ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ ค ํ–ˆ๋‹ค. JS ์ฝ”๋“œ ๋‚ด์—์„œ CSS์™€ ๊ด€๋ จ๋œ ๋กœ์ง์ด ์žˆ์œผ๋ฏ€๋กœ ๊ฒฐ๊ตญ์—” ์ด ์ฝ”๋“œ๋ฅผ CSS ํŒŒ์ผ๋กœ ์ปดํŒŒ์ผํ•ด์•ผํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ผ ์„ฑ๋Šฅ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ•˜์ง€๋งŒ ๋ฆฌ์•กํŠธ์˜ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ๋ฅผ ๋ฐฐ์šฐ๊ณ  ํ•™์Šตํ•˜๋Š” ๋ฐ์—๋Š” styled components๊ฐ€ ๋„์›€์ด ๋œ๋‹ค๊ณ  ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

styled-components ๊ณต์‹๋ฌธ์„œ - Motivation

์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „ ๊ณต์‹๋ฌธ์„œ์— ๋“ค์–ด๊ฐ€ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์„ค๋ช…์„ ์ฝ์–ด๋ณด์•˜๋‹ค.(๊ฐœ์ธ์ ์œผ๋กœ ๊ณต์‹๋ฌธ์„œ์—์„œ ์ œ๊ณตํ•˜๋Š” get started ๋“ฑ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ์„ค๋ช…๋„ ์ข‹์ง€๋งŒ ์™œ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค์—ˆ๋Š”์ง€ ๋ณด์—ฌ์ฃผ๋Š” ๋‚ด์šฉ๋“ค์ด ์ •๋ง ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.)

Motivation

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

  • Automatic critical CSS: ์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ๋Š” ํŽ˜์ด์ง€์—์„œ ๋ Œ๋”๋ง๋œ ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ๋งŒ ์ฃผ์ž…ํ•˜์—ฌ ์ตœ์†Œํ•œ์˜ ์ฝ”๋“œ๋งŒ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๋“œํ•˜๊ฒŒ ํ•œ๋‹ค. ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ์ฝ”๋“œ์–‘์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • No class name bugs: ์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ๋Š” ์Šคํƒ€์ผ์— ๋Œ€ํ•œ ๊ณ ์œ ํ•œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ƒ์„ฑํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค ์ด๋ฆ„ ์ค‘๋ณต, ์ค‘์ฒฉ ํ˜น์€ ์ฒ ์ž ์˜ค๋ฅ˜์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • Easier deletion of CSS: ์ผ๋ฐ˜์ ์ธ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ํด๋ž˜ ์Šค์ด๋ฆ„์ด ์–ด๋””์—์„œ ์‚ฌ์šฉ๋˜์—ˆ๋Š”์ง€ ์•Œ๊ธฐ ์–ด๋ ต๋‹ค. ํ•˜์ง€๋งŒ ์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ชจ๋“  ์Šคํƒ€์ผ๋ง์ด ํŠน์ • ์ปดํฌ๋„ŒํŠธ์— ์—ฐ๊ฒฐ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ช…ํ™•ํ•˜๋‹ค.

ํŠน์ • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  ์‚ญ์ œ๋˜๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ๋„ ๋ชจ๋‘ ํ•จ๊ป˜ ์‚ญ์ œ๋œ๋‹ค.

  • Simple dynamic styling: ์ปดํฌ๋„ŒํŠธ์˜ ์†์„ฑ์ด๋‚˜ ์ƒํƒœ์— ๋”ฐ๋ผ ์Šคํƒ€์ผ์„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Painless maintanence: ๋‹น์‹ ์˜ ์ปดํฌ๋„ŒํŠธ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ์Šคํƒ€์ผ์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ํŒŒ์ผ์„ ์ฐพ์•„๋‹ค๋‹ˆ์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ๊ต‰์žฅํžˆ ํŽธ๋ฆฌํ•˜๋‹ค.
  • Automatic vendor prefixing: ํ˜„์žฌ ํ‘œ์ค€์— ๋งž๊ฒŒ CSS๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์Šคํƒ€์ผ์ฆˆ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‚˜๋จธ์ง€ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•œ๋‹ค.

Global Style

styled components์—์„œ๋Š” createGlobalStyle์„ ํ†ตํ•ด ์ „์—ญ ์Šคํƒ€์ผ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. createGlobalStyle์€ styled components์—์„œ ์ œ๊ณตํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ณดํ†ต GlobalStyles.style.ts์™€ ๊ฐ™์€ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•œ๋‹ค. ๋˜ํ•œ createGlobalStyle์„ ํ†ตํ•ด css์—์„œ reset css ์—ญํ• ์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

import { createGlobalStyle } from 'styled-components';

const GlobalStyles = createGlobalStyle`
  body {
    margin: 0;
    padding: 0;
  }
`;

export default GlobalStyles;

Github project์˜ workflow

ํ•จ๊ป˜ ๊ณต๋ถ€ํ•˜๋Š” ์ค‘์ธ iOS์˜ ๋…ธ์•„์—๊ฒŒ Github project์˜ workflow ์„ค๋ช…์„ ๋“ฃ๊ฒŒ ๋˜์—ˆ๋‹ค. workflow๋ฅผ ํ†ตํ•ด project์˜ ์นธ๋ฐ˜์„ ์ข€๋” ์ž๋™ํ™”ํ•˜์—ฌ ํŽธ๋ฆฌํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ โ€ฆ ์—์„œ workflow๋ฅผ ์„ธํŒ…ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • trigger โ‡’ when
    • action โ‡’ then
    • ex) when: ์ด์Šˆ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์„ ๋•Œ, then: ์ด์Šˆ๋ฅผ TODO์—๋‹ค๊ฐ€ ์˜ฎ๊ฒจ๋ผ

Github action

  • yml ํŒŒ์ผ๋กœ ์Šคํฌ๋ฆฝํŠธ ์งœ์„œ ๋‹ค์–‘ํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์ ์šฉํ•ด๋ณผ์ง€ ๊ณ ๋ฏผ์„ ํ•ด๋ด์•ผ๊ฒ ์ง€๋งŒ, ์–ด๋–ค issue์— ๋Œ€ํ•œ ๋ธŒ๋žœ์น˜๋ฅผ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋“ฑ์˜ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

๐Ÿ“ ์š”์•ฝ ๋ฐ ํ•˜๋ฃจ ๊ฐ„๋‹จ ํšŒ๊ณ 

์ง„์งœ ํ•จ๊ป˜ ํ•˜๋Š” ๋™๋ฃŒ๋“ค ๋•๋ถ„์— ๋งŽ์€ ์ž๊ทน์„ ๋ฐ›๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๋‚˜๋ณด๋‹ค ์ž˜ํ•˜๋Š” ๋™๋ฃŒ๋ฅผ ๋ณด๋ฉด ์˜๊ธฐ์†Œ์นจํ•ด์ง€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์–ด๋–ค ์ ์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์„์ง€ ์ฐพ์•„๋ณด๊ฒŒ ๋œ๋‹ค..! ์•ž์œผ๋กœ๋„ ๋” ์ข‹์€ ๋™๋ฃŒ๋“ค๊ณผ ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๊ณ  ์‹ถ๋‹ค.(๊ทธ์ „์— ๋‚ด๊ฐ€ ๋จผ์ € ์ข‹์€ ์‚ฌ๋žŒ์ด ๋˜์–ด์•ผ๊ฒ ์ง€..?!)

์˜ค๋Š˜์˜ ์ž˜ํ•œ ์ 

  • ๋ฐฑ๋กœ๊ทธ๋ฅผ ์™„์„ฑํ•œ ์ 
  • ํ˜‘์—…ํ•˜๋ฉด์„œ ์ง„ํ–‰ํ•œ ์ 

์˜ค๋Š˜์˜ ์•„์‰ฌ์šด ์ 

  • ์—†๋‹ค.

์ฐธ๊ณ