Hygen을 활용한 반복 작업 자동화와 DX 개선하기

keemsebeen·2025년 10월 8일
14

이번 글은 hygen을 활용해 반복되는 작업을 자동화하고, 개발자 경험(dx)을 개선한 과정을 소개합니다.

배경 - 반복되는 생성 작업

프로젝트를 진행하다 보면, 가장 먼저 공통 컴포넌트 작업을 시작하게 됩니다.

이때 하나의 컴포넌트를 만들때마다 Button.tsx, Button.styled.tsx, Button.stories.tsx, index.ts 등 여러 파일을 생성하고, 각 파일에 반복적인 보일러플레이트 코드를 작성하게 됩니다.

이 과정은 시간이 지날수록 개발 피로도가 높아지고 네이밍, 컨벤션 등등 실수가 발생하기 쉽습니다. 또한 이러한 파일들은 대부분 기본 구조와 틀이 고정적이어서 실제로는 이름만 바뀌는 경우가 많습니다.

  • 스토리북 파일은 meta, tags, parameters 구조가 항상 동일하고,
  • 스타일 파일은 import 문과 styled-components의 기본 형식이 반복되며,
  • index 파일은 export 문의 패턴이 고정되어 있습니다.

즉, 매번 같은 틀을 반복 작성하는 비효율이 존재합니다.

페이지 단위도 마찬가지인데요. 새로운 페이지를 추가할 때는 기존 컨벤션에 맞춰 폴더를 구성해야 하므로 동일한 작업을 반복하게 됩니다. 예를 들어 저희 프로젝트는 다음과 같은 폴더 구조를 가지고 있는데요.

└── src/ 
    ├── Event/
    │   ├── components/
    │   ├── hooks/
    │   ├── pages/
    │   ├── utils/
    │   └── index.ts  
    └── Home/
        ├── components/
        ├── hooks/
        ├── pages/
        ├── utils/
        └── index.ts

새로운 도메인 페이지가 추가된다면, components , hooks , pages , utils 와 같은 폴더를 동일하게 만들어야 합니다.

이처럼 파일 생성이나 폴더 구조 설정 등 반복적인 작업 외에도, 팀 내 컨벤션을 일관되게 유지하는 일은 쉽지 않습니다.

예를 들어 Storybook을 사용할 경우 모든 컴포넌트에 description을 작성해야 하거나, 파일 이름을 파스칼/케밥 케이스 규칙에 맞게 작성해야 합니다. 이러한 규칙들은 매번 기억하고 수동으로 적용하는 것은 번거롭고, 일부를 놓치거나 누락하기도 쉽습니다. 따라서 이러한 반복 작업과 컨벤션 적용을 자동화할 수 있는 도구가 필요하다고 판단했습니다.

해결 - Hygen 도입

이 문제를 해결하기 위해, 처음에는 스크립트나 CLI 명령어를 직접 만들어 사용하는 방법도 고려했습니다. 하지만 이 방식은 템플릿 관리가 어렵고 구현을 위해 추가적인 학습과 시간이 필요하다는 한계가 있었습니다.

그러던 중 Hygen을 알게 되었고, 이를 도입해 반복 작업을 자동화할 수 있었습니다.

hygen이란

프로젝트 내부에 템플릿을 정의해두고 CLI 명령어 한 줄로 파일 생성과 코드 삽입을 자동화할 수 있는 경량 스캐폴딩 도구입니다. 컴포넌트, 도메인 폴더구조, 테스트 코드 처럼 항상 비슷한 패턴으로 작성되는 요소들을 템플릿으로 관리해 일관된 형태로 쉽고 빠르게 파일 생성을 도와줍니다.

아래와 같이 명령어 한 줄로 보일러플레이트 파일들을 자동 생성할 수 있습니다.

특징 - Hygen의 동작 방식

hygen은 프로젝트 내부의 _template 폴더를 기반으로 동작합니다. 해당 폴더 안에는 생성하고자 하는 대상과(component, page) 액션에 따라 디렉터리를 구성합니다.

