일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 합성 컴포넌트
- 이것저것
- 아키텍처
- 리액트
- vite
- Web
- 자바스크립트
- Webworker
- CRA
- context.api
- provider 패턴
- 웹워커
- 프론트엔드
- radixui
- 리팩토링
- 회고
- JavaScript
- sharedworker
- 오블완
- 티스토리챌린지
- server component
- CustomHook
- 에세이
- TypeScript
- react
- MFA
- virtaullist
- MicroFrontEnd
- frontend
- 클린코드
- Today
- Total
Lighthouse of FE biginner
[React] Vite 라이브러리 모드 셋팅하기 본문
Overview
Vite는 웹 애플리케이션을 빠르게 만들수 있도록 도와주는 프론트엔드 개발 툴 입니다. 내부적으로 ESM을 사용하며 ESBuild를 활용해 디펜던시를 빠르게 사전 번들링을 수행하고, rollUp을 사용해 빌드를 효율적으로 진행합니다.
오늘 포스팅에서는 Vite 템플릿을 활용해 라이브러리를 제작할 수 있도록 초기 셋팅 진행 과정을 소개해드리겠습니다.
아래 과정을 천천히 따라와주세요!
https://ko.vitejs.dev/guide/build.html#library-mode
환경 구축
먼저 Vite 환경을 구축해주세요. 환경 구축은 일반적인 Vite 템플릿 생성 과정과 동일합니다.
pnpm create vite my-react-lib --template react-ts
라이브러리를 구축하며 Storybook을 활용해 볼 예정입니다. 아래 공식문서대로 설정을 진행해주세요!
https://storybook.js.org/docs/get-started/frameworks/react-vite?renderer=react
디렉토리 구조 변경
먼저 디렉토리의 구조를 변경할 예정입니다. 우리는 라이브러리 모드로 진행할 예정이기 때문에 웹 어플리케이션을 위한 진입점을 필요하지 않습니다.
1. main.tsx, App.tsx 파일들을 제거해주세요.
2. 새로운 라이브러리 진입점 파일을 생성해주세요. (main.ts)
3. Storybook 탬플릿인 stories 디렉토리에서 components 폴더를 src 하위로 구조 변경해주세요.
vite.config.ts 파일 수정
플러그인
1. 의존성 설치
pnpm install -D vite-plugin-lib-inject-css vite-plugin-dts glob
@vitejs/plugin-react
기본적으로 React를 사용하기 때문에 위 플러그인은 설정되어 있습니다. 만약 babel 대신 swc를 사용하고 싶다면 아래 라이브러리로 대체한 후 import 해 넣어주시면 됩니다.
@vitejs/plugin-react-swc
vite-plugin-lib-inject-css
빌드 과정에서 CSS를 JavaScript 파일에 포함시킬 수 있도록 도와줍니다. 라이브러리를 배포할 때 CSS 파일을 별도로 관리하지 않고, JS 파일 안에 포함시키는 경우에 유용합니다.
vite-plugin-dts
타입스크립트 정의 파일(.d.ts)을 자동으로 생성해주는 플러그인입니다. exclude 옵션을 통해 특정 파일(예: .stories.tsx)을 제외할 수 있습니다. 이로 인해 라이브러리에 불필요한 파일이 포함되지 않도록 할 수 있습니다.
glob
glob 패키지는 파일 시스템에서 파일을 검색하기 위한 패턴 매칭 기능을 제공하는 Node.js 라이브러리입니다.
2. 플러그인 설정
stories 파일은 빌드에서 제외될 파일입니다. 그렇기 때문에 dts파일을 생성하지 않도록 제외시켜줍시다.
plugins: [
react(),
libInjectCss(),
dts({ exclude: ["**/*.stories.tsx", "**/*.stories.ts"] }),
],
build
Vite의 빌드 옵션을 설정해봅시다. 먼저 라이브러리 모드로 빌드를 할 것 이기에 lib 옵션을 설정해줍시다.
build: {
lib: {
entry: resolve(__dirname, "src/main.ts"),
formats: ["es"],
name: "index",
fileName: (format) => `index.${format}.js`,
},
- entry: 라이브러리의 진입점 파일을 지정합니다. 이 예제에서는 src/main.ts 파일이 엔트리로 사용됩니다.
- formats: 라이브러리를 빌드할 출력 형식을 지정합니다. 여기서는 ES 모듈 형식(ESM)만 사용됩니다.
- name: 라이브러리의 이름을 정의합니다.
- fileName: 출력되는 파일 이름을 지정하는 함수입니다. 각 형식에 따라 파일 이름을 지정할 수 있습니다.
rollupOptions
rollUp 번들러가 수행합니다. 그렇기 때문에 롤업의 설정을 할 필요가 있습니다.
rollupOptions: {
external: ["react", "react-dom", "react/jsx-runtime"],
input: Object.fromEntries(
globSync([
"src/components/**/index.tsx",
"src/hooks/**/index.ts",
"src/main.ts",
]).map((file) => {
const entryName = path.relative(
"src",
file.slice(0, file.length - path.extname(file).length)
);
const entryUrl = fileURLToPath(new URL(file, import.meta.url));
return [entryName, entryUrl];
})
),
output: {
entryFileNames: "[name].js",
assetFileNames: "assets/[name][extname]",
globals: {
react: "React",
"react-dom": "ReactDOM",
"react/jsx-runtime": "react/jsx-runtime",
},
},
},
- external: 이 설정은 빌드 결과물에서 외부 라이브러리를 제외합니다. 즉, React와 관련된 라이브러리는 번들에 포함되지 않고, 외부에서 가져오도록 처리됩니다.
- input: 다중 엔트리 포인트를 지정합니다. globSync를 통해 지정된 패턴에 맞는 파일들을 찾아서 엔트리로 설정합니다.
- output: 출력 파일의 이름 형식 및 글로벌 변수 설정을 정의합니다. entryFileNames와 assetFileNames를 통해 파일 이름 규칙을 정의하며, globals는 Vite 설정에서 외부 의존성(external dependencies)에 대한 전역 변수 매핑을 정의하는 옵션입니다.
copyPublicDir
빌드 과정에서 public 디렉토리의 파일을 복사하지 않도록 설정합니다. 이 설정은 라이브러리를 빌드할 때 불필요한 파일이 포함되지 않도록 합니다.
main.ts
라이브러리에서 작업한 컴포넌트를 외부로 내보내기 위해 라이브러리의 배럴 파일을 만들어줍시다. 해당 파일은 라이브러리의 진입점 이기도 합니다.
export { useTableSelection } from "./hooks/useTableSelection";
export type {
UseTableSelectionResult,
UseTableSelectionProps,
RowSelection,
} from "./hooks/useTableSelection";
export { Dialog } from "./components/dialog";
export type { DialogProps } from "./components/dialog";
package.json 수정
{
...
"files": [
"dist"
],
"main": "./dist/main.js",
"module": "./dist/main.js",
"types": "./dist/main.d.ts",
...
}
- files: 패키지 배포 시 포함할 파일/디렉토리를 지정합니다.
- main: CommonJS(CJS) 환경에서 패키지를 사용할 때 기본으로 불러올 파일을 지정합니다.
- module: ES 모듈(ESM) 환경에서 패키지를 사용할 때 기본으로 불러올 파일을 지정합니다.
- types: TypeScript 환경에서 패키지를 사용할 때 참조할 타입 정의 파일을 지정합니다.
build 수행
마지막으로 진행한 설정을 바탕으로 빌드를 수행해봅시다! 빌드 스크립트를 수행하면 타입스크립트 컴파일러가 타입스크립트 컴파일을 수행하고 Vite 빌드를 수행합니다.
// build: tsc && vite build
pnpm run build
빌드 수행 결과 원하는 빌드 결과물을 확인할 수 있습니다!
마치며
라이브러리 모드로 설정을 하는데 있어서 아주 복잡한 과정을 거치지는 않았습니다.
환경에 따라서 다양한 변수가 존재할 수 있어서 위 과정을 그대로 거친다고 해도 생각한대로 셋팅이 진행되지 않을 수도 있습니다.
만약 타입스크립트 컴파일에서 문제가 발생한다면 아래 레포지토리의 tsconfig 파일을 참고해주세요!
읽어봐주셔서 감사합니다.
https://github.com/kangactor123/radix-storybook
'[WEB] 프론트엔드' 카테고리의 다른 글
[React] react-table을 활용해 기본 테이블 만들기 (1) | 2024.08.28 |
---|---|
[React] 실시간 알림 서비스 구현하기 (0) | 2024.08.12 |
페이지 라우팅? 컴포넌트 분기? (1) | 2024.08.08 |
Hello Zustand! (0) | 2024.08.07 |
[React] Radix UI를 활용해 MultiSelect 컴포넌트 구현하기 (1) | 2024.08.01 |