프로젝트 기록

[React-draggable-selector] 셀렉터 라이브러리 제작하기 (3) - npm 배포하기

lerrybe 2023. 8. 16. 18:34

업데이트 사항 (w. 2023/08/24)

https://lerryroad.tistory.com/136

컴포넌트 props 인터페이스를 대폭 수정, 구현 구조를 변경하여 버전 2.X.X로 업데이트했습니다. outdated된 내용 또한 아래 본문에 표시해뒀는데 오래된 버전에 대한 내용은 🚫, 업데이트된 버전에 대한 내용은 그 옆에 ✅로 작성했으니 참고하시면 좋을 것 같습니다.

 

 

npm & github

🐱 Github

🐱 live example

 

 

현재 Vite + React + Typescript 환경에서 진행했기 때문에 이에 맞춰서 세팅을 진행했습니다. 

 

Vite

Vue.js 개발을 위한 빠른 개발 도구로 Vue.js 애플리케이션 개발에 최적화되어 있지만, 다른 프레임워크나 라이브러리에서도 호환하여 사용될 수 있습니다. Vite는 빠른 개발 서버와 HMR(Hot Module Replacement) 기능을 제공하고 있어 애플리케이션 개발 시간을 단축할 수 있습니다. 또한, Rollup과 같은 모듈 번들러를 사용합니다.

 

Rollup

Rollup 번들러는 빌드 시간을 최소화하는 주요 장점이 있습니다. 트리 셰이킹을 지원해 불필요한 코드를 제거할 수 있습니다. 다만 추가 기능을 위해서는 플러그인을 추가로 설치해주어야 하며, 웹팩보다 기능이 다양하지는 않습니다.

 

 

vite 환경에서 rollup을 이용해 번들링을 진행한다고 하여 vite.config.ts 안의 내용과 package.json, tsconfig.json 내용의 변경으로 npm 배포를 위한 설정을 완료할 수 있었습니다.

 

vite.config.ts

- defineConfig를 통해 vite config를 설정, 외부로 내보낼 수 있게 합니다.

- [플러그인 추가] react, dts와 libCss를 통해 리액트, 타입스크립트 맵핑, css 파일의 맵핑을 가능하게 합니다.

- [빌드 옵션] lib: 라이브러리로 만드는데 필요한 옵션들, rollupOptions: 번들러에 추가로 전달할 옵션들

    - lib/entry: 파일을 읽는 시작, 진입점

    - lib/name: 라이브러리 이름

    - lib/fileName: 빌드 파일 이름

    - lib/formats: 빌드로 만들어낼 모듈들의 형태 

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';
import dts from 'vite-plugin-dts';
import libCss from 'vite-plugin-libcss';

const __dirname = dirname(fileURLToPath(import.meta.url));

export default defineConfig({
  plugins: [react(), dts(), libCss()],
  build: {
    lib: {
      entry: resolve(__dirname, 'src/index.ts'),
      name: 'react-draggable-selector',
      fileName: 'index',
      formats: ['es', 'umd', 'cjs'],
    },
    rollupOptions: {
      external: ['react', 'react-dom'],
      output: {
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM',
        },
      },
    },
  },
});

 

📂 package.json

- 참고로 version 정보를 이전과 동일하게 해서 재배포하면 오류가 납니다. 기존 버전정보와 겹치지 않게 새 버전으로 작성 후 배포해야하는데, 일반적으로 프로젝트는 1.0.0 에서부터 시작하고 아래 각 버전의 의미에 따라 숫자를 하나씩 올리면 됩니다.

  • 1.0.0 메이저: 많은 기능들이 추가 혹은 수정되어 배포한 경우
  • 1.0.0 마이너: 작은 기능들의 추가 혹은 수정을 포함해 배포한 경우
  • 1.0.0 패치: 버그, 혹은 사소한 오류를 수정해 배포한 경우

🚫 Outdated version

