피그마
피그마 Dev mode 플러그인을 만들어서 웹 프론트엔드팀 생산성 높여보기
2023.12.18
•
9 min read
안녕하세요. 코멘토에서 웹 프론트엔드를 개발하고 있는 송동훈입니다. 코멘토 프론트엔드팀은 코멘토 디자인 시스템(comento-ui)과 피그마를 활용해 디자이너분들과 효율적으로 협업하고 있습니다.
텍스트 기반 서비스를 개발하다보니 텍스트 작업을 할 때가 많습니다. 작업할 때는 피그마의 Typography 속성을 참고해 comento-ui의 c-typography
코드를 작성합니다. IDE가 자동 완성으로 도와주기는 하지만 매번 텍스트와 속성을 적거나 붙여넣기해야하는 번거로운 작업입니다. 이 작업을 더 단순화해서 생산성을 높일 수 있는 방법은 없을까 고민하다가 피그마 플러그인을 활용하면 어떨까 하는 생각이 들었습니다.
이 글에서는 피그마에서 디자인 시스템 컴포넌트를 활용한 부분을 코드로 손쉽게 변환할 수 있는 피그마 플러그인을 개발해 생산성을 높인 배경과 방법을 소개합니다.
피그마 플러그인
피그마 플러그인은 피그마 에디터의 기능을 확장한 애플리케이션입니다. 웹 친화적으로 로직 부분은 Javascript, UI는 HTML로 작성할 수 있고 피그마 컨텐츠에 접근해서 데이터를 이용하거나 컨텐츠를 생성하거나 수정할 수 있습니다. 인기가 많은 대표적인 플러그인으로는 피그마 파일을 HTML, React 코드로 변환해주는 Figma to Code가 있습니다.
저는 작업할 때 피그마의 Dev mode를 주로 사용합니다. 이 모드는 개발자 도구로 요소를 확인하는 것처럼 개발자 친화적인 UI, UX를 제공해서 작업하기 편하게 해줍니다.
Dev mode에서 동작하는 플러그인의 Code Generation(오른쪽 패널에 코드를 출력하는 기능)을 활용하면 번거로운 작업을 줄일 수 있을 것이라 생각했습니다.
만들고 싶은 플러그인
플러그인이 텍스트의 속성을 참고해 바로 c-typography
코드로 만들어서 타이핑 단계를 없애준다면 생산성이 향상될 것이라고 생각했습니다. 그렇다면 플러그인은 다음과 같은 로직으로 동작할 것이라고 생각했습니다.
- 유저가 피그마의 text를 선택합니다.
- 플러그인이 text의 property를 조사합니다.
- 플러그인이 property들을
c-typography
의 props로 넘겨준 코드를 생성합니다.
개발을 시작하기 전에 ChatGPT에게 제가 원하는 기능의 플러그인을 만들 수 있는지 물어봤는데 답변을 보니 만들 수 있겠다는 생각이 들어서 플러그인 API 문서를 찾기 시작했습니다.
플러그인 생성
플러그인은 피그마 데스크톱 앱에서 생성할 수 있습니다. 데스크톱 앱을 켜고 가이드를 따라가면 기본 예제 코드가 포함된 프로젝트를 생성할 수 있습니다.
플러그인 실행
플러그인을 로컬에서 실행하고 피그마에서 바로 확인할 수 있습니다. 코드가 바뀔때마다 결과를 바로 반영하기 위해 watch 모드로 실행했습니다.
yarn && yarn run watch
피그마에서 Dev mode에서 동작하는 플러그인은 오른쪽 패널에 실행됩니다. 피그마 파일에서 오른쪽 마우스 버튼을 클릭해 "Manage plugins in development" 메뉴에 들어가면 방금 만든 플러그인의 목록을 확인할 수 있습니다.
초기 예제 코드의 빨간 부분이 피그마의 Inspect 패널에 나오는 것을 확인할 수 있습니다.
코드 작성
코드를 보면 피그마 요소를 클릭하면 codegen의 generate
event가 발생합니다. callback으로 넘어오는 CodegenEvent는 SceneNode type인 node
를 넘겨주고 있었고, 여기에는 TextNode
도 포함되어 있습니다.
TextNode의 API 문서를 참고하여 어떤 API를 쓰면 원하는 값을 얻을지 console에 찍어보면서 파악했습니다. 아래 방법으로 console을 열어 볼 수 있었습니다.
type
props는 comento-ui에서 정의한 각 typography의 종류를 나타내는 값입니다. figma
객체의 getStyleById
를 활용하여 값을 가져올 수 있었습니다.
또한 필요한 font-weight
, color
값은 getCSSAsync
method를 이용해 가져온 css
object에서 가져올 수 있었습니다.
아래는 getCSSAsync
메서드를 호출한 결과값입니다.
// getCSSAsync 결과값
{
"color": "var(--Primary-blue800, #1B5192)",
"font-family": "Pretendard",
"font-size": "12px",
"font-style": "normal",
"font-weight": "400",
"line-height": "122% /* 14.64px */"
}
마지막으로 텍스트 내용은 characters
property를 가져왔습니다.
이를 종합하여 코드로 작성하면 다음과 같습니다.
figma.codegen.on('generate', async (event) => {
// TEXT_NODE 일때
if(event.node.type === 'TEXT') {
/*
mixed(여러개의 스타일이 적용된 텍스트)일때는 textStyleId가 figma.mixed이기 때문.
<https://www.figma.com/plugin-docs/api/TextNode/#textstyleid>
*/
if (typeof event.node.textStyleId === "string") {
const css = await event.node.getCSSAsync();
/*
예시
ex) extract 'body1' from 'body/body1(600)'
ex) extract 'caption1' from 'caption/caption1(600)'
*/
const fontType = figma.getStyleById(event.node.textStyleId)?.name.split('/')[1].split('(')[0];
/*
예시
ex) extract 'gray850' from 'var(--Gray-gray850, #202325)'
ex) extract 'red600' from 'var(--Error-red600, #E92525)'
*/
const fontColor = css.color.match(/var\\(--(.+),/)?.[1].split('-')[1];
const fontWeight = css['font-weight'];
const content = event.node.characters;
const code = `<c-typography type="${fontType}" color="${fontColor}" :font-weight="${fontWeight}">${content}</c-typography>`
return [
{
language: "HTML",
code: code,
title: "c-typography-converter",
},
];
}
}
return [
{
language: "PLAINTEXT",
code: "코드를 생성하려면 노드를 선택해주세요.",
title: "c-typography-converter",
},
];
});
피그마로 돌아가 이 플러그인을 실행해보면 아래와 같이 잘 동작하는 걸 볼 수 있습니다.
마치며
이렇게 피그마 플러그인을 만들어 생산성을 높였던 경험을 살펴보았습니다. 플러그인 API가 잘 구현되어 있어서 원하는 기능을 어렵지 않고 빠르게 구현할 수 있었습니다. 간단한 기능을 구현해 보니까 뿌듯했고 시야를 더 넓혀서 다른 컴포넌트에도 적용해보고 싶다는 생각이 들었습니다. 플러그인을 개발하고 실제로 사용하다 보니 텍스트의 중간에 색상이 바뀌는 등 property들이 섞여 있는 예외 상황에는 작동하지 않는 이슈도 발견해 수정하려고 합니다. 이 글이 여러분에게 반복 작업을 줄일 수 있는 영감이 되었으면 합니다. 감사합니다.