🥷

プライベートUIライブラリ作って社内の共通コンポーネントを一括管理

2024/09/03に公開

エイジレスという会社で作っている新規プロダクトは、Next.jsで作られております。
この度、そのプロダクトにおいてフロントに共通資材を管理するためのUIライブラリを作りました🎉
フロントの開発体験を良くしていこう〜!という試みでチャレンジしたものの備忘録になります🙋‍♂️

どこでも、同じデザインを呼べるようにしたい

こちらで作っているプロダクトは、to C向けとto B向けの画面があり、デザインはなるべく統一する形で開発しています。

しかし、現在は同じような用途、デザインのコンポーネントが必要な場合、両方に定義していたのですが、徐々に以下の様な課題が見えてきました。

  • 微妙なレイアウトズレ
  • 共通資材のデザイン修正の際に反映漏れが出てくる
  • 複数画面でパターンがあり、共通のコンポーネントかがわからない(例えば、ボタンのcolorのパターン数が違うなど)

このまま行くと、cssとかがカオスになってきそうだったので、開発体験を改善したく、まずは共通のコンポーネント資材を管理するUIライブラリを導入することにしました。

※基本的なinstallコマンドはyarnで行っています。

今回はデザイナーサイドとの認識一致や、フロントエンジニアがデザインパターンが把握しやすいよう、storybookも導入しました。

以下に導入&各画面での呼び出しまで実装しています。

このやり方が参考になった、またはうちも導入するモチベーション上がった方がいたらいいねお願いします👍

viteでプロジェクト作成〜npm公開まで

基本的な流れはこちらの記事が非常に丁寧に書かれていたので、参考に作成しております。

eslintとprettierの設定も追加

eslintは初期作成時にすでに入っているので、あとは自分のプロジェクトに合わせたルールを設定すれば良さそう。

prettier

yarn add prettier -D

prettierrc.json は一旦最低限でいいと思い以下のように記載

{
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": false,
  "singleQuote": true
}

package.jsonも以下の内容を追記

{
 "scripts": {
    ...
    "fix": "eslint src/**/* --fix && prettier --write ." ← autofixしてくれる
  },
}

Github Actionsでのデプロイ自動化

他の記事を参考に、リリースタグを切ったタイミングでデプロイアクションが走るように定義

# .github/workflows/publish.yml

name: publish package

on:
  release:
    types: [created]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 22
          registry-url: https://npm.pkg.github.com/

      - name: Package install
        run: yarn install --frozen-lockfile

      - name: Update package.json version
        uses: jossef/action-set-json-field@v2.1
        with:
          file: package.json
          field: version
          value: ${{ github.event.release.name }}

      - name: Publish package
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

storybookの導入

以下を実行して、storybookの環境を整える

$npx storybook@latest init 

生成されたpreview.tsを以下のように記述

import type { Preview } from '@storybook/react'
import '../dist/style.css' // ← これを追加しないと、tailwindのcssが読み込めない

const preview: Preview = {
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
  },
}

export default preview

追加したコンポーネントと同じ階層に、index.stories.tsxを追加

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

const meta: Meta<typeof CustomButton> = {
  title: 'components/CustomButton',
  component: CustomButton,
  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">
        <CustomButton>Filled</CustomButton>
        <CustomButton variant={'outlined'}>Outlined</CustomButton>
        <CustomButton variant={'text'}>Text</CustomButton>
        <CustomButton variant={'filledSpecial'}>
          Filled Special
        </CustomButton>
        <CustomButton variant={'filled'} fullWidth>
          FullWidth
        </CustomButton>
        <CustomButton disabled>Disabled</CustomButton>
        <CustomButton size={'xs'}>極小サイズ</CustomButton>
        <CustomButton size={'sm'}>小サイズ</CustomButton>
        <CustomButton>中サイズ</CustomButton>
        <CustomButton size={'lg'}>大サイズ</CustomButton>
      </div>
    )
  },
}

5 package.jsonにstorybook起動のスクリプト追加

{
  "scripts": {
    ...(略)
    "storybook": "storybook dev -p 6006",
  },
}

実行すると、以下のような画面が表示されればOKです👌

storybookを外部公開(basic認証あり)

各画面からUIライブラリを呼び出す

ここが、うちの場合はyarnを使っていた&lint-stagedでコミット前にeslintのチェックをしていたのですが、
その点で少し手こずりました。

.npmrcの生成

他の記事だと、以下のように埋め込みしているものをgithubに上げて、githubのsecretsにNPM_TOKENを設定して読み込ませる。というやり方が書いてあります。
この方法だと、うちの場合はlint-stagedを使っている関係なのか、コミットするタイミングで、${NPM_TOKEN}が無いよ!というエラーが出てしまってうまくいきませんでした。

//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
@ageless-inc:registry=https://npm.pkg.github.com

そのため、.npmrcをコミットせずに、コマンド上で生成できるように定義しました。

1 .gitignoreに.npmrcを追加

.gitignore
...()
.npmrc

2 .npmrceというサンプルファイル作成

npmrce
//npm.pkg.github.com/:_authToken=
@<オーナーや組織名>:registry=https://npm.pkg.github.com

3 generate-npmrc.shで.npmrcを生成するコマンド作成

generate-npmrc.sh
// githubとかだと.envから読み込まないので、ローカル用に分岐追加している
if [ -e ./.env ]; then 
  source ./.env
fi
\cp -r ./.npmrce ./.npmrc
sed -ie "s/_authToken=/_authToken=$NPM_TOKEN/" ./.npmrc

4 .envにトークンを配置

.env
NPM_TOKEN=ghp_✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕✕

5 package.jsonにコマンド実行のスクリプト追加

{
 "scripts": {
    ...
    "preinstall": "sh ./generate-npmrc.sh"
  },
}

6 Github Actionsでyarn install前に5のコマンドを実行するstep追加

...(略)
- name: Pre Install Dependency
    run: yarn preinstall
    env:
      NPM_TOKEN: ${{ secrets.GH_NPM_TOKEN }} ← 先に環境変数をgithubに追加しておく

- name: Install Dependency
    run: yarn

7 ルートで呼び出すcssに、ライブラリのcssをインポート

index.css
// src/styles/index.css
@import '@〇〇/sample-ui/dist/style.css';
_app.tsx
import '@/styles/index.css';

ここまで整えば、ローカルで以下のコマンドを実行してUIライブラリをimportできるはずです。

$yarn preinstall
$yarn add @〇〇/sample-ui@latest

皆さんのプロジェクトでもUIライブラリを導入して、エンジニアが楽にフロント構築できる
環境を整えていけるようになることを願っております😄

Discussion