예를 들어 components라는 generator를 만들고 싶다면 다음과 같이 폴더를 구성합니다.

_templates/
  └── components/
      └── new/
          ├── prompt.js
          ├── main.ejs.t
          ├── stories.ejs.t
          └── index.ejs.t

Hygen의 동작 방식은 크게 세 가지 특징으로 나눌 수 있습니다. 아래에서 각각을 살펴보겠습니다.

1. EJS 문법으로 동적 치환

hygen은 템플릿 엔진으로 ejs를 사용합니다. <%= name %> 처럼 변수를 삽입하거나 <% if (condition) { %> 구문을 활용해 조건 분기 처리가 가능합니다. 이를 통해 파일 이름, 경로, 내용 등을 상황에 맞게 유연하게 제어할 수 있습니다.

2. Front-matter로 파일 생성 위치 정의

.ejs.t 템플릿 파일 상단에는 —-로 구분된 front-matter를 작성하여, 어디에 어떤 파일을 생성할지 지정합니다.

저는 작업을 하면서 to 옵션을 많이 활용했는데요. 해당 옵션은 생성할 파일의 경로를 지정하는 역할을 합니다. 명령어 실행하면, <%= name %> 부분이 실제 입력값으로 치환되어 해당 경로에 파일이 자동 생성됩니다.

---  
to: src/components/<%= name %>/<%= name %>.tsx  
---  

(다양한 옵션은 공식문서에서 확인해주세요!)

3. 프롬프트/인자 처리

prompt.js 파일을 통해 템플릿 생성 시 필요한 CLI에서 대화형으로 입력받을 수 있습니다.
(또는 --key value 형태로 직접 인자를 전달해도 됩니다.)

정리

_templates/
  └── component/
      └── new/
          ├── prompt.js
          ├── main.ejs.t
          ├── stories.ejs.t
          └── index.ejs.t
파일/폴더설명
_templates/Hygen이 템플릿을 찾는 기본 경로입니다. 모든 생성기는 여기 아래에 위치합니다.
component/생성기의 이름입니다. 예: hygen component new 명령으로 실행합니다.
new/액션(Action)입니다. “new”는 새로운 템플릿을 생성하는 명령어로 쓰입니다.
*.ejs.t실제로 생성될 템플릿 파일입니다. 내부에는 front-matter(---)와 EJS 문법(<%= %>)이 포함됩니다.
prompt.js실행 시 입력받을 값을 정의하는 파일입니다. ex. “컴포넌트 이름을 입력하세요.”

예시 - 템플렛 생성 과정

Hygen에서는 프롬프트를 사용하지 않는 방식과 프롬프트를 사용하는 방식 두 가지 모두 지원합니다. 아래에서 각각의 예시를 살펴보겠습니다.

0. 초기 세팅

들어가기에 앞서 먼저 hygen을 전역으로 설치하고 초기 설정을 진행합니다. (전역 설치를 원치 않는 경우 npx를 사용해도 됩니다.)

npm i -g hygen
hygen init self

1. 프롬프트 없이 사용하는 예시

(_template 폴더만 남겨둔 채 다른 예시 파일들은 삭제한 채로 진행했습니다.)

  1. components/new 폴더를 생성합니다.

    해당 폴더가 명령어 실행 기준이 됩니다. 따라서 사용목적에 따라 폴더를 구성하면 됩니다. 저는 컴포넌트 생성 시 사용할 템플릿을 만들어서 component/new라고 지어주었습니다.

  2. 필요한 템플릿 파일들을 준비합니다. 이때 사용자 입력값을 치환하기 위해 <%= components %> 변수를 사용했습니다.

    저희 서비스는 Button.stories.tsx, Button.tsx, index.ts 파일들을 사용하고 있는데요. 각각에 맞춰 템플릿 파일들을 준비했습니다. (위 링크에서 전체 템플릿 코드를 확인할 수 있습니다.)
    main.ejs.t(ex. Button.tsx)

    ---
    to: src/shared/ui/<%= components %>/<%= components %>.tsx
    ---
    
    type <%= components %>Props = {};
    
    export function <%= components %>({}: <%= components %>Props) {
      return <></>;
    };
  3. 이제 CLI 명령어을 실행합니다. 앞서 <%= components %> 변수를 사용했기 때문에, 실행 시 해당 인자를 함께 넘겨줘야 합니다.

    hygen components new --components Sera

명령어를 실행하면, 지정한 경로에 컨벤션에 맞춘 파일들이 자동으로 생성되는 것을 확인할 수 있습니다.

2. 프롬프트를 사용하는 예시

앞선 방식은 명령어 실행 시 직접 인자를 넘겨주는 형태였는데요. Hygen은 이 외에도, CLI 상에서 입력을 받아 처리하는 대화형 프롬프트 방식을 지원합니다.
이를 통해 사용자는 매번 인자를 기억할 필요 없이, 필요한 값을 단계별로 입력받을 수 있습니다.

  1. 동일 폴더에 prompt.js 파일을 생성합니다.


아래 예시는 컴포넌트 이름을 PascalCase로 입력받는 프롬프트 설정입니다. 입력값이 없거나 영어가 아닐 경우, 에러 메시지를 출력해 잘못된 입력을 방지합니다

module.exports = {
  prompt: ({ prompter, args }) =>
    prompter
      .prompt({
        type: 'input',
        name: 'components',
        message: '공통 컴포넌트 이름을 PascalCase로 입력해 주세요. (ex. Button)',
      })
      .then(({ components }) => {
        if (!components) {
          throw new Error('컴포넌트 이름을 입력해 주세요.');
        }
        if (!RegExp(/^[a-zA-Z,-]*$/).test(components)) {
          throw new Error('영어로 입력해 주세요.');
        }
    });
};
  1. 이제 CLI 명령어을 실행합니다.
	hygen components new 

명령어를 실행하면, 프롬프트를 통해 컴포넌트 이름을 입력받고, 해당 값이 템플릿에 반영되어 지정된 위치에 파일이 자동 생성됩니다.

첫번째 인자 전달 방식은 빠른 실행에 유리하고, 프롬프트 방식은 가이드가 필요한 입력값 관리에 유리합니다. 두 방식을 상황에 맞게 병행하면, 빠른 실행과 일관된 컨벤션 관리 모두를 충족할 수 있습니다.

정리 – 도입 후 장단점

도입 후 가장 큰 장점은, 반복적인 작업들에서 해방되었다는 점인데요. 예를 들어, 스토리북 코드는 다른 폴더에 있는 코드를 긁어와 import만 변경하거는 등 컴포넌트를 하나 만드는데 들었던 1분 이상의 시간들이 이제는 15초 이내에 가능해졌습니다.

이 외에도 개발 생산성 향상, 휴먼 에러 방지 측면에서 큰 강점을 느꼈습니다. cli 명령어 한 줄로 컨벤션에 맞는 파일을 쉽게 생성할 수 있어 실제 로직 구현에 더욱 집중할 수 있었어요.

물론 아쉬운 점도 있습니다.프로젝트 구조나 컨벤션이 바뀔 때마다 템플릿을 함께 수정해야 하므로 관리 포인트가 늘어나고, 간단한 파일 생성에는 오히려 직접 작성보다 번거롭게 느껴질 수 있습니다.

장단점을 모두 고려했을 때, Hygen은 반복적인 파일 생성이 빈번한 프로젝트에서 충분히 도입할 만한 가치가 있다고 생각합니다. 특히 3명 이상의 팀에서 명확한 컨벤션을 유지하고 싶다면 강력히 추천합니다!


개발을 하면서 실제 코드들 레포도 첨부합니다!
실제 개발코드1

profile
프론트엔드 공부 중인 김세빈입니다. 👩🏻‍💻

0개의 댓글