4 min read

์–ด๋Š ๋‚  ์šฐ๋ฆฌ๋„ ๋””์ž์ธ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค๊ธฐ๋กœ ํ–ˆ๋‹ค. (1)

๊ทธ๊ฑฐ ์–ด๋–ป๊ฒŒ ํ•˜๋Š”๊ฑด๋ฐ...

Table of Contents

๋ฐœ๋‹จ - ์ „๊ฐœ

์–ด๋Š ํšŒ์‚ฌ์˜ ์–ด๋Š ๋‚  ์กฐ์ง์— ๋””์ž์ด๋„ˆ๊ฐ€ ์ž…์‚ฌํ•˜๊ฒŒ ๋˜๋ฉด์„œ ํšŒ์‚ฌ์—๋„ ๋””์ž์ธ์‹œ์Šคํ…œ์ด ์ƒ๊ธฐ๊ฒŒ ๋˜๋Š”๋ฐ โ€ฆ

๋””์ž์ธ์‹œ์Šคํ…œ ๊ทธ๊ฑฐ ํฐ ํšŒ์‚ฌ๋“ค์ด๋‚˜ ํ•˜๋Š”๊ฑฐ ์•„๋‹ˆ์•ผ?
์ตœ์†Œํ•œ์˜ ๋…ธ๋ ฅ์œผ๋กœ ๋””์ž์ธ์‹œ์Šคํ…œ ์œ ์ง€ํ•˜๊ธฐ - ์ง€๊ธˆ๋ถ€ํ„ฐ ํ•œ๋ฒˆ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋””์ž์ธ์‹œ์Šคํ…œ์˜ ์ƒ์• ์ฃผ๊ธฐ

๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ๊ทธ๋ ‡๋“ฏ, ๋””์ž์ธ ์—ญ์‹œ ์ƒ์• ์ฃผ๊ธฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒ๋ช…์ด ์žˆ๋‹ค๋Š” ๊ฑด ์ฃฝ์Œ๋„ ์žˆ๋‹ค๋Š” ๋œป โ€ฆ
ํƒœ์–ด๋‚˜๊ณ  ์ฃฝ์–ด๊ฐ€๋Š” ๋””์ž์ธ ํ† ํฐ๋“ค์„ ์ž˜ ๊ด€๋ฆฌํ•ด ์ฃผ์–ด์•ผ๊ฒ ์ฃ ?

ํ˜„์žฌ ์ƒํ™ฉ์— ๋Œ€ํ•œ ์‚ฌ์ „์ง€์‹

  • shadcn์ด๋‚˜ antd ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋งˆํฌ์—…์˜ ๋””์ž์ธ ์˜์กด๋„๊ฐ€ ๋‚ฎ์Šต๋‹ˆ๋‹ค. design token (variable)์˜ ์‹ ๊ทœ ์ ์šฉ์ด ํ•„์š”ํ•œ ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ๋„์ž… ์‹œ๋„์—์„œ๋Š” ์ƒ์• ์ฃผ๊ธฐ๋ฅผ ์ด 4๋‹จ๊ณ„๋กœ ๋‚˜๋ˆด์Šต๋‹ˆ๋‹ค.
์ €๋Š” ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ์ž์ด๊ธฐ ๋•Œ๋ฌธ์— .. ๋””์ž์ธ ์ชฝ์€ ์ด๋Ÿฐ์ €๋Ÿฐ ์ถ•์†Œ๊ฐ€ ์ผ์–ด๋‚ฌ์Šต๋‹ˆ๋‹ค.

  1. (๋””์ž์ด๋„ˆ) ํ”ผ๊ทธ๋งˆ์—์„œ ์‚ฌ์ „์ •์˜๋œ ๋””์ž์ธํ† ํฐ ์ˆ˜์ •
  2. (๋””์ž์ด๋„ˆ/FE) ํ”ผ๊ทธ๋งˆ์—์„œ ๋””์ž์ธ ํ† ํฐ์„ ํฌํ•จํ•œ Global CSS ์ถ”์ถœ
  3. (FE) ํ”ผ๊ทธ๋งˆ์—์„œ ์ปดํฌ๋„ŒํŠธ ๋งˆํฌ์—…์— ํ•„์š”ํ•œ css/scss ์ถ”์ถœ
  4. (FE) ํ”„๋กœ์ ํŠธ ์ ์šฉ
    1. ๋””์ž์ธ ํ† ํฐ์„ ํฌํ•จํ•œ global.css ์˜ ์ „์—ญ ์ ์šฉ
    2. ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„ ๋งˆํฌ์—… ์ ์šฉ

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” 1๋ฒˆ 2๋ฒˆ์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณผ๊นŒ์š”.
๊ทธ๋Ÿผ ๋ ˆ์ธ ๊ณ 

