【登竜門Hack関西-Web講座】超初心者向け！たった4時間でやってみるWebフルスタック

:::note
[これは何]
登竜門Hack関西2024Web講座の資料
:::
:::note warn
[外部公開にあたって]
この記事は初学者向けに短時間でツール群や概念を説明するために、意図的に言葉の解像度を落としたり、誇張した表現を行なっている箇所があります
:::


 ## 講師自己紹介

 ### Yuma-Satake
 
 - 名前：佐竹友真
 - 所属：名古屋工学院専門学校(3年)・Matsuriba・NKC-UG・TechUni
 - 領域：Webフロントエンド
 - 趣味：車・旅行
 - Twitter：[Yuma-Satake | Matsuriba代表🏮
](https://x.com/yuma_satake22)

 <img width="200px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/aaf685a0-0af0-5e5b-92e9-a6f0275812fc.jpeg">
 
  - 受賞歴（~~講師なんて、こんなもんなんぼ書いてあってもええですからねぇ~~）
     - 技育CAMP Vol.10（入賞）
     - 技育CAMP Vol.11（入賞）
     - 関西ビギナーズハッカソン（最優秀賞）
     - 技育CAMPアドバンス Vol.1 （大賞）
     - カラビナハッカソン （カラビナ賞受賞）
     - マイナポータルハッカソン （本戦出場）
     - 技育CAMP Vol.5（最優秀賞）
     - 名古屋Web3ハッカソン（4冠）
     - 技育CAMPアドバンス Vol.3（GMO賞）
     - 技育展2023（サイバーエージェント賞受賞）
     - 技育CAMP Vol.5（DeNA賞）
     - etc...


## 初めに

### Webアプリケーションに触れてみよう

今日のWebアプリを見せたメンターの反応

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/e0636b73-1c7f-d254-1c0d-014a909a558a.png"/>

👉リンクにアクセス：[SaTyping【登竜門Hack2024デモWebアプリ】](https://hack-kansai-2024-web-tutorial.web.app)

https://github.com/toryumon-pj/hack-kansai-2024-web-tutorial

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/5153e1eb-87fd-ccc1-7b25-782e423ef924.png)

---
### 触ってみてどう感じた？

- 処理複雑そう
- 何から学んでいけば良いんだろう
- サイトとして公開するのって大変そう
- めっちゃ時間かかりそう
- etc...

### 講座の目的

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/870ba76f-be81-07ee-3fc6-39b9e793d049.png" />

４　時　間　で　W　e　b　ア　プ　リ　ケ　ー　シ　ョ　ン　全　部　な　ん　て　無　理　😇

:::note alert
Webアプリが作れるようになる
:::

:::note info
皆んなが「Webアプリ開発って思ったより簡単やんw」ってなる
:::

- ここで`JS`の文法教えたって誰も覚えてない
- そんな（ライブラリ・技術）があるんだ、へぇーを目指す
- みんなが思ってるより、Webって簡単に作って楽しめるんだぜ！！を伝える
（~~過激なこと言うのでメンター陣に刺されるかも~~）

## Web？モバイル？

### Webとモバイルの比較

Webアプリにするのか、モバイルアプリにするのか、それが問題だ。

| 特徴              | Webアプリケーション                  | モバイルアプリケーション          
|-----------------|----------------------------------|----------------------------|
| アクセス方法         | ブラウザ                      | デバイスにインストール      |
| デバイス互換       | 全てのデバイスで利用可能            | 対応したOSのみ             |
| 更新方法           | サーバー側で自動更新               | ユーザーが手動で更新         |
| 使い始め        | URLを踏んで利用開始   | ストアからインストールして利用     |
| オフライン利用       | 基本的にインターネット接続が必要 | オフラインでも一部機能が利用可能|

**今から開発したいサービスはどんな特徴を持ってそう？**
例えば→（そもそも使われるのはPC？スマホ？・重い処理はある？・センサーが必要？）

### それぞれの長所（一部）

#### 🔥 Webアプリの長所
- **スタートの手軽さ**：リンクを踏むだけで使い始められる
- **デバイス互換性**：ブラウザが使える環境なら、どんな端末でもアクセス可能
- **軽量な使用**：ストレージなどを圧迫する事なく使用できる

#### 🔥 モバイルアプリの長所
- **頻繁な利用に強い**：アプリとしてワンタップでアクセスできる
- **パフォーマンスの高さ**：デバイスの性能を直接引き出せる
- **センサー等の活用**：加速度センサーなどを活かしたサービス開発ができる

<br>

✅ サービスの特徴や使われ方によって、どちらとして開発をすべきかは決まってくる

```ts
if(PCで使われそう）return Webの方が良い
if(リンクから簡単に使ってもらいたい）return Webの方が良い
if(ゲームなど、高いパフォーマンスが必要ない）return Webの方が良い
if(センサー等を使ったサービスではない）return Webの方が良い

return モバイルアプリケーションとして開発しよう
```

[補足]
もちろん勉強目的でモバイルアプリを開発する事は素晴らしいことだが、一般論としてモバイルアプリケーションは開発/運用コストが高く、Webアプリケーションで済むのであればWebアプリケーションとして展開した方が良いという考え方もある

→ 何故モバイルアプリとして開発をしました、が言えると考えられたサービスである事がわかる

## ✅ それでは再確認

この講座の目的は？

:::note info
皆んなが「Webアプリ開発って思ったより簡単やんw」ってなる
:::

今回はやりません

:::note warn
JavaScriptの記法・データベースの設計など
:::

#### [ 午前: 10:00〜12:00 ]

午前中（2時間は4つのステップでやっていき💪

① Webアプリの構成：Webアプリの種類
② フロント・バック・WebAPI：どんな仕組みでモダンなWebが動いているか
③ フロントエンド：React・TypeScriptで書かれてるコードを読んでみる
④ バックエンド：Supabaseで簡単DB

#### [ 午後 13:00〜15:00 ]
午後（2時間）はハンズオン形式でやっていきます

① VSCodeのインストール：Webでよく使われるエディタであるVSCodeのインストール
② やってみよう環境構築：git cloneから始める、初めての環境構築
③ プロジェクト作成：React・Viteを使って初めてのプロジェクト作成
④ 初Hosting：FirebaseHostingを使ってプロジェクトをデプロイ

# ーーー [ 午前のターン！！ ] ーーー

### [ 午前のお品書き ]

① Webアプリの構成：Webアプリの種類
② フロント・バック・WebAPI：どんな仕組みでモダンなWebが動いているか
③ フロントエンド：React・TypeScriptで書かれてるコードを読んでみる
④ バックエンド：Supabaseで簡単DB

## ① Webアプリの構成

### 😇 Webアプリケーションの技術は移り変わりが激しい

Webアプリケーションの技術は移り変わりが激しく、様々な言語やフレームワークが生まれては廃れていっています。
ですが、根本的な仕組みとしては主に仕組みの違う2つの形態が存在し、ここでは便宜上2つを

- レガシーなWebアプリ
- モダンなWebアプリ

という呼び分け方をします。（曖昧な表現です）


### 🛖 レガシーなWebアプリ

Web初期から存在するフレームワークとして、例えばPHPやJavaなどのWebフルスタックフレームワークがあります。
これらはサーバーサイドで全てを処理し、HTMLを生成してクライアントに返すという仕組みです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/00e984ae-e482-17e4-8e08-381a4e9b6b5f.png)

