【Vue.js×Hono】Hello Worldしてみよう！


この記事はTSKaigi Advent Calendar 2024 14日目の記事です。

https://qiita.com/advent-calendar/2024/tskaigi

## はじめに

こんにちは、mocchantaiです！

最近盛り上がっているHonoでバックエンド書きたい！って思ったのに、Vue.js × Honoの記事が全然なくて困っていました。

そんな人も多いと思って、Vue.jsとHonoで一番シンプルで初歩的な記事があるだけでもめちゃくちゃ助かると思いました。

## ゴール

1. **Hono** で `/api/hello` エンドポイントを作成し、「Hello, World!」という文字列を返す
2. **Vue.js** でこのAPIを叩いて、ブラウザに表示する


## ディレクトリ構成

最終的に以下のような構成になります。
```
vue-hono-app/
├── backend/                 # Honoで構築したバックエンド
│   ├── src/
│   │   ├── index.ts         # API定義
│   ├── package.json
│   ├── tsconfig.json
│   └── wrangler.toml
├── frontend/                # Vue.jsで構築したフロントエンド
│   ├── src/
│   │   ├── App.vue          # アプリエントリ
│   │   ├── components/
│   │   │   ├── HelloWorld.vue # APIを表示するコンポーネント
│   ├── package.json
│   └── vite.config.ts
```

## 開発手順

### 1. セットアップ

まず、プロジェクトディレクトリを作成して移動します。

```zsh
mkdir vue-hono-app
cd vue-hono-app
```

### 2. バックエンドの構築

1. Honoプロジェクトを作成
```zsh
npm create hono@latest backend
```
![create-hono.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3360437/37bc0377-bac6-048e-69d4-7e88feed7909.png)


```zsh
cd backend
npm install
```

2. APIの作成
backend/src/index.ts を以下の内容に修正します。

```typescript
import { Hono } from 'hono';
import { cors } from 'hono/cors';

const app = new Hono();

app.use('/api/*', cors()); // CORSを有効化

app.get('/api/hello', (c) => c.text('Hello, World!'));

export default app;
```

差分表示
```diff
 import { Hono } from 'hono';
+import { cors } from 'hono/cors';

 const app = new Hono();

+app.use('/api/*', cors()); // CORSを有効化

-app.get('/', (c) => {
-  return c.text('Hello Hono!');
-});
+app.get('/api/hello', (c) => c.text('Hello, World!'));

 export default app;
```



3. 開発サーバーを起動

別のターミナルを開きbackendディレクトリで以下のコマンドを実行します。
```zsh
npm run dev
```
![backend-server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3360437/7e19cb44-f294-2d02-1fbc-85a9871c2f0d.png)

ブラウザで http://localhost:8787/api/hello にアクセスして、「Hello, World!」が表示されることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3360437/b3302af2-f2ba-5893-1141-40cecb01d1b4.png)


### 3. フロントエンドの構築
**1. Vue.jsプロジェクトを作成**
vue-hono-appディレクトリで以下のコマンドを実行して、Vueのプロジェクトを作成します。

```zsh
npm create vue@latest
```
プロジェクト名: `frontend`
必要に応じて TypeScript や Vue Router を選択します。

![create-vue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3360437/fd8e526f-2acd-5e50-7da8-3fbc6138790d.png)


その後、以下を実行して依存関係をインストールします。

```zsh
cd frontend
npm install
```

**2. APIを叩くコンポーネントの作成**

frontend/src/components/HelloWorld.vue を編集します。
```frontend/src/components/HelloWorld.vue
<script setup lang="ts">
import { ref, onMounted } from 'vue';

const message = ref<string>('Loading...'); // APIレスポンスを格納

onMounted(async () => {
  try {
    const response = await fetch('http://localhost:8787/api/hello'); // Hono APIにリクエスト
    message.value = await response.text(); // レスポンスを取得
  } catch (error) {
    console.error('API fetch error:', error); // エラーハンドリング
    message.value = 'Failed to fetch data.'; // エラー時のメッセージ
  }
});
</script>

<template>
  <div>
    <h1>Vue × Hono Demo</h1>
    <p>API Response: {{ message }}</p> <!-- APIレスポンスを表示 -->
  </div>
</template>
```

**3. App.vueにコンポーネントを表示**

frontend/src/App.vue を以下の内容に編集します。

```frontend/src/App.vue
<template>
  <div id="app">
    <HelloWorld />
  </div>
</template>

<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue';
</script>
```
**4. 開発サーバーを起動**
```zsh
npm run dev
```
![front-server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3360437/ac725f16-ac98-75a4-7947-4911b631d642.png)


http://localhost:5173/ にアクセスして、バックエンドAPIのレスポンスが表示されることを確認します。

![vue-hono-app-hello-world.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3360437/00a7de89-c410-edcb-3d63-efb80ba6cf69.png)

わーーーい！表示できました🙌

## 振り返り
いつもCORSのエラーに悩まされるのですが、今回はHonoの公式ドキュメントを参考に hono/cors を使ってスムーズに解消できました！

ドキュメント見るのって大事だなー

## まとめ
Hono、TypeScriptを使うのがほぼ初めてだったので簡単なものしか作れませんでしたが、同じ境遇の人がの役に立てたら嬉しいです！
これができればバックエンド、フロントエンドの開発に集中できるので、いろんな遊び方をしていきたいです！

## 参考
https://hono.dev/docs/

https://hono.dev/docs/middleware/builtin/cors

https://ja.vuejs.org/guide/quick-start.html

運営に関わらせていただきます。ぜひご参加ください！

https://2025.tskaigi.org/