1. ์‚ฌ์ „์ •์˜๋œ ๋””์ž์ธ ํ† ํฐ ์ˆ˜์ •

ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ”ผ๊ทธ๋งˆ ์ž์ฒด์˜ ๊ธฐ๋Šฅ (variable library) ์‚ฌ์šฉํ•˜๊ธฐ / Tokens Studio ๋“ฑ 3rd Party ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ.

ํ”ผ๊ทธ๋งˆ dev mode์—์„œ ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„ ๋งˆํฌ์—…์„ ์ง€์›ํ•˜๊ธด ํ•˜์ง€๋งŒ, ๊ฒฐ๊ตญ global css ๋‹จ์œ„๋กœ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ์‚ฌ์šฉ์ด ํ•„์š”ํ•ด๋ณด์—ฌ ์ด๋ฒˆ ์‹œ๋„์—์„œ๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ์™ธ๋ถ€ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์š”๋Ÿฐ์‹์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋””์ž์ธ ํ† ํฐ์˜ ๊ฐ’ ์ˆ˜์ •์„ ์œ„ํ•ด์„œ๋Š” ๋””์ž์ธ ์‹œ์Šคํ…œ์ด ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์„ฑ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•œ๋ฐ์š”.
์šฐ์„  ๋””์ž์ธ ํ† ํฐ์ด๋ž€? ์ƒ‰์ƒ ๋“ฑ ๋” ์ด์ƒ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์—†๋Š” ์•„ํ† ๋ฏนํ•œ ๋””์ž์ธ ์†์„ฑ์— ์ด๋ฆ„์„ ๋ถ€์—ฌํ•˜์—ฌ ๋ณ€์ˆ˜๋กœ ๋งŒ๋“  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด๋•Œ, ๋””์ž์ธ ์‹œ์Šคํ…œ์€ ์—ฌ๋Ÿฌ ๊ณ„์ธต์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๋Š” ์ ์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ๋ฐ์š”, ๋ณดํ†ต Raw Value - Primitive - Semantic - Component 4๊ฐœ ๊ณ„์ธต์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์šฐ๋ฆฌ ์‹œ์Šคํ…œ์˜ primary ์ƒ‰์ƒ์ด #FF0000 ์ด๋ผ๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด 4๊ฐœ ๊ณ„์ธต์— ๊ฑธ์ณ์„œ ์ •์˜๋˜์–ด ์žˆ๊ฒ ๋„ค์š”.

Raw ValuePrimitiveSemanticComponent
#FF0000red-100bg-primarybutton-bg-primary

๋งŒ์•ฝ์— button-bg-primary์˜ ์ƒ‰์ƒ์„ ๋นจ๊ฐ„์ƒ‰์—์„œ ํŒŒ๋ž€์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์œผ๋ฉด,

  1. primitive์ธ red-100์˜ raw value #FF0000์„ #0000FF๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๊ฒ ์ง€๋งŒ,
  2. bg-primary์˜ ๊ฐ’์„ #0000FF์˜ ๊ฐ’์„ ๊ฐ–๊ณ  ์žˆ๋Š” blue-100๋กœ ์ฃผ๋Š” ํŽธ์ด ๊ตฌ์กฐ๋ฅผ ์ž˜ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๊ฒ ์ฃ .

๋””์ž์ธ ์‹œ์Šคํ…œ์˜ ๋””์ž์ธ ํ† ํฐ๋„ ์—ญ์‹œ key(name):value๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋“ค๊ณผ ๊ฐ™์•„์„œ, ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜ ์—†์œผ๋ฉด ๊ทธ์— ๋”ฐ๋ฅธ side effect๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