| 技術例 | PHP（Laravel）, Java（SpringBoot）, Ruby（Ruby on Rails） |
|------|---------------------------|

**→ 枯れた技術故に安定しているが、画面がリッチにしずらい・開発体験が悪いなどがある**

### 🏢 モダンなWebアプリ

最近の新規開発では殆どでこちらが採用される。
フロントエンド（ユーザが触る画面側）とバックエンド（サーバーでデータを処理したり保存する側）が分離され、それらがAPIを通じて通信を行う構造。
例えば、フロントエンドはJavaScript、バックエンドはPythonやGoなどを使用します。

| 技術例 | Javascript（フロントエンド）, Node.js, Python, Go（バックエンド）|
|------|---------------------------|

**→ レガシーなWebアプリでの歴史を踏まえ、リッチな画面を、開発しやすい形で作れる**

### 💻 いろんなサイトを見てみよう

どんな技術が使われてるかを見れるChrome拡張

https://chromewebstore.google.com/detail/wappalyzer-technology-pro/gppongmhjkpfnbhagpmjfkannfbllamg?hl=ja

`Python`の`Django`っていうフレームワークが使われてるらしい。
→こいつはフルスタッフフレームワークなので、レガシータイプっぽい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/f5974dfa-c77b-6685-e2dc-cc9708cab3ab.png)

`JavaScript`の`React`が使われてるらしい。
→こいつはWebフロントエンドのフレームワークなので、モダンっぽい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/1feeccb4-8d24-483e-8fe4-574bc720c69b.png)



### ✅ 今回はモダンなWebアプリについて解説します
現在ではWebAPIを用いたモダンなWebアプリが主流なのでこちらを採用。
理解を優先してしつつも、RDBに触れてもらいたく、バックエンドについてはBaaS（Backend as a service）を選定、一般的なサービスの全体の仕組みを俯瞰してもらいたい。

#### [ 技術構成 ]

- フロントエンド
    - TypeScript：型の付いたJavaScript
    - React：JavaScriptのフレームワーク
    - MUI：React向けUIライブラリ
- バックエンド
    - Supabase：リレーショナルデータベースを簡単に使える
- インフラ
    - Firebase：BaaSのうち、特にHosting（サイトの公開）機能を利用

ーーーーーーーーーーーーーーーーーーーーー

## ② フロント・バック・WebAPI

モダンなWebアプリって、2つのパーツに分かれて動いてるらしいけど、どうなってんの？

#### [ フロントエンド ]
どこで動いてる？"ユーザの端末のブラウザの上"
データを表示したり、ユーザの操作をサービスに反映させたりする

✅ 天気を知りたい → サーバー（バック）から天気の情報を取得して表示する
✅ 商品購入ボタン → サーバに購入のリクエストを送る


#### [ バックエンド ]
どこで動いてる？"どこかにあるサーバーの上"
フロントエンドにデータを渡したり、飛んできたデータを保存したりする

