노코드 툴 만드는 사람들 - 1. #C8102E를 외우라고?

노코드 툴 만드는 사람들 - 1. #C8102E를 외우라고?

노코드 툴?

노코드 툴이라고 하면 환영하지 않는 개발자들이 대부분일 것이라고 생각한다. 코드 없이 웹 페이지를 만들 수 있음은 결국에 개발자들의 일자리 문제와 직결되기 때문이다. 개발자가 AI로 대체되느냐 마냐 하는 마당에, '노코드 툴'의 존재는 개발자들을 더욱 예민하게 만든다.

개발자들에게 노코드 툴을 사용하게 만들면 반발은 더욱 커진다. 키보드 두드리면 금방 만드는 웹 페이지를 굳이 이 툴을 새롭게 배워가면서 시간을 더 들여서 만들어야 된다고? 내가 어떻게 공부한 기술인데 그걸 쓰지 말라고?

코더가 되지 말고 개발자가 되어라 라는 말을 들어보았을 것이다. 이 말에 고개를 끄덕이지 않는 개발자는 거의 없을 거라고 생각한다.

축구용품을 판매하는 커머스를 만든다고 생각해보자. 브랜딩도 하고, 디자인도 하고, AI도 붙이고, 사용자들을 끌어들일 만한 컨텐츠들을 개발해서 멋진 홈페이지를 만들었고, 힘들기도 했지만 그 과정이 너무나 재미있고 뿌듯했다.
이제 물건만 팔면 되는데, 누가 얼만큼 주문을 했고, 재고는 얼만큼 남았는지, 홈페이지에 어떤 제품을 먼저 노출시킬 건지, 관리할 수 있는 어드민 페이지가 없다.
크게 생각할 필요도 없고 데이터베이스를 연결하고 몇 개의 페이지를 만들어서 올리면 되는데, 바빠 죽겠는 마당에 이런 단순 작업에 쓰는 시간이 너무 아깝다.

서비스는 고정된 개념이 아니기에 이러한 사이클은 서비스가 유지되는 동안 주기적으로 반복되며 개발자들을 고통받게 한다. 우리는 반복되는 어드민 개발에서 해방되고 싶다. 나에게 스트레스를 주는 건 마찬가지지만, 내 손으로 해결하고 싶고, 열정을 쏟고 몰입하게 만드는 더 크고 복잡한 문제를 엔지니어링하고 싶다.

앞으로 나두모두에서 이러한 니즈를 풀어나가는 과정을 하나하나씩 블로그에 담아보려고 한다. 오늘은 CSS Variables 시스템을 개발한 과정에 대해 이야기 할 것이다.

#C8102E를 외워야 된다고?

나두아이오에서 컴포넌트를 스타일링 하려면 프로퍼티 에디터로 스타일을 수정하거나 직접 CSS를 작성할 수 있었다. 하지만 반복되는 값을 저장해두고 사용하는 시스템이 없어, 매번 똑같은 값을 작성해줘야 된다는 불편함이 있었다.

CSS Variables 시스템을 구축하면 반복해서 사용하는 값은 변수에 저장해두고, 스타일링할 때 사용할 수 있다.

구조

나두아이오는 Editor가 App을 감싸고 있는 구조인데, 이 App은 iFrame으로 불러온다.

Editor와 App은 Bridge로 통신하고, CSS Variables의 경우 App에서 수정될 일이 없기 때문에 Editor에서 App으로 데이터를 보내는 단방향 구조를 사용한다.

App은 styled-jsx를 통해 string으로된 CSS를 resolve하여 jsx로 주입하는 형식을 사용하기 때문에, 브라우저에서 지원하는 CSS Variables를 그대로 사용하기로 했다.

const { className, styles } = useMemo(
  () =>
  styledCss.resolve`${css}`,
  [ css ],
);

return (
    <Fragment>
      {styles}
      ...
    </Fragment>
);

CSS Variables는 특정한 section이나 글로벌에 변수를 선언하고 해당하는 범위 내에서 변수를 사용할 수 있는 시스템이다.

section {
    --primary-color: #C8102E;
}

:root {
    --secondary-color: #00B2A9;
}

개발자 도구를 열면 이런 식으로 확인할 수 있다.

지원하는 브라우저는 다음과 같다.

요구사항

  1. CSS Variables를 프로젝트별로 저장하고, Editor에서 편집할 수 있다.
  2. App에 주입되는 CSS에 var(--variable) 문법을 사용하면 CSS Variables가 적용된다.

