피그마 무료 플랜에서 컬러 코드 추출 자동화하기! (feat. Figmable CLI 배포)

병스커·2025년 3월 16일
0

NodeJS

목록 보기
1/1

피그마 무료 플랜에서도 쉽게 피그마의 컬러 코드를 프로젝트의 root CSS에 import할 수 있는 figmable CLI를 만들었습니다! 🎉

👉🏻 사용해보기
Github 스타 및 이슈 제보하기!

들어가며

디자인에서 시스템을 구축해주었다면, 프론트엔드 개발자는 피그마에서 핸드오프 문서를 보며 섬세하게 반영하는 역할을 수행합니다. 컬러, 타이포그래피, 스페이싱 등, Foundation으로 구축된 값을 그대로 쉽게 재사용할 수 있도록 코드 단에 옮겨오는 작업이 필요하죠.

이것이 꼭 난이도가 높은 작업은 아니더라도, 정보를 틀림없이 잘 반영하는 꼼꼼함이 필요합니다. 또한 처음 반영한 이후, 디자인 시스템이 업데이트가 된다면 또한 누락 없이 잘 반영해야하죠.

하지만 여기서 어떤 점이 변경되었고, 어떤 점이 유지되어야 하는지 잘 파악할 수 있어야합니다. 자칫하다간 누락될 수 있죠.

이번에 저는 휴먼 에러가 발생할 확률이 높은 이 작업의 자동화를 위해, Figmable이라는 이름의 CLI를 만들어보았습니다!


1. figmable은 무엇인가요?

Figmable은 손쉽게 디자인 시스템의 정보를 프로젝트에 업데이트할 수 있는 CLI입니다. 100% 자동화는 아니라도 필요한 시점에 CLI 한번으로 요소를 가져올 수 있죠.

figmable이라는 이름은 Figma와 영어 접미사 -able(~할 수 있는)의 합성어로, "Figma 데이터를 코드에서 쉽게 활용할 수 있게 만드는 도구"라는 의미를 담았습니다! (마블을 연상시키는 발상이기도 했습니다 🤣)

우선 첫 시작으로 Color 코드를 가져올 수 있는 기능을 구현하였습니다.


2. 어떻게 사용하나요?

2.1. 사전 준비사항

2.1.1. Figma API 토큰

  • Figma > Accounts (계정 설정) > Personal access tokens > Generate new token
  • 새 액세스 토큰 생성
  • 토큰을 복사하여 보관

2.1.2. Figma 파일 키

  • 브라우저에서 Figma 파일 열기
  • URL에서 키 복사: figma.com/file/YOUR_FILE_KEY/...

2.1.3. Figma 컬러 오브젝트의 이름 규칙 맞추기

Image

  • 컬러 오브젝트의 이름 앞에 -- Prefix를 붙여야합니다 (예: --primary-500, --orange-600)
    • 이 네이밍 규칙은 Figmable이 컬러 변수를 식별하고 추출하기 위해 반드시 요합니다!
    • 예시:
      --orange-600   →  #EA580C
      --primary-500  →  #3B82F6
      --neutral-900  →  #171717

2.1.4. CSS 파일

  • CSS에 :root 선택자가 필요합니다.

  • 예시:

    /* Tailwind 사용 시 */
    @layer base {
      :root {
        /* CSS 변수가 여기에 추가됩니다 */
        --primary: #000000;
      }
    }
    
    /* 또는 일반 CSS도 가능합니다 */
    :root {
      /* CSS 변수가 여기에 추가됩니다 */
      --primary: #000000;
    }

2.2. 설치

npm install -g figmable

2.3. 사용법

2.3.1. 설정 저장

먼저 Figma 인증 정보파일 경로를 저장합니다.

figmable config \
  --fileKey YOUR_FIGMA_FILE_KEY \
  --token YOUR_FIGMA_API_TOKEN \
  --path ./path/to/your/global.css

2.3.2. 현재 설정 확인

저장된 설정을 확인합니다.

figmable show