✅ 商品一覧を見たい → フロントエンドに商品のデータをあげる
✅ ログインしたい → メールアドレスとパスワードを受け取って、チェックしてあげる


#### 🤔フロントエンドとバックエンドはどうやって連携してるの？

**WebAPI** という仕組みでデータをやり取りしている

ランキングのデータが取得される流れを解説

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/bb745cdd-462c-9c62-1b95-530709012acf.png)


[ フロント→バックへのリクエスト ]
意訳：game_scores_tableの中身を、20件を上限にして全部よこせ

- `supabase.co`：どこのサーバーにリクエストしているのか
- `/game_scores_table`：欲しいデータを指定
- `?limit=20`：取得するデータの制限

```
 https://eruqxkbrgicziahqqycx.supabase.co/rest/v1/game_scores_table?select=*&order=score.desc&limit=20
```

[ バック→フロントエンド ]
意訳：おけ、4つのデータが入ったオブジェクトを配列にして返すで

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/3bb2a0e6-8544-4797-01a9-9e810b920db3.png)

### 💻 実際のサービスを見てみよう

[Twitter](https://x.com/home)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/b3952d24-5df4-e36f-8744-a3f69674fa4b.png)

[ChatGPT](https://chatgpt.com/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/f60b26c0-214d-1a6e-87d6-b7c4ae3fa98f.png)

## ③ フロントエンド：React・TypeScriptで書かれてるコードを読んでみる

#### 全　然　簡　単　じ　ゃ　ね　ぇ　じ　ゃ　ん　😇

わかる。
でも俺の説明は悪くない。
そもそも難しいWebの仕組みが悪い

**でも大丈夫！！！！！**

:::note info
Webフロントで覚えるべきは、**状態** と **スタイリング** だけ！！
:::

### ① 基本的に全部"状態"

状態って何。。？

<details><summary>↓↓↓ 数字が◯◯っていう"状態"
</summary>
17
</details>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/9fd3ad6f-90e9-96d3-0075-8e0e97d4aa2d.png)

<details><summary>↓↓↓ 数字が◯◯っていう"状態"
</summary>
25
</details>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/feb235d2-c7e8-a204-0c06-c2d1501a5240.png)

<details><summary>↓↓↓ モーダルが◯◯という"状態"
</summary>
開いている
</details>

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/15679fb4-4352-6007-234d-4282e8fa72e3.png" />


<details><summary>↓↓↓ モーダルが◯◯という"状態"
</summary>
開いていない
</details>

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/ada6488a-05f4-7f0d-1bc9-3e421b3a5dc4.png" />

<details><summary>↓↓↓ ◯◯◯◯◯◯っていう文字列が入力されている"状態"
</summary>
Circle
</details>

<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/752d31a6-9b9a-8fe1-5105-b5f64ea8b48e.png" />

<details><summary>↓↓↓ ◯◯◯◯◯◯◯◯◯◯あるっていう"状態"
</summary>
{ ranking, nickName, score} というオブジェクトの配列が
</details>

<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/5cef77e0-4565-6117-0367-3fed7c4a6da6.png" />

### 基本的に全部"状態"

Reactでは全て、以下の`useState`で状態を管理する。
基本的にこれ以外に管理の方法はない（誇張した表現）
```typescript
const [state, setState] = useState<Type>(initialValue)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/3bd8de02-acea-22b4-29e8-64665c3cd998.png)

※ここでは本来は`query`というものを用いることが多い

:::note info
つまり"状態管理"を覚えることで

- ランキングの表示
- タイプされている文字の管理
- スコアの表示
- 残り時間の管理
- モーダルを閉じたり開けたり
- etc...

ができるようになる
:::

### ② やろうぜ、スタイリング

Q：つよつよフロントエンジニアの皆さんが思う、フロントの難しいことって？
→ CSS 😇（スタイリング）& etc...

#### [ スタイリングとは ]
Webページの見た目を定義するためのスタイルシート言語であり、HTMLなどで記述された要素のスタイルやレイアウトを指定すること

```css
body {
  font-family: Arial, sans-serif;
  margin: 20px;
}

h1 {
  color: blue;
}

p {
  font-size: 16px;
  line-height: 1.5;
}

a {
  color: red;
  text-decoration: none;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/70a9f1ba-db78-0c32-af22-a0962a6f68ea.png)


#### mdn docs の css のところを見てみよう


https://developer.mozilla.org/ja/docs/Web/CSS


<img width="150px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/d373518a-066a-0c3a-4ac7-6545597d5fed.png" />

<img width="150px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/54228d0e-8e85-1ea4-f851-c2b43b55f057.png" />

<img width="150px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/cf419287-b585-a91d-cccf-8e08f9d7a853.png" />

<img width="150px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/c1b8b7c2-9db7-8bed-f8a7-7de823914913.png" />


#### 呆れるぐらいCSSのプロパティは多い。
2024年現在では、`500`以上のCSSプロパティが存在する。
Webフロントやり初めて2年ぐらい経つけど、いまだにCSSがなぜか適用されなくて困ることなんてざらにある。
たまにしか使わないプロパティは仕様を忘れるので、`mdn docs`に頻繁にお世話になる。

#### 🥲 どうすればいいか？CSSを書かなければいい