Editor는 어떤 변수명에 어떤 값이 매칭되는지만 알면 되고, App의 :root에 CSS Variables를 저장한다.

구현

1. Editor: CSS Variables 생성과 수정 패널

UI 구현은 단순하다. 동적으로 추가/삭제 가능한 폼을 만들고, 저장하는 API와 연동한다.

예약어, 문법, 중복 등 validation 처리한다.

2. App: root 엘리먼트에 변수 주입

일반적으로 .css 파일을 통해 :root에 변수를 저장하지만, 파일을 통해 주입하는 것보다 App의 root 엘리먼트에 접근하여 CSS 변수를 입력하는 방식이 간결하다고 생각했다.

  1. App의 설정들을 다루는 파일에 Provider를 추가하고, 저장한 cssVariables를 받아온다.
  2. root 엘리먼트를 선택한다.
  3. root 엘리먼트 스타일에 setProperty 로 변수를 주입한다.
export const NadooAppCSSVariablesContextProvider = ({
  cssVariables = {},
  children,
}: NadooAppCssVariables & { children: ReactNode }) => {

  useEffect(() => {
    const root = document.querySelector(':root') as HTMLElement;

    Object.entries(cssVariables).forEach(([key, value]) => {
      root?.style.setProperty(key, value);
    });
  }, [cssVariables]);

  return (
    <NadooAppCssVariablesContext.Provider
      value={{ cssVariables }}
    >
      {children}
    </NadooAppCssVariablesContext.Provider>
  );
};

App에 CSS Variables가 설정되어 바로 사용할 수 있다.

3. App: 변수 수정/삭제

Editor에서 Variables를 편집하면 기존에 등록됐던 프로퍼티가 제거돼야 한다. 데이터베이스에서는 이전 변수를 따로 저장하고 있지 않으므로, 렌더링될 때마다 기존에 root 저장돼있던 프로퍼티를 제거하고 다시 추가하는 매커니즘을 구현했다.

렌더링에 영향을 미치지 않도록 이전 변수를 저장하는 데에 ref를 사용했다.

  1. 렌더링 이후 effect가 실행되면 ref에서 이전의 cssVariables를 가져와 root에서 제거한다.
  2. 새로운 cssVariables를 프로퍼티에 세팅한다.
  3. ref에 현재 cssVariables를 저장한다.
  const previousCssVariablesRef = useRef(cssVariables);

  useEffect(() => {
    const previousCssVariables = previousCssVariablesRef.current;

    const root = document.querySelector(':root') as HTMLElement;

    Object.entries(previousCssVariables).forEach(([key, value]) => {
      root?.style.removeProperty(key);
    });

    Object.entries(cssVariables).forEach(([key, value]) => {
      root?.style.setProperty(key, value);
    });

    previousCssVariablesRef.current = cssVariables;
  }, [cssVariables]);

@media (max-width: var(--sm-breakpoint))

CSS Variables를 사용하는 개발자 대부분이 이런 문법을 본 적이 없을 것이다. 왜냐하면 틀린 문법이기 때문이다.
미디어 쿼리에서는 CSS Variables를 사용할 수 없다. 하지만 Theme System에서 브레이크포인트는 핵심 기능이기 때문에 반드시 지원해야 했다.

그래서 찾은 대안이 SASS이다. SASS는 CSS 컴파일러로, CSS 문법을 간결하고 다채롭게 쓸 수 있게 돕는다. SCSS와 SASS는 약간의 문법 차이가 있는데, SASS 컴파일러로 두 문법 모두 커버 가능하다.

SCSS Playground로 변수를 선언하고 미디어 쿼리에서 사용해보았다.

sass 라이브러리를 사용하여 직접 root 엘리먼트에 접근하지 않고, scss로 작성된 string을 css로 변환하여 jsx로 resolve하여 사용한다.

  1. sass 모듈을 불러온다.
  2. cssVariables를 name: value; ... 형식의 string으로 변환한다.
  3. variablesString과 css를 합친 뒤 sass.compileString 을 통해 css로 컴파일한다.
  4. 컴파일한 css를 jsx로 resolve한다.
    4-1. 컴파일 과정에 오류가 있는 경우 기존의 cssString만 리턴하여 resolve한다.
  const sass = require('sass');

  const compileSCSS = (variablesString: string, cssString: string) => {
    try {
      return sass.compileString(variablesString + '\n' + cssString).css;
    } catch (error) {
      return cssString;
    }
  };

  const variablesCss = useMemo(
    () =>
      Object.entries(cssVariables)
        .filter(([key]) => key.startsWith('$'))
        .map(([key, value]) => `${key}: ${value};`)
        .join('\n'),
    [cssVariables],
  );

  const { className, styles } = useMemo(
    () =>
    styledCss.resolve`${compileSCSS(variablesCss, css)}`,
    [variablesCss, css],
  );

  return (
      <Fragment>
        {styles}
        ...
      </Fragment>
  );