다음 정보가 표시됩니다.

  • Figma 파일 키와 URL
  • API 토큰
  • 파일 경로
  • 설정 파일 위치 (직접 수정 가능)

2.3.3. 변수 동기화

설정 후 간단히 실행:

figmable

실행 시:

  1. Figma 파일에서 컬러 변수를 가져옵니다
  2. figma-variables.json에 저장합니다
  3. CSS 파일을 업데이트합니다
  4. CSS 파일의 백업을 생성합니다 (.bak)

3. 왜 figmable이 필요했을까요?

현대 프론트엔드 개발에서 디자인 시스템의 일관성을 유지하는 것은 중요한 과제입니다. 특히 컬러 시스템은 사용자 경험과 브랜드 아이덴티티의 핵심 요소죠. figmable 개발을 시작하게 된 배경은 다음과 같습니다.


2.1. 디자인-개발 싱크 문제

피그마에 디자인 팔레트를 구축하고 이를 스토리북에 반영하는 과정은 순조로웠습니다. 하지만 디자인 변경이 발생할 때마다 매번 수동으로 코드를 업데이트해야 하는 문제가 있었습니다.

디자인팀과 개발팀 사이의 효율적인 협업을 위해서는 이러한 수동 프로세스를 자동화할 필요가 있었습니다.


2.2. 휴먼 에러 방지 필요

매번 변경사항을 일일이 global CSS에 반영하는 작업은 단순 반복 작업이라 난이도가 높지는 않지만, 바꾸지 않아야할 요소를 바꾼다거나, 컬러 코드 입력을 실수한다든가 하는 휴먼 에러가 발생할 여지가 큽니다.

논리적 에러가 발생하는 분야가 아니기 때문이죠.

:root {
  --primary-100: #E6F7FF;
  --primary-200: #BAE7FF;
  --primary-300: #91D5FF;
  --primary-400: #69C0FF;
  --primary-500: #40A9FF;
  /* ... 수십 개의 컬러 변수들 */
}

2.3. 범용성에 대한 고민

처음에는 특정 프로젝트를 위한 모듈로 시작했지만, 이 기능이 모든 프론트엔드 프로젝트에서 필요할 것이라는 생각이 들었습니다.

'이 로직을 매 프로젝트마다 다시 작성하는 건 비효율적이지 않을까? CLI로 만들면 재사용성이 높아지지 않을까?'라는 고민이 figmable의 시작점이이었어요!

최근 npm 라이브러리를 만들어 배포한 경험이 곧장 행동할 수 있게끔 만들어준 원동력이었습니다!


3. figmable은 어떻게 만들어졌나요?

3.1 초기 모듈 개발

처음에는 특정 프로젝트 내에서 피그마 API를 활용해 컬러 코드를 가져오는 간단한 모듈을 만들었습니다. 이 단계에서는 기본적인 HTTP 요청과 응답 데이터 파싱에 집중했습니다.