特に`React`には無数の`UIライブラリ`や`コンポーネントライブラリ`が存在する

#### [ UIライブラリとは ]
UIを構築するための再利用可能なコンポーネント。
例えばボタン・フォーム・モーダル・ナビゲーションなどを簡単に実装できる

#### 例えばこのボタンで比較

以下のボタンを`CSS`と`MUI`で実装した場合の比較（贔屓あり）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/2d815575-fa51-e49d-55ff-3fe50acdcbbb.png)

##### ① `CSS`のみでこのボタンを再現した場合
`hover`・`disable`の時のスタイルなども記述が必要で、思っている以上に大変

```css
/*
完全に同じスタイルにはなりません
*/
 <style>
        .button-contained {
            background-color: #1976d2;
            color: white;
            padding: 6px 16px;
            font-size: 0.875rem;
            min-width: 64px;
            box-shadow: 0px 3px 1px -2px rgba(0,0,0,0.2), 0px 2px 2px 0px rgba(0,0,0,0.14), 0px 1px 5px 0px rgba(0,0,0,0.12);
            border-radius: 4px;
            border: none;
            cursor: pointer;
            text-transform: uppercase;
            transition: background-color 0.3s, box-shadow 0.3s;
        }
        .button-contained:hover {
            background-color: #1565c0;
            box-shadow: 0px 3px 3px -2px rgba(0,0,0,0.2), 0px 3px 4px 0px rgba(0,0,0,0.14), 0px 1px 8px 0px rgba(0,0,0,0.12);
        }
        .button-contained:active {
            box-shadow: 0px 5px 5px -3px rgba(0,0,0,0.2), 0px 8px 10px 1px rgba(0,0,0,0.14), 0px 3px 14px 2px rgba(0,0,0,0.12);
        }
        .button-contained:disabled {
            background-color: rgba(0, 0, 0, 0.12);
            color: rgba(0, 0, 0, 0.26);
            box-shadow: none;
            cursor: not-allowed;
        }
    </style>
```

##### ② UIライブラリである`MUI`を使用した場合

```typescript
<Button variant="contained" />
```

#### MUI
`MUI(旧material-ui)`はGoogleの提供する`Matsruial-Design`をReactのコンポーネントとして簡単に使えるようにしたUIライブラリ。
メインになる`MUI core`だけでも`65`ものコンポーネントがある。


https://mui.com/material-ui/

https://m3.material.io

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/0d30e126-f208-259c-8c3f-874e1a98c8d8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/05fd3323-e461-c044-1cd8-20fa5e7bffb2.png)

凄まじい数のアイコンが同封されていて、簡単に使うことができる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/de65de05-1376-9cc3-167a-d610ee106f08.png)




#### UIライブラリ一覧

それぞれに特徴のあるUIライブラリが多数存在する。
UIライブラリをうまく活用することによって、CSSの記述量をグッと減らすことができる。


※ 一部UIライブラリでないものを含む

