LoginSignup
9
8

はじめに

こんにちは、エンジニアのkeitaMaxです。

今回は、ReactのUIライブラリを作成して公開する方法についてを記事にさせていただきます。

以下の記事を参考にさせていただきます。

プロジェクト作成

以下コマンドでReactのプロジェクトを作成します。

npm create vite@latest

色々聞かれると思うので、以下のように答えます。

develop % npm create vite@latest
Need to install the following packages:
create-vite@5.3.0
Ok to proceed? (y) y
✔ Project name: … react-ui-components-example
✔ Select a framework: › React
✔ Select a variant: › TypeScript

Scaffolding project in /Users/niheikeita/develop/react-ui-components-example...

Done. Now run:

  cd react-ui-components-example
  npm install
  npm run dev

develop % 

StoryBookのインストール

StoryBookを以下コマンドでインストールします。

npx storybook@latest init 
npm i vite-plugin-dts
npm i @types/node

TailwindCSSを使えるようにする

今回はTailwindCSSを使用するので以下のコマンドでインストールします。

npm install -D tailwindcss postcss autoprefixer

するとtailwind.config.jsファイルが作成されるので、以下のように修正します。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
//追加↓
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
//追加↑
  theme: {
    extend: {},
  },
  plugins: [],
}

indec.cssファイルに以下を追加します。

index.css
@tailwind base;
@tailwind components;
@tailwind utilities;

コンポーネントの作成

src/componentsというフォルダを作成し、その配下にButtonファイルを作成します。
その配下にindex.tsxindex.stories.tsxファイルを作成します。

src
└──components
    └── Button
            ├── index.tsx
           └── index.stories.tsx
index.tsx

import React from "react"

type Props = {
  children: React.ReactNode,
  variant: 'default' | 'pink'
}

export const Button = React.memo<Props>(function Button({
  children,
  variant = 'default'
}) {
  const color = (() => {
    switch (variant) {
      case 'default':
        return 'bg-white text-pink-500'
      case 'pink':
        return 'bg-pink-500 text-white'
    }
  })()

  return (
    <button className={color + ' rounded-full px-4 py-2 font-bold transition-transform duration-200 hover:scale-105'}>
      {children}
    </button>
  )
})

index.stories.tsx
import { Meta, StoryObj } from '@storybook/react'
import { Button } from '.'

const meta: Meta<typeof Button> = {
  title: 'components/Button',
  component: Button,
  tags: ['autodocs'],
}
export default meta

type Story = StoryObj<typeof meta>

export const Default: Story = {
  render() {
    return (
      <div className='grid gap-2 bg-gray-100 p-10'>
        <Button variant={'default'} >default</Button>
        <Button variant={'pink'}>pink</Button>
      </div>
    )
  },
}

こんな感じでボタンのコンポーネントを作成してみました。

StoryBookを起動してみると以下のようにTailwinCSSが効いていることがわかります。

スクリーンショット 2024-07-09 13.01.56.png

src/storiesファイルはいらないので削除してしまいます。

また、src/index.tsxを作成し以下のようにします。

index.tsx
import './index.css'

export * from "./Button"

各種設定

参考下の記事と同様に以下のようにします。

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "allowSyntheticDefaultImports": true,
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,

    "allowJs": false,
    "esModuleInterop": false,
    "moduleResolution": "Node"
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}
tsconfig.node.json
{
  "compilerOptions": {
    "composite": true,
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true
  },
  "include": ["vite.config.ts", "package.json"]
}
vite.config.ts

import { resolve } from "path";
import react from "@vitejs/plugin-react";
import autoprefixer from "autoprefixer";
import tailwindcss from "tailwindcss";
import { defineConfig } from "vite";
import dts from "vite-plugin-dts";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    dts({
      insertTypesEntry: true,
    }),
  ],
  css: {
    postcss: {
      plugins: [tailwindcss, autoprefixer],
    },
  },
  build: {
    lib: {
      entry: resolve(__dirname, "src/index.ts"),
      name: 'index',
      fileName: 'index',
    },
    rollupOptions: {
      external: ["react", "tailwindcss"],
      output: {
        globals: {
          react: "React",
          tailwindcss: "tailwindcss",
        },
      },
    },
  },
});

package.jsonは以下を追加します。

  "main": "./dist/index.umd.cjs",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "license": "MIT",
  "exports": {
    ".": {
      "types": "./dist/index.umd.cjs",
      "import": ["./dist/index.js","./dist/style.css"],
      "require": "./dist/index.d.ts"
    }
  },
  "files": [
    "dist"
  ],

またpackage.jsonscriptにいいかを追加します。

build": "tsc && vite build",

また以下をfalseに修正します。

"private": false,

公開する

まず以下コマンドでbuildします。

npm run build

以下のコマンドでnpmにログインをします。
まだnpmのアカウントがない方は作成してください。

npm login

そして以下コマンドで公開するためにpublishします。

npm publish

npmにログインをしてみてみると以下のようにライブラリが公開されているのがわかります。

スクリーンショット 2024-07-09 16.12.26.png

スクリーンショット 2024-07-09 16.12.55.png

おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました!

参考

次の記事

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8