728x90

title: UI 패키지 만들기
date created: 2024-10-03
date modified: 2024-10-03
tags: [pnpm, monorepo, side project]
links: []


모노레포에서 공통 UI를 담당할 패키지를 만들어보자.

1. 패키지 구조 설정

$ mkdir packages
$ cd packages
$ mkdir ui
$ cd ui
$ pnpm init

하위 프로젝트 명령어를 위해 root package.json에 스크립트를 지정해주자.
--filter 옵션을 사용하면 특정 패키지에 대한 명령어를 실행할 수 있다.

{
  "name": "monorepo",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "ui": "pnpm --filter @packages/ui"
  },
  "keywords": [],
  "author": "WONILLISM",
  "devDependencies": {
    "prettier": "^3.3.3",
    "typescript": "^5.6.2"
  }
}

2-1. 의존성 설치

$ pnpm ui add react react-dom tslib
$ pnpm ui add -D @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-json @types/react @types/react-dom rollup rollup-plugin-peer-deps-external rollup-plugin-typescript2 rollup-plugin-terser

해당 의존성들은 아래와 같은 역할을 한다.

  • tslib : TypeScript 코드를 번들링하고, 타입 정의를 포함시킴, 번들링 과정에서 중복 포함되는 것을 방지
  • @rollup/plugin-commonjs : CommonJS 모듈을 ES6로 변환하여 Rollup에서 사용할 수 있게 해줌
  • @rollup/plugin-node-resolve : Node.js의 모듈 해석 알고리즘을 사용하여 외부 모듈을 찾아 번들에 포함시킴
  • @rollup/plugin-json : JSON 파일을 번들에 포함시키고, 모듈 해석 알고리즘을 사용하여 외부 모듈을 찾아 번들에 포함시킴
  • @types/react : React 라이브러리의 타입 정의를 제공
  • @types/react-dom : React DOM 라이브러리의 타입 정의를 제공
  • rollup : 자바스크립트 모듈 번들러
  • rollup-plugin-peer-deps-external : 프로젝트의 종속성을 외부 모듈로 처리하여 번들링 과정에서 중복 포함되는 것을 방지
  • rollup-plugin-typescript2 : TypeScript 코드를 번들링하고, 타입 정의를 포함시킴
  • rollup-plugin-terser : 번들된 코드를 최적화하여 번들 크기를 줄임

다음으로 peerDependencies를 설정해주자.

{
  "peerDependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  }
}

이제 번들링을 위한 설정 파일을 만들어주자.

$ touch rollup.config.mjs
// javascript/typescript 프로젝트 번들링하기 위한 rollup 설정

import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript2";
import json from "@rollup/plugin-json";
import { terser } from "rollup-plugin-terser";

export default {
  input: "src/index.ts", // 메인 엔트리 경로
  output: [
    // CommonJS 형식으로 dist/index.js 생성
    // 소스맵 생성
    {
      file: "dist/index.js",
      format: "cjs",
      sourcemap: true,
    },
    // ES Module 형식으로 dist/index.esm.js 생성
    // 소스맵 생성
    {
      file: "dist/index.esm.js",
      format: "esm",
      sourcemap: true,
    },
  ],
  plugins: [
    peerDepsExternal(), // peerDependencies에 있는 모듈을 외부 모듈로 처리 - 번들링에 포함되지 않음
    resolve(), // 모듈 경로 해석
    commonjs(), // CommonJS 모듈을 ES6 Module로 변환
    typescript({
      tsconfigOverride: {
        compilerOptions: {
          declaration: true,
          declarationDir: "./dist",
        },
      },
      rollupCommonJSResolveHack: true,
      clean: true,
    }), // typescript 파일을 컴파일, 선언 파일( .d.ts ) 생성
    json(), // json 파일을 읽어오는 플러그인
    terser(), // 코드 압축, 난독화
  ],
};

2-2. 빌드 스크립트 추가

{
  ...
  "scripts": {
    "build": "rollup -c rollup.config.mjs",
    "storybook": "storybook dev -p 6006",
    "storybook:build": "storybook build"
  }
  ...
}

3. 스토리북 설정

스토리북은 컴포넌트 라이브러리를 시각적으로 테스트하고 문서화하는 데 사용되는 도구이다.

$ pnpm dlx storybook@latest init 

3-1. typescript 설정

{
  // 상위 디렉토리의 tsconfig.json 설정을 상속
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    // 컴파일된 파일이 저장될 디렉토리
    "outDir": "dist",
    // 사용할 라이브러리 정의
    "lib": ["ES6", "dom"],
    // 소스맵 생성 여부
    "sourceMap": true,
    // JavaScript 파일 컴파일 허용 여부
    "allowJs": false,
    // React JSX 처리 방식
    "jsx": "react-jsx",
    // 모듈 해석 방식
    "moduleResolution": "node",
    // 소스 파일의 루트 디렉토리
    "rootDirs": ["src"],
    // 모듈 해석을 위한 기본 경로
    "baseUrl": ".",
    // 엄격한 타입 체크 옵션들
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    // 사용하지 않는 지역 변수 체크
    "noUnusedLocals": true,
    // CommonJS 모듈과 ES 모듈 간의 상호 운용성 개선
    "esModuleInterop": true,
    // 선언 파일(.d.ts) 생성
    "declaration": true,
    // 데코레이터 메타데이터 생성
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    // JSON 모듈 import 허용
    "resolveJsonModule": true,
    // 헬퍼 함수 사용 (코드 중복 감소)
    "importHelpers": true,
    // 모듈 경로 별칭 설정
    "paths": {
      "tslib": ["path/to/node_modules/tslib/tslib.d.ts"]
    }
  },
  // 컴파일에 포함할 파일 패턴
  "include": ["src/**/*"],
  // 컴파일에서 제외할 파일 패턴
  "exclude": ["node_modules", "dist", "**/*.stories.tsx"]
}
728x90
300x250
WONILLISM