더보기
더보기
{
  "name": "react-draggable-selector",
  "version": "1.0.0",
  "type": "module",
  "description": "A library for select times with drag action in React.",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/lerrybe/react-draggable-selector.git"
  },
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.umd.cjs"
    }
  },
  "browser": "./browser/specific/main.js",
  "author": {
    "name": "Yeji Kim"
  },
  "keywords": [
    "react",
    "drag",
    "selector",
    "custom",
    "styling",
    "grid",
    "component",
    "styled-components"
  ],
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build --base=./",
    "preview": "vite preview",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build",
    "prepare": "yarn build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
  },
  "dependencies": {
    "@types/react": "^18.2.15",
    "@types/react-dom": "^18.2.7",
    "@types/styled-components": "^5.1.26",
    "dayjs": "^1.11.9",
    "styled-components": "^6.0.6",
    "vite-plugin-dts": "^3.5.1",
    "vite-plugin-libcss": "^1.1.1"
  },
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0"
  },
  "devDependencies": {
    "@storybook/addon-essentials": "^7.2.0",
    "@storybook/addon-interactions": "^7.2.0",
    "@storybook/addon-links": "^7.2.0",
    "@storybook/blocks": "^7.2.0",
    "@storybook/react": "^7.2.0",
    "@storybook/react-vite": "^7.2.0",
    "@storybook/testing-library": "^0.0.14-next.2",
    "@typescript-eslint/eslint-plugin": "^6.0.0",
    "@typescript-eslint/parser": "^6.0.0",
    "@vitejs/plugin-react": "^4.0.3",
    "chromatic": "^6.21.0",
    "eslint": "^8.45.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.3",
    "eslint-plugin-storybook": "^0.6.13",
    "prettier": "^3.0.0",
    "prop-types": "^15.8.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "storybook": "^7.2.0",
    "typescript": "^5.0.2",
    "vite": "^4.4.5"
  },
  "bugs": {
    "url": "https://github.com/lerrybe/react-draggable-selector/issues"
  },
  "homepage": "https://github.com/lerrybe/react-draggable-selector#readme",
  "_id": "react-draggable-selector@0.0.6"
}
{
  "name": "react-draggable-selector",
  "version": "2.1.1",
  "type": "module",
  "description": "A library for select times with drag action in React.",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/lerrybe/react-draggable-selector.git"
  },
  "bugs": {
    "url": "https://github.com/lerrybe/react-draggable-selector/issues"
  },
  "homepage": "https://react-draggable-selector.vercel.app/",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.umd.cjs"
    }
  },
  "browser": "./browser/specific/main.js",
  "author": {
    "name": "Yeji Kim"
  },
  "keywords": [
    "react",
    "drag",
    "selector",
    "grid",
    "component"
  ],
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build --base=./",
    "preview": "vite preview",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build",
    "prepare": "yarn build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
  },
  "dependencies": {
    "@types/react": "^18.2.15",
    "@types/react-dom": "^18.2.7",
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "dayjs": "^1.11.9",
    "vite-plugin-dts": "^3.5.1",
    "vite-plugin-libcss": "^1.1.1"
  },
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0"
  },
  "devDependencies": {
    "@storybook/addon-essentials": "^7.2.0",
    "@storybook/addon-interactions": "^7.2.0",
    "@storybook/addon-links": "^7.2.0",
    "@storybook/blocks": "^7.2.0",
    "@storybook/react": "^7.2.0",
    "@storybook/react-vite": "^7.2.0",
    "@storybook/testing-library": "^0.0.14-next.2",
    "@typescript-eslint/eslint-plugin": "^6.0.0",
    "@typescript-eslint/parser": "^6.0.0",
    "@vitejs/plugin-react": "^4.0.3",
    "chromatic": "^6.21.0",
    "eslint": "^8.45.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.3",
    "eslint-plugin-storybook": "^0.6.13",
    "prettier": "^3.0.0",
    "prop-types": "^15.8.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "storybook": "^7.2.0",
    "typescript": "^5.0.2",
    "vite": "^4.4.5"
  }
}

 

 

📂 tsconfig.json

{
  "compilerOptions": {
    "useDefineForClassFields": true,
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": false,
    "target": "es5",
    "lib": ["es6", "dom", "es2016", "es2017"],
    "jsx": "react-jsx",
    "sourceMap": true,
    "declaration": true,
    "declarationMap": true,
    "outDir": "dist",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,

    /* Linting */
    "strict": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noFallthroughCasesInSwitch": true,
    "types": ["vite/client"]
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"],
  "references": [{ "path": "./tsconfig.node.json" }]
}