[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개의 댓글

관련 채용 정보