최근 제가 사이드 프로젝트로 진행하는 프로젝트에서 사용할 목적으로 UI 컴포넌트 라이브러리를 만들었습니다.
UI 컴포넌트를 만들 때, 프로젝트를 vite의 react 템플릿을 사용하여 생성하였습니다.
vite로 라이브러리를 빌드할 때는 react web app을 빌드할 때와 달리 추가적인 설정이 필요합니다.
아래 제가 vite로 라이브러리를 build 하며 겪었던 과정을 말씀드리겠습니다.
라이브러리 entry point 만들어주기
vite의 react 템플릿을 사용하여 프로젝트를 생성했을 때, vite는 index.html을 entry point로 하여 프로젝트를 빌드합니다.
하지만 저희는 UI 라이브러리를 만드는 것이기 때문에 index.html이 존재하지 않습니다.
그래서 저는 src 디렉토리 하위에 main.ts로 entry point를 만들어줬습니다.
// src/main.ts
export { default as Icon } from './components/base/icon';
export { default as Typography } from './components/base/typography';
export { default as UI } from './components/ui';
export { vars as Theme } from './styles/theme.css';
라이브러리 빌드를 위해 vite.config.js 설정하기
vite.config.js를 수정해서 entry point를 비롯한 설정을 추가해 줍니다.
/// <reference types="vitest/config" />
// import 구문들...
export default defineConfig({
// ...
build: {
lib: {
name:'ui',
entry: ['src/main.ts'],
cssFileName: 'ui-style',
formats: ['es','umd'],
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
},
},
});
build 옵션의 의미는 다음과 같습니다.
- lib.name : 노출된 전역변수로 formats이 'umd' 혹은 'iife' 일 때 필요
- lib.entry : entry point 지정, 여러 entry point 지정도 가능
- lib.formats : 빌드 결과물의 형식, 'es', 'umd', 'cjs', 'iife', 'system' 중에 선택
- lib.cssFileName : css 파일 출력 이름 지정
rollup 옵션의 의미는 다음과 같습니다.
- rollupOptions.external : 라이브러리에 포함하지 않을 디펜던시 명시
- rollupOptions.output : 라이브러리 외부에 존재하는 디펜던시를 위해 UMD 번들링 시 전역 변수 명시
저는 react를 빌드 패키지에 포함하지 않을 것이므로 'react'와 'react-dom'을 rollupOptions.external에 추가했습니다.
vite-config-dts 설치 (optional. typescript 프로젝트만 해당)
typescript 프로젝트에서 위에까지 설정하고 빌드를 하면 타입은 다 날아가고 자바스크립트 파일만 생성됩니다.
d.ts 파일을 생성하기 위해 vite-config-dts 플러그인을 설치해 줍니다.
npm i vite-config-dts -D
vite.config.js에 plugin에 vite-config-dts를 추가합니다.
export default defineConfig({
plugins: [
react(),
dts({
tsconfigPath: './tsconfig.json',
outDir: 'dist',
rollupTypes: false,
}),
// ...
],
// ... 다른 옵션들
})
tsconfigPath는 공식문서에서 보면, 공식 vite template인 프로젝트일 때 tsconfig.json의 경로를 작성하라고 명시되어 있습니다.
rollupTypes는 여러 d.ts 파일을 하나의 d.ts 파일로 만드는 옵션인데, 이 옵션을 켰을 때 저 같은 경우 타입이 이상해져서 껐습니다.
Package.json에 라이브러리 entry point 명시하기
# package.json
{
"name": "@runzipper/ui",
"version": "0.0.15",
"author": {
"name": "BHyeonKim",
"email": "rlaqhguse@gmail.com",
"url": "https://github.com/BHyeonKim"
},
"description": "UIkit for zipper app",
"repository": {
"type": "git",
"url": "https://github.com/Runzipper/ui"
},
"packageManager": "yarn@4.10.3",
"files": [
"dist"
],
"exports": {
".": {
"types": "./dist/src/main.d.ts",
"import": "./dist/main.mjs",
"require": "./dist/main.umd.js"
},
"./styles": "./dist/ui-style.css"
...
}
package.json의 exports 필드에 entry point를 명시합니다.
❗️ types 필드는 항상 첫 번째에 있어야 합니다.
"types" - can be used by typing systems to resolve the typing file for the given export. This condition should always be included first.
types 필드를 통해 생성된 타입의 위치를 지정하고, conditional exports를 통해 import 키워드와 require 키워드 모두 지원하도록 설정하였습니다.
추가적으로 files 필드를 설정하여 npm package에는 소스코드를 제외한 빌드 결과물만 올라가도록 설정하였습니다.
'개발' 카테고리의 다른 글
| [Next.js] Next.js 어플리케이션에 i18n 구현하기 (0) | 2025.12.15 |
|---|---|
| [압축 알고리즘] LZ77 구현 (0) | 2025.11.13 |
| [압축 알고리즘] LZ77 알고리즘 이란? (0) | 2025.11.13 |