// 초기 모듈의 핵심 로직 예시
async function fetchFigmaColors(fileId: string, token: string): Promise<ColorTokens> {
  const response = await fetch(`https://api.figma.com/v1/files/${fileId}`, {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  const data = await response.json();
  return parseColorTokens(data);
}

3.2 CLI을 위한 리포지토리로의 전환

이 기능을 재사용하기 쉽게 만들기 위해 별도의 리포지토리를 생성했습니다. 이 단계에서 코드 구조를 더 모듈화하고, TypeScript를 사용해 타입 안정성을 강화했습니다.


3.3 사용자 경험 개선

CLI 도구의 사용성을 높이기 위해 여러 가지 기능을 추가했습니다:

  1. 직관적인 로그 메시지: 사용자가 진행 상황을 쉽게 이해할 수 있도록 명확한 메시지를 설계했습니다.

    console.log('🎨 피그마에서 컬러 토큰을 가져오는 중...');
    
  2. 로딩 스피너: API 호출 시간 동안 사용자에게 피드백을 제공하기 위해 ora 라이브러리를 활용해 로딩 스피너를 구현했습니다.

    import ora from 'ora';
    
    const spinner = ora('피그마 API에서 데이터를 가져오는 중...').start();
    try {
      const data = await fetchFigmaData(fileId, token);
      spinner.succeed('데이터를 성공적으로 가져왔습니다!');
    } catch (error) {
      spinner.fail('데이터 가져오기 실패');
      console.error(error);
    }
  3. 백업 기능: 기존 CSS 파일이 손상되는 것을 방지하기 위해 자동 백업 기능을 구현했습니다. 동시에 백업이 필요 없는 경우를 위한 -no-backup 옵션도 제공했습니다.

    if (!flags.noBackup && fs.existsSync(outputPath)) {
      const backupPath = `${outputPath}.backup`;
      fs.copyFileSync(outputPath, backupPath);
      console.log(`💾 기존 파일의 백업이 생성되었습니다:     ${backupPath}`);
    }

3.4 배포 준비

CLI 도구로서 제대로 기능하기 위해서는 bin 설정이 필수적이라는 점을 알게 되었습니다. 이를 위해 index.ts 최상단에 shebang(#!/usr/bin/env node)을 추가하고, package.json에 bin 필드를 정의했습니다.

{
  "name": "figmable",
  "version": "1.0.0",
  "bin": {
    "figmable": "dist/index.js"
  }, 
  "scripts": {
    "build": "rollup -c rollup.config.mjs",
    "prepare": "npm run build",
  }
}

4. 어떻게 만들었는가?

4.1 CLI 라이브러리 선택: Yargs vs Commander

CLI 도구를 개발할 때 사용자 입력을 효과적으로 받기 위해, 라이브러리를 사용한다는 것을 알게되었습니다. 두 가지 주요 npm 라이브러리로, CommanderYargs가 있었어요.

조사를 해보니 통상 두 가지 다른 방향성이 있었습니다.

  • Commander: 간결하고 직관적인 명령어 구조를 만들 때 널리 사용됨
  • Yargs: 복잡한 인수 구조와 다양한 옵션 처리가 필요할 때 선호됨

figmable은 Figma의 파일 키(file-key), API 토큰(token), 파일 경로(path) 등 여러 인수를 유연하게 입력 받아야 했습니다.

특히 설정 명령어와 기본 동기화 명령어가 서로 다른 옵션을 가져야 했기 때문에, 저는 Yargs를 선택하였어요.

// 설정 명령어와 기본 명령어의 옵션이 다른 구조
.command("config", "Save configuration", (yargs) => {
  return yargs.option("fileKey", {...})
})
.command("$0", "Sync Figma variables", (yargs) => {
  // 다른 옵션 구성
})

Yargs는 이런 복잡한 구조를 명확하게 표현할 수 있었고, TypeScript와의 통합도 자연스러워서 개발 과정이 수월했습니다.

다음 CLI를 만들 때는 Commander를 사용해보려 합니다! 각 도구의 장단점을 직접 경험해보면 더 깊이 이해할 수 있을 것 같아요!


4.2 사용자 경험 요소

CLI 도구의 사용자 경험은 GUI와는 다른 방식으로 접근해야 합니다

  • 명확한 명령어 체계: 사용자가 직관적으로 이해할 수 있는 명령어와 옵션 구조가 필요합니다.
  • 상세한 에러 메시지: 문제 발생 시 사용자가 스스로 해결할 수 있도록 구체적인 에러 메시지를 제공해야 합니다.
  • 진행 상황 표시: 장시간 실행되는 작업의 경우, 로딩 스피너나 진행률 표시가 중요합니다.
  • 자세한 도움말: -help 옵션을 통해 모든 기능과 사용 예시를 충분히 제공해야 합니다.

4.3 설치 및 실행 환경

npm을 통해 전역 설치될 CLI 도구는 다음 사항을 고려해야 했습니다.

  • 적절한 bin 필드 설정
  • 플랫폼 호환성(Windows, macOS, Linux)
  • 최소한의 의존성으로 설치 용이성 확보
  • Node.js 버전 호환성

4.4 환경 변수 관리

figable을 사용하기 위해, 피그마 REST API를 사용하죠. 이때 사용자의 환경변수가 필요합니다.(file key, token, path 등) 매번 CLI의 인수로 작성하는 것은 아주 불편하고 실수할 여지가 많은 방식이라 생각했어요.

저는 최초 figable config- 명령어를 이용하여 최초 1번만 설정하면 이후, figable만 실행하여 쉽게 사용할 수 있도록 만들었습니다.

이를 위해 config에서 받은 인수를 사용자의 환경에 자동으로 .figmablerc라는 파일을 생성하여 쉽게 관리할 수 있도록 만들었습니다.

  • API 키와 같은 민감한 정보를 안전하게 저장
  • 사용자 홈 디렉토리에 설정 파일 생성
  • 설정 파일 자동 생성 및 업데이트 기능

5. 트러블 슈팅

개발 과정에서 마주친 주요 문제들과 그 해결책을 공유합니다. 이러한 경험이 비슷한 도구를 개발하시는 분들께 도움이 되길 바랍니다.

5.1 /varibales/local 사용 불가

피그마에서 디자인 값을 가져올 수 있는 REST API를 제공한다는 것을 알게되었어요. 현재 통상 피그마에서는 Local Variables를 이용하여 간편하게 디자인 토큰을 관리할 수 있습니다.

혹시나 하였는데 역시나! 피그마 REST API에서는 이 기능으로 만들어진 디자인 토큰을 손쉽게 get할 수 있는 엔드포인트를 제공하고 있었어요!

하지만... 무료 플랜에서는 /variables/local 엔드포인트에 접근할 수 없다는 제약이 있다는 것을 알게되었습니다.

이 문제를 해결하기 위해 대체 접근법을 만들었습니다.

  1. 파일 정보를 가져오는 일반 API를 사용하여 문서 구조를 분석
  2. 컬러 스타일이 적용된 노드를 찾아 해당 스타일 정보 추출
  3. CSS 변수명 형식에 맞게 데이터 구조화

조금 번거롭더라도,핸드오프 문서에서 컬러그래피의 Color Object의 이름에 반드시 -- prefix를 붙여서, 디자인 토큰 이름으로 작성해주어야 합니다. 해당 피그마 파일 모든 object의 이름 중에서 위 규칙과 같은 요소들만 가져와 json으로 추출합니다.

이를 통해 자체적으로 디자인 시스템의 컬러 코드를 가져올 수 있는 방법을 만들었습니다!

5.2 환경 변수 관리 문제

사용자가 컬러 코드를 추출하기 위해 매번 API 키와 파일 경로를 입력하는 것은 너무 불편합니다. 마치 리포지토리에 .env 파일에 환경변수를 입력하여 보안과 재사용성을 확보하는, 그런 방법을 사용하고 싶었어요.

처음에는 dotenv를 고려했지만, 전역 설치 CLI에서는 적합하지 않다고 판단했습니다.

❯ figmable config --fileKey YOUR_KEY --token YOUR_TOKEN --path ./src/styles/global.css
✅ Configuration saved: /Users/byungskersmacbook/.figmablerc

대신 사용자 홈 디렉토리에 설정 파일, .figmablerc를 생성하는 방식을 선택했습니다! 이제 환경변수는 최초 1회만 설치하고 이후에는 figmable만 실행하여 css에 자동 반영되도록 하였습니다.

또한 이후 figmable show 커맨드를 이용하여 변수들을 확인할 수 있고, 수정이 필요할 경우 로그에 출력된 경로로 이동하여 직접 쉽게 입력할 수 있도록 만들어두었습니다!


마치며

디자인 토큰을 손쉽게 가져오는 방법을 고민하고 계시다면, figmable을 한번 경험해보세요! 유용하셨다면, GitHub 저장소에 스타로 응원 해주시면 감사하겠습니다!! 😆

또한, 냉철한 피드백 혹은 이슈를 제보해주시거나 더 좋은 아이디어가 있다면 얼마든지 기여 부탁드려요!

긴 글 읽어주셔서 감사합니다!

profile
제품 주도 개발을 추구하는 개발자입니다.

0개의 댓글