概要

React.js の話をしようぜ!

いやいや、そりゃあ勿論、 Python こそが母国語であり、最高だよ? で、次点は? といえばそれはもう JavaScript と TypeScript だろう。そんな JS, TS のフロントエンドフレームワークでもっとも有名なもののひとつが、 React.js ってわけだ。

今回は、

  • yarn を使って、
  • react を立ち上げて、
  • vite-tsconfig-paths を導入して src/@/ で書けるようにして、
  • 基本的な pages, components, utils レイヤーを用意して、
  • react-router-dom を導入して SPA にして、
  • GitHub Pages へアップして、

“さあオリジナリティ出していくぜ、” のひとつ前の段階までを揃えるぜ。

 

注意点

  • プロジェクト名は my-react とする
    • 今回の記事では、プロジェクト名 (= GitHub repository 名) を my-react とする。この部分は、各自自分の好きな名前に置き換えてくれたまえ。
  • GitHub Pages ではカスタムドメインを使うトコまではやらず、シンプルな https://foo.github.io/my-react/ で動かすことを前提にする

……まあ正直、親愛なるみろりHP読者諸兄でプログラミング趣味の人はほとんど居ないと思ってるけどな!

 

yarn を使う

nodeyarn を用意してくれ。 yarn はバージョン1を用意しておこうぜ。

node --version
# --> v20.11.0

yarn --version
# --> 1.22.22

 

react を立ち上げる

yarn create vite my-react -- --template react-swc-ts
# React + TypeScript + SWC で作成

cd my-react

yarn install
# yarn.lock

yarn list react
# --> └─ react@18.3.1
# NOTE: warning が出るけど、それは完全一致検索を欠く yarn list が悪い。

yarn dev --host
# うん、開けるね。

yarn build
# うん、 dist が出来たね。

yarn preview --host
# うん、 dist の中身を開けるね。

# *.tsbuildinfo はビルドキャッシュだから、バージョン管理外にする

 

GitHub Pages へアップ

個人的に、デプロイ環境はいっちばん最初に整えておきたい。だってデプロイ環境こそがゴールなんだからさ。そこんところを、最初に整えておきたい。

まず vite.config.ts にベースの URL を設定する↓。

// vite.config.ts にこれ書いて……↓

export default defineConfig({
  base: '/my-react/', // <-- これ
})

GitHub Pages へデプロイするための yaml はこんな感じ↓だね。これを GitHub へ push したら gh-pages ブランチが出来るわけだ。そしたら Settings > Pages から、そのブランチを公開しようぜ。

# .github/workflows/deploy-react-application.yml

name: Deploy React Application

on:
  workflow_dispatch:

  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    # 忘れがちなやつ。
    permissions:
      contents: write

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"

      - name: Install dependencies
        run: yarn install

      - name: Build
        run: yarn build

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          # React のデフォルトビルド先は dist。
          publish_dir: ./dist

 

vite-tsconfig-paths を導入する

../../../components/Button みたいな import を書くのはダルすぎるので、 @/components/Button って書けるようにしようぜ。

yarn add -D vite-tsconfig-paths
# vite-tsconfig-paths を導入

公式の README を参考に vite.config.ts をこんな風に追記するぜ↓。

// vite.config.ts

import react from '@vitejs/plugin-react-swc'
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
  base: '/my-react/',
  plugins: [react(), tsconfigPaths()],
})

公式の README にハッキリ書いてなくてわかりづらいけれど、 tsconfig.json も編集する必要があるぜ↓。

// tsconfig.json

{
  "compilerOptions": {
    // ... ここでは省略 ...

    // vite-tsconfig-paths に @ -> src/ 変換してもらうための設定。
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src"]
}

ここで注意なんだけれど、最近の tsconfig は、復数に分割されているときがある。もし tsconfig.json がこんな感じ↓だったら……

{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}

baseUrlpaths 設定を書くのは tsconfig.json ではなくて tsconfig.app.json のほうだ。判断基準としては、最初から include が書いてあるほうを編集対象だと思えばいいぜ。

// tsconfig.app.json

{
  "compilerOptions": {
    // ... ここでは省略 ...

    // vite-tsconfig-paths に @ -> src/ 変換してもらうための設定。
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src"]
}

 

各種レイヤー pages, components, utils を作る

初期状態のすっからかんの React だと、何をしていいか分からんもんな。ベースを用意しよう。

# フォルダを作る。
mkdir -p src/{pages,components,utils}

# src/components/Button.tsx を作成
echo 'type ButtonProps = {
  label: string
  onClick: () => void
}

function Button({ label, onClick }: ButtonProps) {
  return <button onClick={onClick}>{label}</button>
}

export default Button' > src/components/Button.tsx

# src/utils/formatDate.ts を作成
echo 'function formatDate(date: Date): string {
  return date.toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
  })
}

export default formatDate' > src/utils/formatDate.ts

# src/pages/HomePage.tsx を作成
echo 'import Button from "@/components/Button"
import formatDate from "@/utils/formatDate"
import { useEffect, useState } from "react"

function HomePage() {
  const [formattedDate, setFormattedDate] = useState<string>('')

  useEffect(() => {
    const currentDate = new Date()
    const dateStr = formatDate(currentDate)
    setFormattedDate(dateStr)
  }, [])

  const handleClick = () => {
    alert("Button clicked!")
  }

  return (
    <div>
      <h1>Welcome to the Home Page - {formattedDate}</h1>
      <Button label="Click Me" onClick={handleClick} />
    </div>
  )
}

export default HomePage' > src/pages/HomePage.tsx

# src/pages/NotFoundPage.tsx を作成
echo 'function NotFoundPage() {
  return (
    <div>
      <h1>Not Found</h1>
    </div>
  )
}

export default NotFoundPage' > src/pages/NotFoundPage.tsx

これでファイル完成。まだ、 HomePage.tsx を実際に使うようにはなっていない。次の項目でそこを作る。

 

react-router-dom を導入して pages を使うようにする

パッケージをインストールして、 main.tsxApp.tsx を編集する。

yarn add react-router-dom

echo 'import App from "@/App"
import "@/index.css"
import React from "react"
import ReactDOM from "react-dom/client"
import { BrowserRouter } from "react-router-dom"

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <BrowserRouter basename="/my-react">
      <App />
    </BrowserRouter>
  </React.StrictMode>
)' > src/main.tsx

echo 'import "@/App.css"
import HomePage from "@/pages/HomePage"
import NotFoundPage from "@/pages/NotFoundPage"
import { Route, Routes } from "react-router-dom"

function App() {
  return (
    <Routes>
      <Route path="/" element={<HomePage />} />
      {/* その他のパスは 404 */}
      <Route path="*" element={<NotFoundPage />} />
    </Routes>
  )
}

export default App
' > src/App.tsx

以上だ!

 

おしまい

以上を GitHub Pages へ push すると、こんな風に動くハズだぜ。

あとは、画面を追加したかったら pages を増やしていき、 UI パーツを増やしたかったら components を増やしていき、処理を共通化したかったら utils を増やしていけばいいというわけだ! こういう風に、作業の基盤があるとやりやすいんだよねー。

React.js は、みろりHPのフロントエンドにどうかな、と思って始めてみたのだ。 Vue.js も候補にあったのだけど、 Vue.js の最新バージョン3は、 React.js にその特徴を寄せてきているらしいから、 “はーん、じゃあ React.js のほうがええんや?” と単純に考えたわけだ。