| 名前       | GitHubリポジトリ          | 特徴     |
|------------|---------------|----------------------------|
| MUI        | [mui/material-ui](https://github.com/mui/material-ui) | - 高度にカスタマイズ可能なReactコンポーネントライブラリ<br>- デザインシステムの構築をサポート<br>- コンポーネントの豊富なセット |
| Chakra UI  | [chakra-ui/chakra-ui](https://github.com/chakra-ui/chakra-ui) | - シンプルでモジュール化されたコンポーネント<br>- デフォルトでレスポンシブデザイン対応<br>- 優れたアクセシビリティのサポート |
| Tailwind CSS | [tailwindlabs/tailwindcss](https://github.com/tailwindlabs/tailwindcss) | - ユーティリティファーストのCSSフレームワーク<br>- クラスベースでスタイリング<br>- カスタマイズが簡単 |
| Mantine UI  | [mantinedev/mantine](https://github.com/mantinedev/mantine) | - 高度にカスタマイズ可能なReactコンポーネントライブラリ<br>- 完全にタイプセーフ<br>- ユーザーインターフェースを簡単に構築 |
| shadcn-ui  | [shadcn/ui](https://github.com/shadcn/ui) | - シンプルでモジュール化されたReactコンポーネント<br>- デザインシステムと統合が容易<br>- 高度なカスタマイズが可能 |

#### CSSを全く書かない訳ではない

実際には、`MUI`等のUIライブラリを`CSS`で拡張して記述することが多い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/5e958b52-9ac1-3a74-52e2-ba2d8683015d.png)

#### CSSを書かなければいい
もちろん`CSS`を知っていないと使えないものも多い！でも、

:::note info
UIライブラリをうまく使うことによって、難関であるスタイリングをかなり楽にできる
:::

### ✅ ここまで知ったで、今回のフロントエンドのリポジトリを見てみよう

`hack-kansai-2024-web-tutorial`

見るポイント
① 基本的に全部`状態`
② `スタイリング`は楽していこう　

https://github.com/toryumon-pj/hack-kansai-2024-web-tutorial

## ④ バックエンド：Suapbaseで簡単DB

Webフロントで覚えるべき→`状態`と`スタイリング`だけ
じゃぁ`バックエンド`は？

:::note info
とりあえず`CRUD`できるだけで、割と色々できる！！
:::

#### [ CRUDとは ]
データベースに対する

- `Create`（作成）
- `Read`（読み取り）
- `Update`（更新）
- `Delete`（削除）

の4つの操作。
つまりデータベースに対して行う基本的なデータの読み書きの4操作の頭文字をとったもの。
実はバックエンドの多くの開発は、この`CRUD`を実行するためのAPIを作ることに割かれている。

#### `CRUD`だけで割と色々できるぜ

例えば`ランキング機能`を例にとると

- 新しいスコアをデータベースに登録する：`Create`
- ランキングの一覧を取得する：`Read`
- ユーザーのスコアを更新する：`Update`
- 古いスコアを削除する：`Delete`

といった操作は全て`CRUD`以上にロジックを含んでおらず、データを読み書きしているだけ、ということが分かる。

### 🚀 `Supabase`で`CRUD`をする方法

`Supabase`とは、`Backend as a Service（BaaS）`の一つ
認証・DB・関数実行などの本来バックエンドで実行する内容をフロントエンドのコードにまとめて記述することができるようになる。

https://supabase.com

#### スコアを`Create（Insert）`する
```ts
await supabase.from(('game_scores_table').insert({
  player_nickname: nickName,
  score: playScore
})
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/c3c1a1ad-4c55-ba29-c8c4-323cde20e0b6.png" width="300px" />

#### ランキングを`Read（Get）`する
全部のスコアを`score`で並び替えて、`limit`件上限で取得
```ts
const { data } = await supabase
    .from('game_scores_table')
    .select('*')
    .order('score', { ascending: false })
    .limit(limit);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/a3096b61-b0ee-b4a1-21e8-e8eb3d4d49e1.png)

#### スコアを`Update(Upsert)`する
`plyer_nickname`が被っている場合には上書きする
```ts
await supabase.from('game_scores_table').upsert(
    {
      player_nickname: nickName,
      score,
    },
    {
      onConflict: 'player_nickname',
    }
);
```

#### 古いスコアを`Delete`する
```ts
await supabase.from('game_scores_table').delete().match({
    player_nickname: player_nickname,
})
```

#### CRUDだけで割と色々できる

もちろん制限や取得方法の工夫などはあるが、これらの機能はDBに読み書きを行っているだけで、特定のロジックを持っていない。
`BaaS`等を利用したりすることで、思ったより簡単にできる事は広がる。

:::note info
とりあえず`CRUD`できるだけで、割と色々できる！！
:::

### 🚀 `GUI`でDB構築

#### DB用語について

##### DBって何？

データベース（DB）とは、サービス内で使うデータを効率的に保存、管理、検索するための仕組み。大量のデータを整理し、必要なデータを迅速に読み出したりできるようにしている。
RDB・NoSQLなど様々種類があるが、RDB（リレーショナルデータベース）が主流。

##### SQL

SQL（Structured Query Language）とは、データベース管理システムに対してデータの操作やクエリを実行するための標準的なプログラミング言語です。

#### DBムズイ

一般的にRDB（リレーショナルデータベース）を作成する場合には、`SQL`を実行してDBを作成する。
※そもそもRDBが何かを説明していると1日終わるので、 DBは`データを突っ込む表形式の箱の集まり`ぐらいの認識でOK

↓↓↓ 使っている`game_scores_table`を作成する`SQL`
```sql
CREATE TABLE game_scores_table (
    score_id UUID PRIMARY KEY,
    player_nickname TEXT NOT NULL,
    score INT8 NOT NULL,
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
```

- `SQL`わからん...
- いちいちコマンドを叩かないと状況がわからない

→ 初学者には普通にむずい😇

#### `Supabase`はGUI上でDBを作成できる

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/95eb51c2-5b42-0b85-325e-1129fba81a9b.png" />


### 🪐Supabaseの活用
#### [ 認証機能 ]
`Googleでログイン`や`Githubでログイン`といったよくあるログインを簡単につくれる
（ハッカソンではまじでおすすめ。認証部分だけBaaSに投げてるチームもよくみる）

https://supabase.com/docs/guides/auth

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/ba1fee35-10d2-0537-d394-59b502817110.png)


#### [ リアルタイムDB ]
通常の`WebAPI`は、呼び出さないとデータが更新されない。
`WebSocket`と呼ばれる技術を簡単に使うことができ、同時編集や、リアルタイム対戦などが実装できる。
（カーソルの位置やプレイヤーの位置をリアルタイムで反映させられる）

https://supabase.com/docs/guides/realtime

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/72445099-4aa1-76b7-9d9f-38855fbb0e98.png)

# ーーー [ 午後のターン！！ ] ーーー

### [ 午後のお品書き ]

① VSCodeのインストール：Webでよく使われるエディタであるVSCodeのインストール
② やってみよう環境構築：git cloneから始める、初めての環境構築
③ プロジェクト作成：React・Viteを使って初めてのプロジェクト作成
④ 初Hosting：FirebaseHostingを使ってプロジェクトをデプロイ

## ① `VSCode`のインストール

### VSCodeとは？

VSCode（Visual Studio Code）は、多くの開発者に使われている人気のソースコードエディタです。様々なプログラミング言語に対応でき、豊富な拡張機能を利用して自分好みにカスタマイズできる。そしてこれが無料。ありがとうMS。

https://code.visualstudio.com/download

### インストール

それぞれのPCに合ったインストーラを選択して、インストール！
（win機の人は、インストーラーが降ってくるかもだけど、展開して全部`next`）

| PC の種類                 | セレクト                                                                       |
| ------------------------- | ------------------------------------------------------------------------------ |
| Windows の方              | ↓ Windows |
| Mac の方                  | ↓ Mac |

<br>

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/af4e8ac6-e1a0-8702-2fcb-1de04215ab25.png" />

:::note info
GitとVSCode入ってれば大抵のプロジェクトは開ける！！
:::


## ② やってみよう環境構築

### `git clone`して、手元にプロジェクトをダウンロード
ここでは`git`・`github`の構築は取り扱いません（git講座で完了済み）

https://github.com/toryumon-pj/hack-kansai-2024-web-tutorial

1. VSCodeを起動して、左上メニューバーから`フォルダを開く`で`デスクトップ`を選択
1. 左上メニューバーから`ターミナル→新しいターミナル`を選択（3点リーダーに隠れてる場合がある）
1. ターミナルで`git clone https://github.com/toryumon-pj/hack-kansai-2024-web-tutorial.git`でエンターキーを押下
1. デスクトップに`hack-kansai-2024-web-tutorial`のフォルダができている事を確認する
1. 作成されていることが確認できたら、一旦VSCodeは閉じる

:::note warn
作業ミス防止のために、必ず一旦VSCodeは閉じてください
（誤ったディレクトリでの実行を防ぐため）
:::

### `README.md`を読んで環境構築

#### ✅ README.mdを読んで環境構築する意味

どんなリポジトリにも基本的に`README.md`というファイルが入っています。
これはそのプロジェクトの`GetStarted（環境構築の方法）`や操作方法が書いてあり、これをしっかり読んで環境構築をすることは、つよつよエンジニアへの第一歩になります。

#### 1.プロジェクトフォルダを開く
`VSCode`の左上のバーから`ファイル→フォルダを開く`で`hack-kansai-2024-web-tutorial`のフォルダを開いて下さい。
合わせてVSCodeからターミナルも開いておきましょう。

#### 2.`README.md`を開く
VSCodeでは`markdown（拡張子が.md）`を`右クリック→プレビューを開く`でプレビュー表示することができます

<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/c58e6c3b-d632-b50c-89c0-a3e428526e01.png" />

#### 3.プロジェクトを開いて環境構築

##### １.⓪の`prettier`の下りはスキップしてOK
##### ２.Node.jsのインストール

以下のリンクから `Node.js` をインストールしてください

[Node.js のインストールリンクはこちら](https://nodejs.org/ja/download/)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/5aefd415-1806-116f-04a5-03ab23540ae0.png" width="500px">

※ `Node.js`のバージョンが進んでいる可能性がありますが、後ろに`(LTS)`と書いてあるものであれば問題ないです◎（`Current`はダメ）

| PC の種類                 | セレクト                                                                       |
| ------------------------- | ------------------------------------------------------------------------------ |
| Windows の方              | I want the `[v20.13.1(LTS)]`version of Node.js for `[Windows]` running `[x64]` |
| Mac の方                  | I want the `[v20.13.1(LTS)]`version of Node.js for `[Mac]` running `[ARM64]`   |
| Mac の方（IntelCPU 搭載） | I want the `[v20.13.1(LTS)]`version of Node.js for `[Mac]` running `[x64]`     |

##### ３.Node.js の動作確認

バージョンが表示されればインストールが成功しています（バージョンが表示されない場合には、PC を再起動してください）

```zsh
node -v
```

##### ４.Dependencies のインストール

プロジェクトに必要な Dependencies をインストールしてください
※ Dependenciesとは、このプロジェクトを動作させるために必要なプログラム群のこと

```zsh
npm install
```

##### 5 .envの設定

以下のコマンドを実行し、作成された`.env`ファイルの中身を書き換えてください
（講習の中では`.env`ファイルの中身は配布します）

```env
cp .env.template .env
```

##### [ envとは ]
`envroiment`の略で、環境変数と呼ばれる非公開や可変にすべき文字列を入れておく場所です。
今回は`Supabase`のapiKeyとURlを格納しています。
講義外でこの手順を再現する場合には、`Supabase`のプロジェクト画面左下の`project-setting→API`から2つを回収できます。

:::note alert
`.env`ファイルや、その中身は絶対に公開してはいけません
Githubなどにアップロードしてしまった場合には、有識者に助けを求めて下さい
:::


##### 6.開発用サーバーの起動

開発用サーバの起動（<a src="http://localhost:3000">http://localhost:3000</a> で画面が確認できる様になります）

```zsh
npm run dev
```

この画面が表示されればOK
※もし画面が真っ白な場合には`.env`ファイルがうまく作成できていない可能性があります

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/f66e5607-923b-112c-e88c-0205177ebd18.png" />

:::note info
これで手元で様々なReactのプロジェクトが動かせるようになりました！
:::

## ③ プロジェクト作成

既存のプロジェクトをクローンして手元で動かすことはできるようになりました。
次は`Vite`というツールを使って自分でプロジェクトを作ってみましょう！

### 1.ツールのインストール
本来は不要ですが、操作ミスを防止するために先にインストールします。
```
npm i -g vite
```

### 2.VSCodeでフォルダを開く
`VSCode`を開いて、左上のバーから`ファイル→フォルダを開く`で`デスクトップ`を開いて下さい。
合わせてターミナルも新しく開いておいて下さい。

:::note warn
既にVSCodeを開いてる場合には必ず一度閉じてから行なって下さい
:::

### 3.ターミナルでプロジェクト作成

`VSCode`のターミナルで以下のコマンドを実行します
```zsh
npx create-vite
```

以下が表示されるのでそのままエンター
```zsh
> ? Project name: › vite-project
```

以下が表示されるので、矢印キーで`React`を選択してエンター

```zsh
? Select a framework: › - Use arrow-keys. Return to submit.
    Vanilla
    Vue
>   React
    Preact
    Lit
    Svelte
    Solid
    Qwik
    Others
```

以下が表示されるので、`TypeScript + SWC`を矢印キーで選択してエンター
```zsh
? Select a variant: › - Use arrow-keys. Return to submit.
    TypeScript
>   TypeScript + SWC
    JavaScript
    JavaScript + SWC
    Remix ↗
```

### 4.プロジェクトを開く

`VSCode`を一度閉じた上でもう一度開き、左上のバーから`ファイル→フォルダを開く`でデスクトップにある`vite-project`を選択して開く。
合わせてターミナルも開いておいて下さい。

:::note warn
VSCodeを必ず一度閉じてから作業をして下さい
:::

### 5.プロジェジェクトの実行

以下のコマンドをそれぞれ実行し、インストールと開発サーバの起動をします
```
npm i
npm run dev
```

開発用サーバの起動（<a src="http://localhost:3000">http://localhost:3000</a> で以下の画面が確認できる様になればOK）

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/8ee32178-0198-386d-3b91-269130ff1448.png" />

### 6.ファイルを編集

この後`Hosting`を行なってサイトを公開しますが、全員一緒のサイトなんておもんないぜ！！
ってことで、ファイルをちょっとだけ編集してみます。

VSCode左のバーから、`src`の下にある`App.tsx`を開く

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/cd45cc14-ed8a-5f43-a6a8-c69caeb4d8e6.png" />

`App.tsx`の`19行目周辺`にある`Hello Vite + React!`という文字を任意の文字に書き換え、保存します

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/0a0180db-917e-5fb6-df13-c05687fd4f6c.png" />

これを、こう

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/9f1661e2-4798-7ce9-a58d-8cf88993a465.png" />

:::note warn
ファイルの保存を忘れないで下さい！！
- windows→`ctrl`+`s`
- mac→`command`+`s`
:::

### 7.完成

中央の文字列が書き換わっていれば成功です！

<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/0f13c47e-7892-9350-ac1d-acec4ef0361e.png" />

:::note info
自分で作ったプロジェクトを編集することができました！
:::


## ④ 初Hosting

### [ `Hosting`とは ]
Webサイトにおける`Hosting`とは、サービスを実際にサーバーに載せて、一般からアクセス可能な状態にすること→こういうこと（https://hack-kansai-2024-web-tutorial.web.app/ranking）
サーバにアップロードする事を`デプロイする`という

◎実際にサービスとして触る事ができる状態になっているというのが、ハッカソン的にポイントが高い

### 🔥Firebase Hosting
ホスティングサービスは沢山あるが、今回は`Firebase`という`BaaS（Supabaseと一緒）`を使う
※`Supabase`にはホスティング機能が無いので別の`BaaS`を組み合わせて使います🥲）

`Firebase`はGoogleが提供している`BaaS`で、同社の`Google Cloud Platform`をラップして作られている。
`Supabase`と同様に`CLIツール`が優秀で、初心者でも分かりやすい。

https://firebase.google.com/?hl=ja

#### ⓪ firebaseにアクセス
[firebase（https://firebase.google.com/?hl=ja）](https://firebase.google.com/?hl=ja)にアクセスし、中央の`使ってみる`からアクセス

<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/0b6e7741-cdc5-9566-b45c-d88992dc897e.png" />

#### ① プロジェクト作成

`プロジェクトを作成`から新規プロジェクトを作成

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/49d244bc-2d7f-6992-fcb3-c4db015d80b1.png" />

プロジェクト名を聞かれるので`vite-project`と入力し、`続行`

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/8ee72c7b-f882-3e81-2f0f-2022512a061d.png" />

アナリティクスのオンオフを聞かれるのでスイッチを`オフ`にして、`プロジェクトを作成`

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/9ba70b28-0765-ecb1-3351-017ab809282f.png" />

この画面になればOK！`続行`を押して次へ

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/afca66b6-73ef-4162-07fd-1f4d8585de61.png" />

#### ②アプリ作成
プロジェクトのトップにWebのスタートボタンがあるので、そこから設定を開始

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/f6ab08f6-a007-57d8-f35e-110462fb1954.png" />

アプリのニックネームに`vite-project`を入力し
`このアプリの Firebase Hosting も設定します`というチェックボックスがあるのでチェック、`アプリを登録`で進む

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/fc4018bd-257f-5d72-5ddf-76a5e98df14e.png" />

:::note warn
ここまできたら`VSCode`のターミナルが`vite-project`で開かれている事を確認して下さい
:::

記載されている以下のコマンドをコピーして、`VSCode`のターミナルに貼り付け実行

```zsh
npm install firebase 
```

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/d711b053-a9a1-3ba3-7ba2-d1e8c78ac2b5.png" />

:::note alert
以下のコマンドをそのまま実行しないで下さい
:::

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/b60a7962-e2aa-4e9e-523e-7254f354eb24.png" />


**[ Macの方 ]**
`VSCode`のターミナルで以下のコマンドを実行して下さい

```
sudo npm install -g firebase-tools
```

以下の表記でパスワードを求められますが、普段使っているMacのパスワード入力して下さい
※ 入力しても表示されませんが正常です、エンターで確定できます

```
Password:
```

**[ Windowsの方 ]**
`VSCode`ではなく、別のアプリとして`PowerShell`というアプリを探します。
実行時に`右クリック→管理者として実行`をして開いたのちに、以下のコマンドを実行して下さい。

```
npm install -g firebase-tools
```
:::note warn
実行後にPowerShellは必ず閉じて下さい。
VSCodeのターミナルは必ず開き直して下さい。
:::

:::note alert
以下のコマンドをそのまま実行しないで下さい
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/2c7f34e4-7551-dea2-328d-5d8c5968ec21.png)

以下のコマンドを実行して下さい。
ブラウザが開かれ、Googleアカウントでのログインを求められるので、`Firebase`にログインしたのと同じアカウントでログインして下さい

```zsh
firebase login
```

次に以下のコマンドを実行して下さい

```zsh
firebase init hosting
```

こんな派手な画面が現れます

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/ca1877f0-c580-cd99-5338-6580ecf0af4b.png" />

矢印キーで移動して、`Use an existing project（既にあるプロジェクト）`を選択してエンター。

```zsh
? Please select an option: (Use arrow keys)
> Use an existing project 
  Create a new project 
  Add Firebase to an existing Google Cloud Platform project 
  Don't set up a default project 
```

どのプロジェクトを使うか聞かれるので、先ほど作成してた`vite-project`を矢印キーで選択して、エンター。

```zsh
? Select a default Firebase project for this directory: 
  hack-kansai-2024-web-tutorial (hack-kansai-2024-web-tutorial) 
> vite-project-48e2c (vite-project) 
  javascriptstudymeeting (JavaScriptStudyMeeting) 
```

優秀な`Firebase`は「もしかして`Vite`使ってる？」って聞いてくるのでそのままエンター。

```zsh
? Detected an existing Vite codebase in the current directory, should we use this? Yes
```

リージョン（サーバを置く場所）を聞いてくるので、`asia-east1 (Taiwan)`を矢印キーで選択してエンター。

```zsh
? In which region would you like to host server-side content, if applicable? 
  us-central1 (Iowa) 
  us-east1 (South Carolina) 
  us-west1 (Oregon) 
> asia-east1 (Taiwan) 
  europe-west1 (Belgium) 
```

自動デプロイの有効化について聞いてきますが、今回は使わないため、`n`と入力してエンター。
```zsh
? Set up automatic builds and deploys with GitHub? (y/N) : n
```

以下のように出れば成功です！

```
✔  Firebase initialization complete!
```

:::note warn
以下のコマンドが設定中に表示されている場合には、どこかで選択ミスをしている or 作業ディレクトリが間違っているため、再度やり直して下さい
`Configure as a single-page app (rewrite all urls to /index.html)?(y/N)`
:::

#### ④ いざデプロイ

以下のコマンドを`VSCode`のターミナルで実行してサイトをデプロイしましょう！

```
firebase deploy
```

以下のような表記になっていれば成功です！！
いちばん下の`Hosting URL: ◯◯◯◯◯◯◯.web.app`というところからサイトにアクセスできます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/36d846e3-6559-1a2e-6d19-4ba615dd1fb2.png)

正しくサイトが表示されていれば完成です。

<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740071/a63d8888-80d5-9fd3-f613-88f458de10e5.png" />

:::note info
これで講座の内容が全て完了しました🎉
:::

# 最後に

今回は

- Webサービスはモバイルアプリと何が違うのか
- Webサービスはどんな構造で動いているのか（実際のサービスを見ながら）
- フロントエンド・バックエンドについて
- 自分でプロジェクトを作り公開

まで幅広く取り扱いました。
今日の作業が全てできるようになれば、自分で`React/TS`のサービスを作り、公開することが可能になっています🔥

- VSCodeの拡張機能など
- React及びJavaScriptの話
- Supabase及びDBの話

など、重要な部分をかっ飛ばして進めてきたので、実際にサービスを作るにあたっては困る部分も多いかもしれませんが、この4時間が皆さんのWebエンジニアとしてのスタートになっていれば大変嬉しいです。

### Happy Web Developer life ！！！

<br>

ぜひTwitterフォローして下さい！！

https://x.com/yuma_satake22