[NPM 배포] SpeechBubble 배포하기 (1)
자유글

[NPM 배포] SpeechBubble 배포하기 (1)

프로젝트를 할때마다 만나는 ui가 있습니다. 

바로 말풍선입니다.

 

보기에는 상당히 구현하기 매우 쉬워보입니다. 하지만 문제는 저 위에 뾰족 나와있는 저 삼각형이 문제입니다. 

저 삼각형을 구현하려면 일단 위치를 일일이 맞춰주어야 하죠. 항상 구현할 때 너무너무 귀찮았습니다. 

따라서 이참에 한번 말풍선 라이브러리를 만들어보자! 라는 생각이 들었고 그 배포기를 블로그에 적어보려합니다.

1. 프로젝트 설정

이번 프로젝트는 번들링 사이즈 개선을 위해서 pnpm과 vite를 사용해서 배포하려고 합니다.

일단 vite 프로젝트를 만들어줍니다.

React 와 TypeScript를 사용하겠습니다.

 

2. 컴포넌트 생성

필요 없는 파일은 다 지우고 말풍선에 필요한 Pointer 컴포넌트들을 만들었습니다. (Public도 함께 삭제해줍니다.)

그리고 index.ts에서 컴포넌트들을 한꺼번에 export해줍니다.

//  src/lib/index.ts
export { default as PointerBorder } from "./components/PointerBorder";
export { default as Pointer } from "./components/Pointer";

3. vite config 파일 수정

 타입스크립트를 사용해서 개발하기 위해 d.ts파일 번들링 위한 vite-plugin-dts를 설치해줍니다.

pnpm i -D @types/node vite-plugin-dts

insertTypesEntry옵션을 통해 package.json types 속성에 지정된 위치에 타입 정의 파일을 생성할 수 있게 합니다.

저는 storybook을 사용해 ui test를 할 예정이기 때문에 storybook을 추가해보았습니다.

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

// https://vitejs.dev/config/
export default defineConfig({
  build: {
    lib: {
      entry: "src/lib/index.ts",
      name: "@hellol/speech-bubble",
      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,
    }),
  ],
});
  • lib
    • entry: 라이브러리 진입점, 제공하고자 하는 컴포넌트 모두 export하는 부분
    • name: 라이브러리 이름
    • formats: 라이브러리를 어떤 형식으로 빌드할지 지정, es모듈과 commonjs 형식으로 빌드
    • fileName: 출력 파일 이름 지정
  • rollupOptions
    • external: 라이브러리에 포함하지 않을 dependency
    • globals: 라이브러리 외부에 존재하는 dependency를 위해 번들링 시 사용될 전역 변수 명시
    • banner: 번들 앞에 문자열을 추가함, "use client";를 추가해 컴포넌트의 모든 사용을 클라이언트 컴포넌트로 보장
    • interop: 외부 의존성과의 모듈 간 상호 작용 방식 설정 (기본 모드에서 Node.js 동작 방식을 따르며, TypeScript의 esModuleInterop 동작과 다르므로 auto로 설정하여 ES모듈과 CommonJS모듈 간의 상호 운용성 문제를 줄임)

4. package.json 수정 및 npm 배포

npm에 배포하기 위해서 entry 와 다른 정보들을 적어줍니다.

{
  "name": "@hellol77/speech-bubble",
  "version": "0.0.1",
  "description": "Speech bubble component",
  "main": "dist/index.cjs.js",
  "module": "dist/index.es.js",
  "types": "dist/index.d.ts",
  "type": "module",
  "exports": {
    ".": {
      "module": "./dist/index.es.js",
      "import": "./dist/index.es.js",
      "default": "./dist/index.cjs.js"
    }
  },
  "author": {
    "name": "hellol77",
    "email": email
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/Hellol77/speech-bubble"
  },
  ...
}

이후에 파일 수정시 배포할때는 version을 다른 버전으로 적어줘야 에러가 뜨지 않고 배포를 할 수 있습니다.

이후 

npm publish --access=public

을 하면 npm 배포가 가능합니다!

 

5. npm 배포 테스트 해보기

npm 배포가 잘 되었는지 로컬에서 테스트 해볼 수 있습니다.

pnpm pack
pnpm i ./hellol77-speech-bubble-0.0.1.tgz

pnpm pack을 통해서 package를 만든후 만든 패키지 파일을 프로젝트에 추가해 줍니다 

추가 후 

import { Pointer } from "@hellol77/speech-bubble";

import 해주면 로컬에서 테스트 해볼 수 있습니다.

다음 글에서는 본격적으로 speech bubble을 개발해보도록 하겠습니다.

 

Reference

 

[npm 라이브러리 배포] React 컴포넌트 라이브러리 배포전 테스트 및 배포하기

[react 컴포넌트 npm 라이브러리로 배포하기] React 컴포넌트 라이브러리 배포전 테스트 및 배포하기편

velog.io

 

 

[React] vite와 함께 리액트 컴포넌트 npm에 배포하기

우리가 흔히 사용하는 react, eslint와 같은 패키지를 우리도 npm에 직접 배포할 수 있습니다. react 함수와 컴포넌트 등을 작성한 라이브러리를 추후 프로젝트에 만들어서 사용할 예정이기 때문에,

devpluto.tistory.com