생각/react

[npm 라이브러리 제작기] 라이브러리 만들 때 어떻게 만들까?

kyunghoonk00k 2025. 2. 24. 19:29
반응형

 

 

"라이브러리 만드는 게 보통 어떻게 진행되는 걸까?"

처음엔 막막했다


라이브러리를 만든다는 게 뭔가 대단해 보였는데, 막상 시작하려니 뭐부터 해야 할지 감이 안 왔다. "뭘 만들어야 유용할까?" 고민하다가, React 프로젝트에서 자주 쓰일 법한 아코디언 컴포넌트를 만들어보자는 생각이 들었다. 타입스크립트를 쓰면 타입도 깔끔하게 보이니까 이걸로 해보자고 마음먹었다.


1. 기본 세팅

mkdir react-common-components-library
cd react-common-components-library
그리고 npm init -ypackage.json을 바로 만들었다. 이름은 react-common-components-library로 정했는데, npm에서 검색해보니 중복이 없어서 괜찮았다. 처음 설정은
{
  "name": "react-common-components-library",
  "version": "0.0.1",
  "description": "A common React components library built with TypeScript",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc"
  },
  "author": "kyunghoonkook",
  "license": "MIT"
}

 

npm install --save-dev typescript
npx tsc --init

 

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "jsx": "react",
    "outDir": "./dist",
    "rootDir": "./src",
    "declaration": true,
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

 

2. 아코디언 컴포넌트 만들기


뭘 만들까 하다가 아코디언으로 시작했다. 리스트를 접었다 폈다 할 수 있는 컴포넌트라 실무에서도 유용할 것 같았다. src/components 폴더를 만들고:

 

// src/components/Accordion.tsx
import React, { useState } from 'react';

interface AccordionItem {
  id: string;
  title: string;
  content: React.ReactNode;
}

interface AccordionProps {
  items: AccordionItem[];
}

const Accordion = ({ items }: AccordionProps) => {
  const [openItemId, setOpenItemId] = useState<string | null>(null);

  const toggleItem = (id: string) => {
    setOpenItemId(openItemId === id ? null : id);
  };

  return (
    <div>
      {items.map((item) => (
        <div key={item.id}>
          <button
            onClick={() => toggleItem(item.id)}
            style={{
              width: '100%',
              padding: '10px',
              textAlign: 'left',
              backgroundColor: '#f1f1f1',
              border: 'none',
              cursor: 'pointer',
            }}
          >
            {item.title}
          </button>
          {openItemId === item.id && (
            <div style={{ padding: '10px', backgroundColor: '#fff' }}>
              {item.content}
            </div>
          )}
        </div>
      ))}
    </div>
  );
};

export default Accordion;

 

이 아코디언은 items 배열을 받아서 각 항목을 버튼으로 보여주고, 클릭하면 내용을 펼치게 했다.
 

3. 빌드 과정


이제 이걸 다른 프로젝트에서 쓸 수 있게 컴파일해야 했다. package.json을 수정했다:

 

{
  "name": "react-common-components-library",
  "version": "0.0.1",
  "description": "A common React components library built with TypeScript",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc"
  },
  "author": "kyunghoonkook",
  "license": "MIT",
  "devDependencies": {
    "typescript": "^4.9.5",
    "@types/react": "^18.0.27"
  },
  "peerDependencies": {
    "react": "^18.0.0"
  },
  "files": ["dist"]
}​

 

4. 스토리북으로 테스트

npx sb init​
stories 폴더에 Accordion.stories.tsx를 만들어서 테스트 코드를 썼다:
// stories/Accordion.stories.tsx
import React from 'react';
import { Meta, Story } from '@storybook/react';
import Accordion from '../src/components/Accordion';

export default {
  title: 'Components/Accordion',
  component: Accordion,
} as Meta;

const Template: Story<AccordionProps> = (args) => <Accordion {...args} />;

export const Default = Template.bind({});
Default.args = {
  items: [
    { id: "1", title: "Item 1", content: "This is item 1 content" },
    { id: "2", title: "Item 2", content: "This is item 2 content" },
  ],
};​
브라우저에서 아코디언이 잘 나오고, 버튼을 누르면 내용이 펼쳐졌다. 스토리북 덕에 컴포넌트를 직관적으로 확인할 수 있어서 편했다. 
 

5. 배포까지


npm에 올리기로 했다. 로그인하고:

 

npm login

 

빌드하고 배포
 
npm run build
npm publish --access public
npm 사이트에서 보면 0.0.1로 올라가 있었다. 처음이라 좀 긴장했는데, 해보니까 별거 아니었다.

 

이 과정을 떠올려보니, 라이브러리 만드는 건 몇 가지 단계를 거치는 거였다. 아이디어 정하고, 코드 쓰고, 빌드하고, 테스트하고, 배포하는 과정. 타입스크립트로 타입을 잡아주니까 마음이 놓였고, 스토리북으로 테스트하니까 더 편했다. 빌드할 때 실수했던 게 아쉽긴 한데, 그걸 고치면서 배운 것도 있다. 다음엔 스타일을 props로 받거나 컴포넌트를 더 추가해볼까? 이렇게 정리하다 보니 또 만들어보고 싶어진다.
반응형