Hygen 처음 적용해보기
4 minute read
2024-07-15
세팅법
원래 기본적으로 맥에서는 패키지 매니저인 brew 를 사용하는데 hygen 이 없다고 나온다. 그래서 npm 으로 전역 설치했다.
hygen 전역 설치
npm i -g hygenhygen 초기화
hygen init self이 명령어를 호출하면 아래와 같이 내장 파일들이 설치된다.

여기서 생성된 폴더명으로 명령어를 칠 수 있게 된다.
hygen generator {help/new/with-prompt} ...나는 여기서 react 라는 템플릿 세트를 만들려고 한다. 그렇다면 아래와 같이 입력해준다.
hygen generator new react나만의 템플릿 덩어리 만들기
그럼 react 라는 디렉토리가 새로 만들어진 걸 볼 수 있다. 거기에 원하는 자동 생성을 원하는 정적 파일들을 .ejs.t 확장자로 생성해줘야 한다.

이렇게 정한 템플릿을 기준으로 name 옵션을 지정해서 동적인 파일을 생성할 수 있다.
hygen react new --name FooComponent결과적으로 아래와 같이 생성된다.

물론 템플릿 파일 상단에 meta 데이터를 꼭 빠뜨리면 안된다.
---
to: src/components/<%= h.changeCase.pascal(name) %>/style.ts
---tilda 와 ejs 같이 사용하기
---
to: "<%= `src/stories/ETC/${name}/${name}.stories.ts` %>"
---
import type { Meta, StoryObj } from '@storybook/react';
import <%= name %> from './<%= name %>';
const meta: Meta<typeof <%= name %>> = {
title: 'ETC/<%= name %>',
component: <%= name %>,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
// argTypes: {},
// args: {},
} satisfies Meta<typeof <%= name %>>;
export default meta;
type Story = StoryObj<typeof <%= name %>>;
export const Base: Story = {
// args: {},
};혹은
<%= `${name}` %>이렇게 사용할 수도 있다.
prompt
function toPascalCase(str) {
return str
.split(/[\s_-]+/) // 공백, 밑줄, 대시로 문자열을 분할
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // 각 단어의 첫 글자는 대문자로, 나머지는 소문자로 변환
.join(''); // 단어를 결합하여 최종 결과 반환
}
function isKebabCase(str) {
return /^[a-z]+(-[a-z]+)*$/.test(str);
}
/**
* @typedef {import('enquirer').} Enquirer
*/
/**
* @param {object} options - The options for the prompt function.
* @param {Enquirer} options.prompter - The prompter instance.
* @param {any} options.args - The arguments for the prompt function.
* @returns {Promise<void>}
*/
const prompt = async ({ prompter, args }) => {
// 함수 본문
const componentPromptResult = await prompter.prompt({
type: 'input',
name: 'name',
message: '카테고리 컴포넌트 이름을 kebab-case 로 입력하세요.',
});
if (!componentPromptResult.name) {
throw new Error('컴포넌트 이름을 입력하세요!');
}
if (!isKebabCase(componentPromptResult.name)) {
throw new Error('컴포넌트 이름은 kebab-case 이어야 합니다.');
}
const meta = {
name: toPascalCase(componentPromptResult.name),
// files: multiSelectPromptResult.files, // 다른 값 넘길 때
args,
};
console.log(meta);
return meta;
};
// eslint-disable-next-line no-undef
module.exports = {
prompt,
};
만약 여러 선택을 하려고 한다면 아래와 같이 prompt 추가할 수 있다.
const multiSelectPromptResult = await prompter.prompt({
type: 'multiselect',
name: 'files',
message: '생성할 파일 목록을 선택해주세요.',
initial: ['style', 'storybook'],
choices: [
{
name: 'style',
message: `${componentPromptResult.name}.style.ts`,
},
{
name: 'storybook',
message: `${componentPromptResult.name}.stories.tsx`,
},
{
name: 'type',
message: `${componentPromptResult.name}.type.ts`,
},
],
});