pnpm + tsdown으로 React 라이브러리 만들기 ② - React 라이브러리 생성
pnpm + tsdown으로 React 라이브러리를 만드는 과정에서 React 라이브러리 생성 방법에 대해 정리한 페이지입니다.
Tags
monorepo, pnpm, React, tsdown
Environment
pnpm v10.32.1
react v19.2.3
tsdown v0.21.3
@tsdown/css v0.21.4
1. 개요
pnpm + tsdown으로 React 라이브러리를 만드는 방법에 대해 정리한 페이지입니다.
총 5개의 Part로 분리하여 작성하였으며, 이 페이지에서는 React 라이브러리 생성 과정을 다룹니다.
- 1. 프로젝트 초기화하기
- 2. React 라이브러리 생성하기
- 3. Next.js demo 생성하기
- 4. 라이브러리 배포하기
- 5. demo 배포하기
2. React 라이브러리 생성하기
2.1. React 라이브러리 초기화하기
프로젝트 루트에서 다음 명령어를 입력하여 React 라이브러리 폴더를 생성합니다.
1mkdir -p packages/react-toc/src
2cd packages/react-toc이후 다음 명령어를 입력하여 라이브러리를 초기화합니다.
1pnpm init생성된 package.json 파일을 열고 다음과 같이 라이브러리를 배포하기 위한 설정을 진행합니다.
1{
2 "name": "@hyunjinno/react-toc",
3 "version": "0.0.1",
4 "description": "A library that automatically generates a Table of Contents (TOC) from your headings with scroll tracking.",
5 "type": "module",
6 "main": "./dist/index.cjs",
7 "types": "./dist/index.d.cts",
8 "sideEffects": false,
9 "exports": {
10 ".": {
11 "types": "./dist/index.d.mts",
12 "import": "./dist/index.mjs",
13 "require": "./dist/index.cjs"
14 },
15 "./style.css": "./dist/style.css"
16 },
17 "files": ["dist"],
18 "scripts": {
19 "test": "echo \"Error: no test specified\" && exit 1",
20 "build": "tsdown",
21 "watch": "tsdown --watch ./src"
22 },
23 "keywords": ["toc", "table-of-contents"],
24 "author": "HyunJinNo",
25 "homepage": "https://hyunjinno.github.io/react-toc",
26 "repository": {
27 "type": "git",
28 "url": "https://github.com/HyunJinNo/react-toc"
29 },
30 "license": "MIT",
31 "peerDependencies": {
32 "react": "^18 || ^19",
33 "react-dom": "^18 || ^19"
34 }
35}위의 package.json 설정 내용을 설명하면 다음과 같습니다.
2.1.1. 패키지 기본 정보
1{
2 "name": "@hyunjinno/react-toc",
3 "version": "0.0.1",
4 "description": "A library that automatically generates a Table of Contents (TOC) from your headings with scroll tracking."
5}name
npm에 배포되는 패키지 이름으로,@hyunjinno/...와 같이 스코프를 포함하도록 설정하였습니다. 추후 라이브러리를 배포한 후,npm install @hyunjinno/react-toc명령어로 설치할 수 있습니다.version
현재 라이브러리 버전을 나타냅니다.description
패키지 설명 부분입니다.
2.1.2. 모듈 시스템 설정
1{
2 "type": "module",
3 "main": "./dist/index.cjs",
4 "types": "./dist/index.d.cts"
5}type
"type": "module"로 설정하면 기본을ESM(ES Module)로 사용하게 되며, 모든.js파일이 ESM으로 해석됩니다.main
CommonJS 환경(require) 에서의 진입점입니다.types
TypeScript 타입 정의 파일을 지정하는 부분입니다.
2.1.3. sideEffects
1{
2 "sideEffects": false
3}Tree-shaking 최적화를 통해 사용하지 않는 코드를 제거할 수 있습니다.
2.1.4. exports
1{
2 "exports": {
3 ".": {
4 "types": "./dist/index.d.mts",
5 "import": "./dist/index.mjs",
6 "require": "./dist/index.cjs"
7 },
8 "./style.css": "./dist/style.css"
9 }
10}exports 옵션을 통해 ESM과 CJS 모두 지원하도록 설정합니다.
| 상황 | 파일 |
|---|---|
| ESM (import) | index.mjs |
| CJS (require) | index.cjs |
| 타입 | index.d.mts |
1import { Toc } from "@hyunjinno/react-toc";1const { toc } = require("@hyunjinno/react-toc");또한 CSS를 별도 export로 제공하도록 설정합니다.
1import "@hyunjinno/react-toc/style.css";2.1.5. files
1{
2 "files": ["dist"]
3}npm publish시 dist만 포함하도록 설정합니다.
2.1.7. scripts
1{
2 "scripts": {
3 "test": "echo \"Error: no test specified\" && exit 1",
4 "build": "tsdown",
5 "watch": "tsdown --watch ./src"
6 }
7}위에서 설정한 명령어에 대해 설명하면 다음과 같습니다.
build
tsdown 번들러를 통해 dist를 생성합니다.watch
watch 모드로 실행하면 코드 수정 시 자동으로 재빌드됩니다.
2.1.8. 메타 정보
1{
2 "keywords": ["toc", "table-of-contents"],
3 "author": "HyunJinNo",
4 "homepage": "https://hyunjinno.github.io/react-toc",
5 "repository": {
6 "type": "git",
7 "url": "https://github.com/HyunJinNo/react-toc"
8 },
9 "license": "MIT"
10}keywords
npm에 표시될 키워드 목록을 지정하는 부분입니다.author
라이브러리 제작자를 지정하는 부분입니다.homepage
npm에 표시될 Homepage를 지정하는 부분으로, 여기서는 GitHub Pages로 배포할 demo 웹사이트 URL을 작성하였습니다.repository
라이브러리 저장소를 지정하는 부분입니다.license
라이브러리 라이선스를 지정하는 부분입니다.
2.1.9. peerDependencies
1{
2 "peerDependencies": {
3 "react": "^18 || ^19",
4 "react-dom": "^18 || ^19"
5 }
6}번들 중복 방지를 위해 peerDependencies에 React를 외부 의존성으로 지정합니다. 이를 통해 라이브러리 사용자가 React를 설치하게 됩니다.
2.2. tsconfig.json 설정하기
생성한 라이브러리 디렉토리에서 tsconfig.json 파일을 생성한 후,
프로젝트 루트에 있는 tsconfig.base.json을 확장하도록 설정합니다.
1{
2 "extends": "../../tsconfig.base.json",
3 "compilerOptions": {
4 "outDir": "dist",
5 "declaration": true,
6 "declarationDir": "dist"
7 },
8 "include": ["src"]
9}2.3. React 라이브러리 의존성 설치하기
프로젝트 루트에서 다음 명령어를 입력하여 React 라이브러리 및 tsdown 번들러 의존성을 설치합니다.
1pnpm add -Dw react react-dom @types/react @types/react-dom typescript tsdown라이브러리에서 CSS도 제공할 경우, 다음 패키지를 설치할 수 있습니다.
1pnpm add -Dw @tsdown/css또한 특정 라이브러리에서만 필요한 의존성의 경우, 다음과 같이 설치할 수 있습니다.
1pnpm add -D clsx2.4. tsdown 설정하기
packages/react-toc 디렉토리에서 tsdown.config.ts 파일을 생성한 후, 다음과 같이 설정합니다.
1/* tsdown.config.ts */
2
3import { defineConfig } from "tsdown";
4
5export default defineConfig({
6 entry: ["./src/index.ts"],
7 format: ["esm", "cjs"],
8 dts: true,
9 clean: true,
10 deps: { neverBundle: ["react", "react-dom"] },
11});위의 코드를 설명하자면 다음과 같습니다.
entry
빌드 진입점을 설정합니다.format
ESM과 CJS 모두 지원하도록 설정합니다.dts
.d.ts파일을 생성하도록 설정합니다.clean
라이브러리 빌드 전, 이전에 생성된 빌드 결과물을 삭제하도록 설정합니다.deps
React 번들을 제외하도록 설정합니다.
2.5. React 컴포넌트 생성하기
다음과 같이 라이브러리에서 사용하는 React 컴포넌트를 생성합니다.
1/* H2.tsx */
2
3import clsx from "clsx";
4
5type H2Props = Omit<
6 React.ComponentProps<"h2"> & {
7 children: string;
8 },
9 "id"
10>;
11
12export const H2 = ({ children, ...props }: H2Props) => {
13 return (
14 <h2 {...props} className={clsx("toc-heading", props.className)}>
15 {children}
16 </h2>
17 );
18};2.6. style.css 생성하기
라이브러리에서 CSS 파일을 제공할 수 있습니다.
1.react-toc-wrapper {
2 display: flex;
3 flex-direction: column;
4 gap: 1rem;
5 border-left: 1px solid #dddddd;
6 height: fit-content;
7 padding-bottom: 1rem;
8}
9
10.react-toc-wrapper-heading {
11 padding-left: 1rem;
12 font-weight: 500;
13}
14
15.react-toc-list {
16 display: flex;
17 flex-direction: column;
18 gap: 0.625rem;
19}
20
21.react-toc-link {
22 overflow: hidden;
23 text-overflow: ellipsis;
24 white-space: nowrap;
25
26 &:hover {
27 color: #0056b2;
28 }
29}
30
31.react-toc-active {
32 border-left: 1px solid #0056b2;
33 color: #0056b2;
34 margin-left: -1px;
35}
36
37.react-toc-h2 {
38 padding-left: 1rem;
39}
40
41.react-toc-h3 {
42 padding-left: 1.75rem;
43}
44
45.react-toc-h4 {
46 padding-left: 2.5rem;
47}
48
49.react-toc-h5 {
50 padding-left: 3.25rem;
51}
52
53.react-toc-h6 {
54 padding-left: 4rem;
55}2.7. index.ts 설정하기
라이브러리에서 제공하는 React 컴포넌트와 CSS 파일을 지정합니다.
1import "./style.css";
2
3export { H2 } from "./H2";
4export { H3 } from "./H3";
5export { H4 } from "./H4";
6export { H5 } from "./H5";
7export { H6 } from "./H6";
8export { Toc } from "./Toc";
9export { TocProvider } from "./TocProvider";2.8. 라이브러리 빌드하기
다음 명령어를 입력하여 라이브러리 빌드를 수행할 수 있습니다.
1pnpm run build
또는 watch 모드로 실행하여 코드 수정 시 자동으로 재빌드할 수 있습니다. watch 모드는 주로 개발 과정에서 사용합니다.
1pnpm run watch3. 다음 Part
다음 글에서는 Next.js demo 애플리케이션을 생성하고 라이브러리 문서를 작성하는 과정을 다룹니다.
4. 참고 자료
- React+typescript 컴포넌트 라이브러리 생성하기 ③rollup 설정 — 콩부합시다
- 고티켓-react 컴포넌트 라이브러리 만들기(3)-rollup — 이찬진 컴퓨터 교실
- esbuild vs rollup vs webpack vs tsup | "웹 자바스크립트 번들러" npm 패키지 비교
- 리액트 컴포넌트 라이브러리를 빌드하고 배포하는 방법 — React와 TypeScript를 좋아하는 개발자
- 리액트 라이브러리 npm에 배포하기 with rollup
- rolldown/tsdown: The elegant bundler for libraries powered by Rolldown
- Nextra - Next.js Static Site Generator
- HyunJinNo/react-toc: A library that automatically generates a Table of Contents (TOC) from your headings with scroll tracking.