[npm 라이브러리 배포] React 컴포넌트 라이브러리 배포전 설정

이선예·2023년 12월 23일
0
post-thumbnail

이전 포스팅에 이어서 작성합니다.
[npm 라이브러리 배포] 개발환경 세팅하기(yarn+Vite+React+TypeScript+Emotion+Storybook)


1. vite.config.ts 수정하기

  • TypeScript를 사용해서 라이브러리 프로젝트를 개발하려면 타입 정의 파일(.d.ts)를 생성해줘야하므로 vite-plugin-dts 플러그인을 설치해줘야한다.
  • insertTypesEntry옵션을 사용해서 package.json types속성에 지정된 위치에 타입 정의 파일을 생성할 수 있게 한다.
yarn add -D vite-plugin-dts

라이브러리 빌드 설정

  1. lib 속성
  • entry: 라이브러리 진입점, 제공하고자하는 컴포넌트를 모두 export하는 부분
  • name: 라이브러리 이름
  • formats: 라이브러리를 어떤 형식으로 빌드할지 지정, ES모듈과 CommonJS 형식으로 빌드
  • fileName: 출력 파일 이름 지정
  1. rollupOptions 속성
  • external: 라이브러리에 포함하지 않을 dependency 명시
  • output : 번들 출력에 대한 옵션 설정
  • globals: 라이브러리 외부에 존재하는 dependency를 위해 번들링 시 사용될 전역 변수 명시
  • banner: 번들 앞에 문자열을 추가함, "use client";를 추가해 컴포넌트의 모든 사용을 클라이언트 컴포넌트로 보장 (리액트 서버 컴포넌트가 나온 시점에서 명시하는게 더 안전할 것 같다고 판단)
    use client 공식문서
  • interop: 외부 의존성과의 모듈 간 상호 작용 방식 설정 (기본 모드에서 Node.js 동작 방식을 따르며, TypeScript의 esModuleInterop 동작과 다르므로 auto로 설정하여 ES모듈과 CommonJS모듈 간의 상호 운용성 문제를 줄임)
    output.interop 공식문서
vite.config.ts 코드
import * as path from 'path';

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import dts from 'vite-plugin-dts';

export default defineConfig({
  assetsInclude: ['/sb-preview/runtime.js'],
  build: {
    lib: {
      entry: path.resolve(__dirname, 'src/lib/index.ts'),
      name: 'react-carousel-image-optimized',
      formats: ['es', 'cjs'],
      fileName: (format) => `index.${format}.js`,
    },
    rollupOptions: {
      external: ['react', 'react-dom', '**/*.stories.tsx'],
      output: {
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM',
        },
        banner: '"use client";',
        interop: 'auto',
      },
    },
    commonjsOptions: {
      esmExternals: ['react'],
    },
  },
  plugins: [
    react({
      jsxImportSource: '@emotion/react',
      babel: {
        plugins: ['@emotion/babel-plugin'],
      },
    }),
    dts({
      insertTypesEntry: true,
    }),
  ],
});

2. package.json 수정하기

CommonJS와 ES모듈 두 가지 방식을 모두 지원하기 위해, exports에서 require을 사용하는 경우와 import를 사용하는 경우 어떤 파일에서 불러올 지 지정해준다.

  • main: CommonJS형식으로 빌드된 메인 파일의 경로
  • module: ECMAScript모듈 형식으로 사용하는 환경에서 사용되는 진입 지점 파일의 경로
  • types: TypeScript 프로젝트에서 사용되는 타입 정의 파일의 경로
  • exports: node_modules 조회 또는 자체 이름에 대한 자체 참조를 통해 로드된 이름으로 가져올 때 패키지의 진입점을 정의, 환경별로 다른 패키지 진입점을 정의
{
  //패킹된 라이브러리의 이름을 결정
  "name": "라이브러리 이름", 
  "description": "라이브러리 설명",
  "keywords": [
    관련 키워드
  ],
  "author": {
    "name": "이름",
    "email": "이메일"
  },
  "repository": {
    "type": "git",
    "url": "git주소"
  },
  "private": false,
  "license": "MIT", //라이브러리 라이센스
  "version": "0.0.1",
  "type": "module",
  "main": "dist/index.cjs.js",
  "module": "dist/index.es.js",
  "types": "dist/index.d.ts",
  "exports": {
    ".": {
      "module": "./dist/index.es.js",
      "import": "./dist/index.es.js",
      "default": "./dist/index.cjs.js"
    }
  },
}

참고 문서
npm package.json 공식문서
Node.js 공식문서


3. tsconfig.json 수정하기

최종적으로 빌드됐을 때, 배포에 필요한 파일과 폴더를 지정해준다.(TypeScript 컴파일러가 JavaScript 코드로 변환할 소스 파일을 지정하는 것)
나같은 경우 src/lib에 컴포넌트 라이브러리로 배포할 파일을 넣었고, lib폴더 내에 테스트 코드를 제외시켜줬다.

{
  "compilerOptions": {
//생략
  },
  "include": ["src/lib"],
  "exclude": ["**/*.stories.tsx"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

여기까지 하면 라이브러리를 배포할 준비는 모두 마쳤고, 다음 포스팅에서는 테스트 컴포넌트를 만들어서 로컬에서 테스트해보고, 실제 npm registry에도 배포하는 과정을 기록할 예정이다.

profile
의미있는 훈련 기록 저장소

0개의 댓글