はじめに
TypeScript はフロントエンド開発とバックエンド開発の両方で利用することができます。
この記事では、フロントエンドとバックエンドの両方で TypeScript を利用したToDoリストのWebアプリを開発します。
開発環境
- Windows11
- VSCode
- TypeScript 4.9.5
- React 18.2.0
- React Router 6.10.0
- Vite 4.1.0
プロジェクトフォルダの作成
まずWebアプリ用に todo-app
というフォルダを作成し、その中に frontend
と backend
というフォルダを作成しました。
バックエンド開発
まずはバックエンドを開発してきます。
package.jsonの作成
Node.jsでのアプリ開発を行うため、以下のコマンドで package.json
を作成します。
yarn init -y
以下の package.json
ファイルが作成されます。
{
"name": "backend",
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
tsconfig.jsonの作成
TypeScriptを利用できるようにするため、以下2つのパッケージをインストールします。
- typescript
- @types/node
yarn add -D typescript @types/node
yarn.lock
や node_modules
が新たに作成され、package.json
にも以下の値が追加されます。
"devDependencies": {
"@types/node": "^18.15.5",
"typescript": "^5.0.2"
}
次に tsconfig.json
を作成するため、以下のコマンドを実行します。
yarn tsc --init
作成された tsconfig.json
内の target
を "esnext"
に変更します。
Expressの導入
Node.jsのフレームワークであるExpressを導入します。
以下のコマンドでExpressをインストールします。
yarn add express
package.json
に以下の値が追加されます。
"dependencies": {
"express": "^4.18.2"
}
TypeScriptを使うため、以下のコマンドも実行します。
yarn add -D @types/express
package.json
の "devDependencies"
に "@types/express": "^4.17.17"
が追加されます。
次にバックエンド開発のメインのファイルとなる server.ts
というファイルを backend
フォルダ直下に作成します。そして、package.json
の "main"
を "server.js"
に書き換えます。
server.ts
では、Express を利用できるように以下のコードを書きます。
import express, { Express } from "express";
const app: Express = express();
Expressの起動
実際にExpressを起動して、動作確認をしてみます。
確認用にログを出力するコードを書きます。
import express, { Express, Request, Response } from "express";
const app: Express = express();
const port = 3001;
app.get("/", (req: Request, res: Response) => {
res.send("Hello World!");
});
app.listen(port, () => {
console.log(`listening on port ${port}`);
});
次にTypeScriptをNode.jsで実行するために ts-node をインストールします。
yarn add -D ts-node
そして、ローカルサーバーを起動します。
yarn ts-node server.ts
ローカルサーバーを起動することができ、ログも表示されました。
また、ブラウザで http://localhost:3001 にアクセスすると、「Hello World!」と表示されます。
CROS設定
次に CORS1 対応のため、CORS というミドルウェアをインストールします。TypeScript対応のため、@types/cors も一緒にインストールします。
yarn add cors @types/cors
次にCORSをインポートして全てのAPIをCORS許可します。
import express, { Express, Request, Response } from "express";
import cors from "cors";
const app: Express = express();
const port = 3001;
app.use(cors());
ToDoリスト取得機能の実装
ToDoリストの取得機能を実装します。
まずはToDoの型を定義します。
export type Todo = { id: number; title: string; completed: boolean };
次に "/todo-list"
にアクセスすると、ToDoリストを返すようにします。
import express, { Express, Request, Response } from "express";
import { Todo } from "../types";
import cors from "cors";
const app: Express = express();
const port = 3001;
app.use(cors());
const sampleData = [
{ id: 1, title: "牛乳を買う", completed: false },
{ id: 2, title: "洗濯をする", completed: true },
{ id: 3, title: "請求書を支払う", completed: false },
];
let todoList: Todo[] = sampleData;
app.get("/", (req: Request, res: Response) => {
res.send("Hello World!");
});
app.get("/todo-list", (req: Request, res: Response) => {
res.json(todoList);
});
app.listen(port, () => {
console.log(`listening on port ${port}`);
});
これでバックエンドの開発は完了です!
フロントエンド開発
次はフロントエンドを開発していきます。
Reactプロジェクトの作成
以下のコマンドでプロジェクトを作成します。
yarn create vite . --template react-ts
以下のコマンドを実行すると、ローカルサーバーが起動します。
yarn
yarn dev
vite.config.ts
でポートの指定やローカルサーバー起動時にブラウザを自動起動する設定を追加することができます。
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
open: true,
},
});
ルーティング作成
次にルーティングを作成します。
今回は React Router を利用します。
まずは、以下のコマンドでインストールします。
yarn add react-router-dom
次にフロントエンドのコードにルーターを追加します。
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
const router = createBrowserRouter([
{ path: "/", element: <div>ToDoリスト</div> },
]);
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
動作確認をします。ルートにアクセスすると、「ToDoリスト」と表示されることが確認できました。
ToDoリストコンポーネント作成
次は <div>ToDoリスト</div>
と書いていた箇所をコンポーネント化します。
import { FC } from "react";
export const Home: FC = () => {
return (
<div>
<h1>ToDoリスト</h1>
</div>
);
};
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { Home } from "./routes/Home";
const router = createBrowserRouter([{ path: "/", element: <Home /> }]);
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
バックエンドへアクセス
次はいよいよ先に作成したバックエンド(APIサーバー)へアクセスする機能を実装します。今回は Fetch API と SWR を利用して実装します。
まずは、SWR をインストールします。
yarn add swr
次に fetch
をSWRで利用できるようにするため、fetch
をラップした fetcher
関数を作成します。
export const fetcher = async (path: string) => {
try {
const res = await fetch("http://localhost:3001" + path);
return res.json();
} catch (error) {
alert(error);
}
};
次にSWRを利用して、ToDoリスト取得できるようにします。
export const useTodoList = () => useSWR<Todo[]>("/todo-list", fetcher);
そして、Home
コンポーネント内で useTodoList
をインポートしてAPIを呼び出し、その結果をレンダリングします。
import { FC } from "react";
import { useTodoList } from "../api";
export const Home: FC = () => {
const { data: todoList, error, isLoading } = useTodoList();
if (error) return <div>failed to load</div>;
if (isLoading) return <div>loading...</div>;
return (
<div>
<h1>ToDoリスト</h1>
<ul>
{todoList?.map((todo) => (
<li key={todo.id}>
<input
type="checkbox"
id={String(todo.id)}
checked={todo.completed}
/>
<label htmlFor={String(todo.id)}>{todo.title}</label>
</li>
))}
</ul>
</div>
);
};
最後に
今回はフロントエンドとバックエンドの両方でTypeScriptを利用したToDoリストのWebアプリを開発しました。両方とも同じ言語だと実装しやすいですね。
参考
- CORSを絶対に理解する
- Express
- Fetch API
- SWR
- ts-node
- Tutorial v6.10.0 | React Router
- 【TypeScriptあり】Node.jsとReactでWebアプリを作る【Express使います】
- yarn init --yes/-y
- @types/cors - npm