provider를 통해 직접 dom에 접근할 필요가 없어 매커니즘이 간결해졌고, 미디어 쿼리를 지원할 수 있게 되었다. 또한 Editor에서도 sass를 이용해서 validation 처리를 하여, CSS 수정 과정에서 문법 오류가 있는 경우 핸들링해주어 기존에 부족했던 기능을 보완했다.

이번 시간엔…

오늘은 노코드 툴을 개발하는 이유와 사용자들에게 주고 싶은 가치, 그리고 CSS Variables 시스템을 설계하고 구현한 내용을 이야기했다.
입사 후에 처음으로 큰 시스템 구축을 맡으면서 App과 Editor 시스템을 더 잘 이해하게 되었고, CSS Variables와 SASS에 대해서도 알 수 있어 많은 것을 남긴 작업이었다.

다음 시간엔…

CSS Editor에서 자동완성으로 CSS Variables를 더욱 편하게 사용할 수 있게 보완하였고 그 내용을 담으려고 한다.




Read more

AI 홈페이지 제작, 이제는 기획자 대신 지시자가 되세요!

AI 홈페이지 제작, 이제는 기획자 대신 지시자가 되세요!

전통적인 홈페이지 제작은 기획자에게 많은 것을 요구했었어요. 디자인 컨셉을 정하고, 레이아웃을 구상하며, 각 페이지에 들어갈 모든 문구와 이미지를 직접 고민해야 했었어요. 시간과 노력이 많이 드는 작업이었죠 ㅠㅠ 하지만 AI 시대에는 우리의 역할이 완전히 달라졌어요! 이제 더 이상 '기획자'가 될 필요가 없고, 우린 오직 '지시자'가

By 나두아이오
새로운 홈페이지를 위한 AI 프롬프트 템플릿

새로운 홈페이지를 위한 AI 프롬프트 템플릿

AI 홈페이지 빌더를 사용하면 여러분의 아이디어를 순식간에 현실로 만들 수 있어요. 믿기 어려우시겠지만 진짜예요! 근데 어떤 프롬프트를 사용해야 할지 막막할 때가 있죠. 여러분의 고민을 덜어드리기 위해, 비즈니스 유형별로 바로 사용할 수 있는 AI 프롬프트 템플릿을 준비했습니다. 아래 템플릿을 참고하여 여러분의 비즈니스에 맞는 내용을 추가하거나 수정해서 사용해 보세요! 1. 소상공인/로컬

By 나두아이오
AI 홈페이지 제작 프롬프트 작성법

AI 홈페이지 제작 프롬프트 작성법

AI 홈페이지 빌더를 사용하면 누구나 손쉽게 전문가급 웹사이트를 만들 수 있습니다. 하지만 어떤 프롬프트(지시)를 입력하느냐에 따라 결과물의 완성도는 크게 달라져요. AI는 사용자의 의도를 완벽히 이해하는 '마법'이 아니기 때문이죠. AI에게 원하는 홈페이지를 얻는 마법의 주문, 바로 '구체적인 프롬프트'입니다. AI에게 원하는 결과를 얻는 3가지

By 나두아이오
SEO는 물론 AEO까지, AI 시대 검색 엔진 최적화 전략

SEO는 물론 AEO까지, AI 시대 검색 엔진 최적화 전략

요즘 남녀노소 할 것 없이 정보가 궁금하면 챗GPT에 물어봅니다. 점점점 네이버나 구글에 검색하지 않는 시대가 됐지요. 그만큼 AI가 우리 생활과 행동에 큰 영향을 주고 있고, 검색이 아닌 AI 대화로 정보를 얻어가는 행태 때문에 홈페이지 노출 전략도 달라집니다. AI 시대에는 홈페이지의 노출 전략을 근본적으로 달라요. 챗GPT와 구글의 AI Overviews나 네이버의 AI

By 나두아이오