2. ๊ธ€๋กœ๋ฒŒ ํ† ํฐ ๋‚ด๋ณด๋‚ด๊ธฐ

Tokens Studio - JSON Schema Tokens Studio์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด JSON ์Šคํ‚ค๋งˆ๋กœ ๋””์ž์ธ ํ† ํฐ์„ ๋‚ด๋ณด๋‚ด๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ์˜ˆ์ƒํ•œ ๋Œ€๋กœ JSON์ด ์žˆ์œผ๋ฉด .. ์ฝ”๋“œํ™” ์‹œ์ผœ์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ์žˆ๊ธฐ ๋งˆ๋ จ์ž…๋‹ˆ๋‹ค.

style dictionary ๋ฌธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”,

{
  "source": ["tokens/**/*.json"],
  "platforms": {
    "scss": {
      "transformGroup": "scss",
      "prefix": "sd",
      "buildPath": "build/scss/",
      "files": [
        {
          "destination": "_variables.scss",
          "format": "scss/variables"
        }
      ],
      "actions": ["copy_assets"]
    },
    "android": {
      "transforms": ["attribute/cti", "name/snake", "color/hex", "size/remToSp", "size/remToDp"],
      "buildPath": "build/android/src/main/res/values/",
      "files": [
        {
          "destination": "style_dictionary_colors.xml",
          "format": "android/colors"
        }
      ]
    }
  }
}

ํ”Œ๋žซํผ์— ๋”ฐ๋ฅธ ๋ณ€ํ™˜๋„ ๊ฐ€๋Šฅํ•˜๊ณ , ์Šคํ‚ค๋งˆ ์„ ์–ธ์— ๋”ฐ๋ผ์„œ ๋ณผ ํŒŒ์ผ๊ณผ ๋ณ€ํ™˜ํ•  ํŒŒ์ผ์— ๋Œ€ํ•œ ์ •์˜๋งŒ ์ž˜ ํ•ด์ฃผ๋ฉด ์ž˜ ๋ณ€ํ™˜ํ•ด์ค๋‹ˆ๋‹ค. ๋””์ž์ธ ํ† ํฐ์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ CI์— ๋ฌถ์–ด์•ผ ํ•˜๋Š”์ง€๋Š” ๊ณ ๋ฏผ๋˜๋Š” ์‚ฌํ•ญ์ธ๋ฐ์š”, ์›ํ‹ฐ๋“œ์˜ ๋””์ž์ธ์‹œ์Šคํ…œ ํ”ผ๊ทธ๋งˆ ๋Œ“๊ธ€์—์„œ ํžŒํŠธ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

์–ด์ฐจํ”ผ ๋ณ€๊ฒฝ์ ์˜ huamn followup์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ž๋™ํ™”๋ฅผ ํ•˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์œผ๋กœ ์ดํ•ดํ–ˆ์–ด์š”.
1๊ฐœ ์ปดํฌ๋„ŒํŠธ์˜ ์ˆ˜์ •์ด ์•„๋‹Œ, ๋””์ž์ธ ํ† ํฐ ๋‹จ์œ„์˜ ์ˆ˜์ •์€ ์ „์—ญ์ ์ด๊ณ  / ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์ด๋“œ์ดํŽ™ํŠธ์˜ ๋ฒ”์œ„๊ฐ€ ๋„“์Œ์œผ๋กœ, ์ž‘์—…์˜ ์ž๋™ํ™”๋ฅผ ํ•˜๋˜, ์ž๋™ ์ ์šฉ๋˜๊ธฐ์—๋Š” ๋ฌด๋ฆฌ๊ฐ€ ์žˆ๊ฒ ๋‹ค๋Š” ๋ฐ ๋™์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์‹œ๊ฐ„์— ..

์˜ค๋Š˜๋„ ์—ญ์‹œ ์šฉ๋‘์‚ฌ๋ฏธ์ž…๋‹ˆ๋‹ค.
๋‹ค์Œ ์ฃผ์— ์ปดํฌ๋„ŒํŠธ ๋งˆํฌ์—… ์ถ”์ถœ๊ณผ ์ฝ”๋“œ๋กœ ๋ณด๋Š” ์˜ˆ์‹œ๋กœ ๋Œ์•„์˜ค๊ฒ ์Šต๋‹ˆ๋‹ค.