카테고리 없음

컴포넌트를 라이브러리로 관리해보자구요?

Dev.JH 2025. 3. 1. 20:31

npm

디자인 시스템을 관심을 바탕으로 현재 진행 중인 프로젝트에 있는 컴포넌트들을 라이브러리화 해서 다른 프로젝트에서도 설치 한번으로 컴포넌트들을 사용할 수 있으면 좋을 것 같다라는 생각을 하였다.

굳이 이러한 일을 왜하냐면 규모가 있고, 프론트엔드 개발 생산성에 초점을 맞춘 회사라면 다양한 프로젝트에서 라이브러리화 된 컴포넌트를 적극적으로 사용할 수 있겠다는 생각이 들어서이다.

 

자 그럼 거두절미하고 라이브러리로 만드는 여정을 떠나보자!


버튼 컴포넌트 라이브러리로 만들기

1. tsconfig 파일

  • declaration 옵션으로 타입 선언 파일(.d.ts) 생성
  • outDir에 컴파일 산출물을 저장
  • 라이브러리 소스는 src 폴더에 위치
{
  "compilerOptions": {
    "target": "ES5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "ESNext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react-jsx",
    "declaration": true,
    "declarationDir": "./dist/types",
    "outDir": "./dist",
    "emitDeclarationOnly": false
  },
  "include": ["src"]
}

2. pacakge.json

  • "files" 필드로 배포 시 포함할 파일(여기서는 dist)을 지정
  • peerDependencies로 React 버전 요구사항 지정
{
  "name": "wedy-component-library",  // 내 라이브러리 이름
  "version": "1.0.0",   // 버전
  "description": "wedy component library",  // 라이브러리 설명
  "main": "dist/index.js",
  "module": "dist/index.esm.js",
  "types": "dist/types/index.d.ts",
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "tsc"
  },
  "peerDependencies": {
    "react": ">=17.0.0",
    "react-dom": ">=17.0.0"
  },
  "devDependencies": {
    "typescript": "^5.0.0"
  }
}

3. gitignore

node_modules/
src/
public/
tsconfig.json

4. 라이브러리에 올릴 button component

버튼 컴포넌트의 상대 경로 src/components/Button.tsx

import { cva, type VariantProps } from "class-variance-authority";
import { forwardRef, type ButtonHTMLAttributes } from "react";

const buttonVariants = cva(
  "inline-flex px-[3px] gap-[6px] items-center justify-center word-break:keep-all disabled:pointer-events-none disabled:opacity-30 transition-colors duration-200 transition",
  {
    variants: {
      variant: {
        main: "bg-gray-300 hover:bg-gray-600 text-white",
        none: "text-white",
      },
      rounded: {
        xl: "rounded-[4rem]",
        lg: "rounded-lg",
        md: "rounded-md",
        sm: "rounded-sm",
        none: "rounded-none",
      },
      width: {
        full: "w-full",
        register: "w-[230px]",
      },
      height: {
        xl2: "h-[80px]",
        xl: "h-[58px]",
        lg: "h-[48px]",
        md: "h-[40px]",
        sm: "h-[35px]",
      },
      size: {
        lg: "text-[1.6rem] font-bold",
        md: "",
      },
    },
    defaultVariants: {
      variant: "main",
      rounded: "md",
      width: "full",
      size: "md",
      height: "lg",
    },
  }
);

interface ButtonProps
  extends ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, rounded, width, size, height, ...props }, ref) => {
    return (
      <button
        className={buttonVariants({
          variant,
          rounded,
          width,
          size,
          height,
          className,
        })}
        ref={ref}
        {...props}
      />
    );
  }
);
Button.displayName = "Button";

 

5. src/index.ts

export * from "./components/Button";

🚀 결과물

제가 배포한 라이브러리 구경하러 와보세요~ (별거 없음)

wedvice-component-libarary - npm

 

wedvice-component-libarary

Latest version: 1.2.0, last published: 3 minutes ago. Start using wedvice-component-libarary in your project by running `npm i wedvice-component-libarary`. There are no other projects in the npm registry using wedvice-component-libarary.

www.npmjs.com