✅ 목표 구조
my-ui-kit/
├── src/
│ ├── MyButton.tsx //예시
│ └── index.ts
├── package.json
├── tsconfig.json
├── .gitignore
├── README.md
├── babel.config.js
└── .npmignore (또는 설정으로 src 제외하지 않도록 주의)
✅ 1. 패키지 초기화 (터미널 사용)
mkdir my-ui-kit
cd my-ui-kit
yarn init -y
✅ 2. TypeScript 설정
yarn add -D typescript
npx tsc --init
// build 시 타입에러 나면 타입스크립트 설치
yarn add typescript --dev
// 다시 빌드
yarn build
🔍 왜 필요한가요?
tsc는 TypeScript를 JavaScript로 변환하는 도구예요.
UI Kit 라이브러리를 배포하려면 .tsx 소스 코드를 .js와 .d.ts로 변환해야 하므로 필수입니다.
// 타입스립트 컴파일러 설정 수정 (tsconfig.json)
{
"compilerOptions": {
"outDir": "./dist",
"module": "ESNext",
"target": "ES2015",
"declaration": true,
"jsx": "react-native",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true, // ✅ 타입 충돌 무시
"allowSyntheticDefaultImports": true,
"types": ["react", "react-native"] // ✅ Node 타입 제거
},
"include": ["src"]
}
//skipLibCheck: node_modules 안의 타입 에러를 무시합니다.
//types: 명시적으로 react, react-native만 사용하겠다고 선언합니다.
✅ 3. 사용할 컴포넌트 작성
✅ 4. 빌드 & 배포 준비
//빌드
yarn build
//.gitignore
node_modules
dist
//.npmignore (또는 "files" 필드로 dist만 포함)
src
tsconfig.json
babel.config.js
✅ 5. NPM에 배포
정식 패키지처럼 쓰고 싶다면, 다음 절차로 NPM에 공개 배포해야 함
// package.json
"name": "실제 배포 할 라이브러리 이름 넣기"
// 1) 스코프 있는 패키지를 퍼블릭으로 설정 (중요)
// package.json에 다음 추가:
"publishConfig": {
"access": "public"
}
// NPM 로그인
npm login
// 최초 배포 (scoped 패키지는 공개 설정 필수)
npm publish
// 이후 재배포 시 package.json에서 "version" 수정 후 배포해야 함
✅ 6. 다른 프로젝트에서 사용
yarn add @your-scope/ui-kit
react-native 모듈이 직접 설치되어 있지 않아 에러 뜰 때
cd my-ui-kit
yarn add react-native --dev
//※ 실제 배포될 때는 peerDependencies로만 처리하므로 앱에는 영향을 주지 않아요.
//react-native는 앱마다 버전이 다를 수 있으므로, 라이브러리에서는 직접 설치하면 충돌 위험이 있음.
//그래서 package.json에는 peerDependencies로 명시하고, 개발 편의상 devDependencies에도 넣는 방식.
✅ 7. GitHub에 오픈소스 등록
// GitHub 리포지토리 만들기
// README.md 작성 (사용법 포함)
// MIT License 추가
//GitHub에 Push:
git init
git remote add origin https://github.com/your-name/my-ui-kit.git
git add .
git commit -m "init"
git push -u origin main
전체코드 예시
//package.json
{
"name": "my-ui-kit",
"version": "0.1.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "tsc",
"prepublishOnly": "yarn build"
},
"peerDependencies": {
"react": ">=17",
"react-native": ">=0.63"
},
"publishConfig": {
"access": "public"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
"devDependencies": {
"@types/react": "^19.1.6",
"@types/react-native": "^0.73.0",
"typescript": "^5.8.3"
}
}
//tsconfig.json
{
"compilerOptions": {
"outDir": "./dist",
"module": "ESNext",
"target": "ES2015",
"declaration": true,
"jsx": "react-native",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"types": ["react", "react-native"]
},
"include": ["src"]
}
//.gitignore
node_modules
dist
//.npmignore
src/
tsconfig.json
README.md
.gitignore
babel.config.js
// src 폴더와 내부에 사용할 컴포넌트 파일.tsx
📦src
┣ 📜Button.tsx
┣ 📜FormInput.tsx
┣ 📜ThemeProvider.tsx
┗ 📜index.ts
// /src/index.ts
export * from "./Button";
export * from "./FormInput";
export * from "./ThemeProvider";
🔁 유지보수 팁
"scripts": {
"build": "tsc",
"prepublishOnly": "yarn build"
}
//테스트할 때는 npm link 또는 yarn link를 활용하면 편합니다.
🚀 자동화 워크플로우: 3단계
필수전제
1. package.json에 "version"이 존재하고
2. Git을 사용 중이며 커밋은 완료된 상태
✅ [1] standard-version 설치
yarn add --dev standard-version
✅ [2] package.json 스크립트 추가
"scripts": {
"build": "tsc",
"release": "standard-version",
"release:patch": "standard-version --release-as patch",
"release:minor": "standard-version --release-as minor",
"release:major": "standard-version --release-as major",
"publish:all": "yarn build && npm publish"
}
✅ [3] 자동 배포 절차
// 패치 업데이트 (버그/소규모 변경)
yarn release:patch
yarn publish:all
//마이너 업데이트(기능 추가)
yarn release:minor
yarn publish:all
//메이저 업데이트(호환 깨짐)
yarn release:major
yarn publish:all
반응형
'React Native' 카테고리의 다른 글
[expo] expo-camera를 이용해서 바코드 스캔 구현하기 (0) | 2025.04.29 |
---|---|
[expo] eas buil 및 배포하기 및 재배포 (1) | 2025.04.29 |
Error: EBUSY: resource busy or locked, rmdir (0) | 2025.02.27 |
[RN] forwardRef를 사용하는 이유 (0) | 2025.02.21 |
[RN] 프로젝트 시작하기 (+svg 넣는법) (0) | 2025.02.13 |