概要
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 repository 名) を
- GitHub Pages ではカスタムドメインを使うトコまではやらず、シンプルな
https://foo.github.io/my-react/
で動かすことを前提にする
……まあ正直、親愛なるみろりHP読者諸兄でプログラミング趣味の人はほとんど居ないと思ってるけどな!
yarn を使う
node
と yarn
を用意してくれ。 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" }
]
}
baseUrl
と paths
設定を書くのは 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.tsx
と App.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 のほうがええんや?” と単純に考えたわけだ。