React入門1.5: 環境構築 [ローカル版-番外編]

# はじめに
私自身の復習兼、備忘録的な意味もあり、複数回の記事に渡って React に関する記事をまとめていきたいと思います。

# 本記事の目的
今回は番外編として、ローカル環境での React アプリ開発の環境構築をしていきます。

## シリーズの一覧
1. [React入門１: 環境構築 [オンライン版]](https://qiita.com/banana_bancho/items/64fa6ccb58101eadbb63)
   - React入門1.5: 環境構築 [ローカル版-番外編] (今回)
1. [React入門２: 盤面の作成](https://qiita.com/banana_bancho/private/c50495b5d4c30555cec3)
1. [React入門３: インタラクションの実装](https://qiita.com/banana_bancho/private/557d14b2413cb0317ce4)
1. [React入門４: リファクタリング [リフトアップ編]](https://qiita.com/banana_bancho/private/81730326c004e52c6aad)
1. [React入門５: リファクタリング [インタラクション編]](https://qiita.com/banana_bancho/private/3f20d23aadb49fe233f8)
1. [React入門６: 手番の実装](https://qiita.com/banana_bancho/private/6bed838f67e575f58b72)
1. [React入門７: ゲームの勝利判定](https://qiita.com/banana_bancho/private/c0eca4e9348edb430561)
1. [React入門８: テキストの実装](https://qiita.com/banana_bancho/private/b841b1ce38482b31753c)
1. [React入門９: タイムトラベル(1)](https://qiita.com/banana_bancho/private/c674872e32fcb52bb2a0)
1. [React入門10: タイムトラベル(2)](https://qiita.com/banana_bancho/private/861398f1fa4efd378938)
1. [React入門11: タイムトラベル(3)](https://qiita.com/banana_bancho/private/0d3cf7e1b1ebbf20c5e0)

# 環境構築
- オンラインエディタ CodeSandbox を使った方法はコチラから

https://qiita.com/banana_bancho/items/64fa6ccb58101eadbb63

今回は、ローカル環境で React のプロジェクトを作成する方法として、次の2つを記します。

- 方法A: 手動
    ファイルの作成とコマンド操作によって、プロジェクトを自力で作成していきます。
- 方法B: 自動
    1つのコマンドを実行することで、公式が提供するプロジェクトのひな型を作成します。

## 特徴
方法Aでは、ファイルの作成やコマンドの操作など複数の手順を自力で行うため、少し手間がかかります。といっても、目次から確認できるように工数はそんなに多くありません。この方法では、最小限のファイル数でプロジェクトを構成することが可能です。

一方で、方法Bでは、1つのコマンドのみでプロジェクトのディレクトリを作成することができます。そのため、簡単に開発環境を構築することができます。また、公式が提供しているというのも利点です。短所として、不要なファイルも作成されるため、プロジェクトの整理に手間がかかります。

## どっちがよいのか
個人的には、まずは方法AでReactにおけるプロジェクトの構成を学びながら開発し、ある程度慣れたら方法Bに移行するのが良いと思います。

## 方法A
プロジェクトを保管したいディレクトリに移動してから次の手順を踏んでください。説明の便宜上、ここでは ```sample_a``` というフォルダ内での作業例を示していきます。

### 設定ファイルの作成
ターミナルにて、次のコマンドで package.json を作成します。エクスプローラーの操作でテキストファイルを作成しても構いません。
```
npm init -y
```

package.json はプロジェクトの設定と依存関係の一覧を管理するためのファイルです。このファイルに基づいて、パッケージのインストールが行われます。

現在のディレクトリ構成は次のようになっています。新規作成したものを ```(new)``` と示しておきます。
```
sample_a               # プロジェクト全体の管理フォルダ
- package.json         # (new) 設定ファイル
```

### 設定ファイルの編集
お好みのエディタで package.json を次の内容に変更しましょう。
``` json: package.json
{
  "name": "react-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
    },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "^5.0.1"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
```

### Reactに関するパッケージの導入
インストールするパッケージを次に示します。
|パッケージ|機能|
|---|---|
|```react```| React ライブラリのエントリポイント|
|```react-dom```| Reactにおける仮想DOMの提供|
|```react-scripts```| webpackとbabelの内部的動作|

これらのパッケージを次のコマンドでインストールしていきます。少し時間がかかるので、その間に次の手順へ進みましょう。
```
npm install react react-dom react-scripts
```

新しく追加されたフォルダとファイルについて説明していきます。
-  node_modules フォルダ
プロジェクトにおいて依存関係のパッケージがインストールされる場所です。このフォルダには、プロジェクトが依存する外部のパッケージやモジュールが格納され、プロジェクトの実行やビルドに必要なコードやリソースが含まれています。通常、このフォルダは手動で管理する必要はなく、package.json および package-lock.json ファイルに基づいて、自動的にパッケージがインストールされます。
-  package-lock.json ファイル
プロジェクトにおいて依存関係のバージョンを確定するためのものです。具体的には、プロジェクトにインストールされた各パッケージの正確なバージョン、およびその依存関係を保存します。

インストール完了後のディレクトリ構成は次のようになっています。
```
sample_a               # プロジェクト全体の管理フォルダ
- package.json         # 設定ファイル
- package-lock.json    # (new) パッケージの記録ファイル
- node_modules         # (new) パッケージの管理フォルダ(中身は省略)
```

### ファイルの作成
次のように public フォルダと src フォルダを作成してください。各フォルダについては、後に説明します。
```
sample_a               # プロジェクト全体の管理フォルダ
- package.json         # 設定ファイル
- package-lock.json    # パッケージの記録ファイル
- node_modules         # パッケージの管理フォルダ(中身は省略)
- public               # (new) 後述
- src                  # (new) 後述
```

#### public フォルダ
静的なアセット(画像やフォント、外部スクリプトなど)を格納するための場所です。

##### index.html ファイル
public フォルダに、次のような index.html ファイルを作成しましょう。
```html: index.html
<!DOCTYPE html>
<html lang="ja">

  <head>
    <!-- 文書の文字エンコーディングをUTF-8に指定 -->
    <meta charset="UTF-8">
    <!-- ページのタイトルを指定 -->
    <title>React練習</title>
  </head>

  <body>
    <!-- Reactアプリケーションが描画されるルート要素の定義 -->
    <div id="root"></div>
  </body>

</html>
```

```<body>``` 要素下にある ```<div>``` 要素に注目してください。```id``` の値が ```root``` となっていますね。後ほど、この要素をJavaScriptで取得することで、Reactのプログラムを実装していきます。

現在のディレクトリ構成は次のようになっています。
```
sample_a               # プロジェクト全体の管理フォルダ
- package.json         # 設定ファイル
- package-lock.json    # パッケージの記録ファイル
- node_modules         # パッケージの管理フォルダ(中身は省略)
- public               # 静的アセットの管理フォルダ
  - index.html         # (new) Webページの主要コンテンツ
- src                  # 後述
```

#### src フォルダ
Reactアプリケーションのソースコードを格納する場所です。ここに[コンポーネント](#コンポーネント指向)やスタイル、画像などのファイルを保存していきます。

##### index.js ファイル
src フォルダに、次のような index.js ファイルを作成しましょう。このファイルがReactアプリケーションのエントリーポイント(プログラムの実行を開始する場所)となります。
```jsx: index.js
// ReactおよびReactDOMをインポート
import React from 'react';
import ReactDOM from 'react-dom/client';

// Appコンポーネントを'./App'からインポート
import App from './App';

// ルート要素を特定のDOM要素に関連付ける
const root = ReactDOM.createRoot(document.getElementById('root'));

// ルート要素にReactコンポーネントを描画する
root.render(
  // React.StrictModeコンポーネントでアプリケーションをラップする
  <React.StrictMode>
    {/* Appコンポーネントを描画 */}
    <App />
  </React.StrictMode>
);
```

```root.render()``` の引数を見ると、JavaScript と少し異っており、HTML のような書き方をしていることが確認できます。この文法が React 特有の [JSX](#JSXによる直感的なコーディング) と呼ばれる構文となります。

流れとしては、index.html にあった ```<div>``` 要素( ```id = root``` )を取得して、後述にある ```App.js``` の ```App()``` コンポーネントを実装しています。


##### App.js ファイル
src フォルダに、次のような App.js ファイルを作成しましょう。このファイルに、コンポーネント ```App``` を記述していきます。
```jsx: App.js
// Appコンポーネントの定義
function App() {
  return (
    <div className="App">
      <h1>Hello, world!</h1>
    </div>
  );
}

// Appコンポーネントを他のファイルで利用できるようにエクスポート
export default App;
```

こちらにも JSX の構文がコンポーネント ```App()``` の ```retrun``` 文に記されていることを確認できます。

最後にある ```export default App;``` によって、このファイルは ```import``` されると、コンポーネント ```App()``` を返すように設定しています。

以上でプロジェクトの作成は終了です。最終的には、次のようなディレクトリ構成になっています。
```
sample_a               # プロジェクト全体の管理フォルダ
- package.json         # 設定ファイル
- package-lock.json    # パッケージの記録ファイル
- node_modules         # パッケージの管理フォルダ(中身は省略)
- public               # 静的アセットの管理フォルダ
  - index.html         # Webページの主要コンテンツ
- src                  # ソースコード管理フォルダ
  - index.js           # (new) エントリポイント
  - App.js             # (new) コンポーネント
```


## 方法B
まずは、プロジェクトを作成したいディレクトリに移動してください。
ターミナルにて、次のコマンドを実行することで、Reactのプロジェクトを作成してくれます。
```
npx create-react-app プロジェクト名
```

```プロジェクト名``` は任意の文字列で作成が可能ですが、大文字を含めることはできません。ここでは、```sample_b``` とした場合の例を示します。コマンドの処理が終わると、現在いるディレクトリに ```sample_b``` というフォルダが作成されます。このフォルダの内容を次に示します。
```
sample_b               # プロジェクト全体の管理フォルダ
- package.json         # 設定ファイル
- package-lock.json    # パッケージの記録ファイル
- README.md            # 
- .gitignore           # 
- .git                 # 
- node_modules         # パッケージの管理フォルダ(中身は省略)
- public               # 静的アセットの管理フォルダ
  - index.html         # Webページの主要コンテンツ
  - favicon.ico        # 
  - logo192.png        # 
  - logo512.png        # 
  - manifest.json      # 
  - robots.txt         # 
- src                  # ソースコード管理フォルダ
  - index.js           # エントリポイント
  - index.css          # 
  - App.js             # コンポーネント
  - App.css            # 
  - App.test.js        # 
  - reportWebVitals.js # 
  - setupTests.js      # 
```

# 動作確認
方法Aでは ```sample_a``` ディレクトリ、方法Bでは ```sample_b``` ディレクトリでターミナルを開いて次のコマンドを実行しましょう。

```
npm start
```

次のような出力が確認できれば成功です。ブラウザが自動的に立ち上がり、各方法での動作結果が確認できます。
```
Compiled successfully!

You can now view プロジェクト名 in the browser.

  Local:            http:// 省略
  On Your Network:  http:// 省略

Note that the development build is not optimized.
To create a production build, use npm run build.

webpack compiled successfully
```
## 方法A の動作結果
次のように「Hello, world!」と表示されたページが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/82779a8d-001f-7218-e61b-0fdc6252bf54.png)

## 方法B の動作結果
次のように React のマークが時計回りに回転しているページが確認できます。

![output_video.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2844961/6a239939-16e7-6480-fc29-1b5837725a40.gif)

# おわりに
今回は、番外編としてローカル環境での環境構築についてまとめていきました。メインシリーズでは React 公式チュートリアルについてまとめています。よろしければ、[シリーズの一覧](#シリーズの一覧) からご確認ください。