Windows 10 + Node.js + VSCode で React の開発環境を準備する

## はじめに

Javascript というかフロントエンドが苦手なので、UIフレームワークのひとつである React を触りながら、少しずつ仲良くなっていこうと思います。

まずは環境の準備から始めてみます。最終的には以前開発したホロジュールアプリのリニューアル版の開発に繋げていきたいです。

## 利用する環境

下記構成の環境を利用しました。

* Windows 10 Pro 21H1
* Visual Studio Code 1.59.0
* PowerShell 7.1
* Git for Windows 2.32.0.windows.2

## Reactとは

[React](https://ja.reactjs.org/) は、フロントエンドのユーザーインターフェイスを構築するためのオープンソースの JavaScript ライブラリ

完全なアプリケーションフレームワークを提供する他の JavaScript ライブラリとは異なり、React は、状態を維持し、UI 要素を生成する **コンポーネント** と呼ばれるカプセル化されたユニットを使用してアプリケーションビューを作成することだけに重点を置いている。

そのため、複雑なアプリケーションを開発する場合は、状態管理・ルーティング・APIとのやりとりを行う追加のライブラリなどが必要となる。

### 宣言的な View

* アプリケーションの各状態に対応するシンプルな View を設計するだけで、React はデータの変更を検知し、関連するコンポーネントだけを効率的に更新して描画することができる。

* JavaScript 内に HTML タグを注入するような JSX (JavaScript XML) 記法により、描画結果がイメージしやすく、このような宣言的な View を用いることで、コードの見通しも良くなり、デバッグしやすくなる。

### コンポーネントベース

* 自身の状態を管理するカプセル化されたコンポーネントを作成し、これらを組み合わせることで複雑なユーザインターフェイスを構築できる。

* React コンポーネントは、コンポーネントの UI を表す JSX を返却する **render** メソッドを実装し、返却された JSX コードがブラウザーに準拠している HTML に変換される。

* コンポーネントのロジックは、Template ではなく JavaScript そのもので記述するため、様々なデータをアプリケーション内で簡単に取り回すことができ、かつ DOM に状態を持たせないようにすることができる。

## Node.js とバージョンマネージャー

React に必要なファイルをプロジェクトとして管理して開発を行うために、Node.js をインストールします。

[Node.js](https://nodejs.org/ja/) は JavaScript でサーバープログラムの開発を行う際に多用されている、JavaScriptの開発環境です。

Node.js のバージョンアップは非常に早いため、利用するバージョンを適宜切り替えることができる、バージョンマネージャーを利用してみます。

バージョンマネージャーを利用することで、対象となるプロジェクトの環境や要件にあわせて、複数の Node.js のバージョンを切り替えることができます。

一般的には nvm が利用されますが、Windows はサポートされていないため、代わりに、nvm-windows をインストールし、それを使用して Node.js と Node Package Manager (npm) をインストールします。

* これまでは、Node.js のバージョンマネージャーとして nodist を利用していましたが、更新が止まっているようで Node.js のアップデートに失敗したり、npx コマンドが利用できなかったりしたため、今回は nvm-windows を利用してみます。

* Node.js のバージョンマネージャーを利用せずに コンテナ環境を利用するべきという意見もありますが、コンテナ環境を構築できない事情があるため、バージョンマネージャーを利用します。

* すでに Node.js や Nodist などの他のバージョンマネージャーを利用している場合はアンインストールして環境変数なども綺麗にしておきましょう。

### nvm-windows のインストール

1. [nvm-windows](https://github.com/coreybutler/nvm-windows) のリポジトリを開き、[Download Now](https://github.com/coreybutler/nvm-windows/releases) をクリックします。

1. 最新リリースの **nvm-setup.zip** をダウンロードします。

1. ダウンロードが完了したら、ZIP ファイルを開いて、**nvm-setup.exe** ファイルを実行します。

1. Setup - NVM for Windows の指示に従って、セットアップを行います。
![img01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283306/d6924d4e-52f3-4f04-6aa4-6a34d0dde1ed.jpeg)
![img02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283306/819f964c-362b-6ac6-7af5-437029f0091f.jpeg)
![img03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283306/eb534cfb-99bf-32b7-6920-1ea1baef939a.jpeg)
![img04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283306/b6240ed7-7fa8-4c23-1b96-c5f361cc8462.jpeg)
![img05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283306/5ef5712f-5258-6e1c-18bd-8e905e186dfd.jpeg)

1. インストールが完了したら、PowerShell を開き、windows-nvm を使用して、現在インストールされている Node.js のバージョンを一覧表示します。

    ```powershell
    > nvm ls
    No installations recognized (何もインストールされていない)
    ```

1. 下記コマンドを実行して、Node.js の最新の LTS バージョンを確認します。（最新版は問題が発生する可能性があるため、最新のLTS = long-term support を対象とします。）

    ```powershell
    > nvm list available
    |   CURRENT    |     LTS      |  OLD STABLE  | OLD UNSTABLE |
    |--------------|--------------|--------------|--------------|
    |    16.6.2    |   14.17.5    |   0.12.18    |   0.11.16    |
    |    16.6.1    |   14.17.4    |   0.12.17    |   0.11.15    |
    |    16.6.0    |   14.17.3    |   0.12.16    |   0.11.14    |
    |    16.5.0    |   14.17.2    |   0.12.15    |   0.11.13    |
    |    16.4.2    |   14.17.1    |   0.12.14    |   0.11.12    |
    |    16.4.1    |   14.17.0    |   0.12.13    |   0.11.11    |
    ...
    ```

1. 参考）Node.js の最新版をインストールする場合は下記コマンドです。

    ```powershell
    > nvm install latest
    ```

1. 下記コマンドを実行して、Node.js の最新の LTS バージョンをインストールします。

    ```powershell
    > nvm install 14.17.5
    ```

1. インストールされている Node.js を確認します。

    ```powershell
    > nvm ls
    ```

1. 下記コマンドを実行して、利用するバージョンを選択します。

    ```powershell
    > nvm use 14.17.5
    ```

    nvm use コマンドを実行した際に下記のような文字化けしたエラーメッセージが表示された場合

    ```powershell
    > nvm use 14.17.5
    exit status 1: ���̑��������s���邽�߂̏\���ȓ����������܂����B
    ```

    PowerShell を管理者モードで起動して実行すると成功する。

    ```powershell
    > nvm use 14.17.5
    Now using node v14.17.5 (64-bit)
    ```

    nvm をインストールしたフォルダパスに空白が含まれているとエラーが発生する場合があるので注意すること。

1. 現在の Node.js と npm のバージョンを確認します。

    ```powershell
    > node --version
    v14.17.5
    > npm --version
    6.14.14
    ```

## Create React App を利用したプロジェクトの作成と実行

Node.js に含まれる npx というコマンドを用いて「Create React App」というプログラムを実行することで、React 開発のプロジェクトを作成することができます。

```powershell
> cd D:\Develop\Git
> npx create-react-app react_sample
```

しばらく待つと、指定したプロジェクト名のフォルダにプロジェクトが作成されます。

```powershell
> cd .\react_sample\
> ls

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2021/08/13    15:50                node_modules
d----          2021/08/13    15:49                public
d----          2021/08/13    15:49                src
-a---          1985/10/26    17:15            310 .gitignore
-a---          2021/08/13    15:50         688917 package-lock.json
-a---          2021/08/13    15:50            815 package.json
-a---          1985/10/26    17:15           3369 README.md
```

* node_modules フォルダ
  * npm で管理されるモジュールたち
* public フォルダ
  * 公開フォルダ（html や css などを配置）
* src フォルダ
  * React で作成したファイルなど
* .gitignore
  * Git の管理に含めないファイルを指定
* package-lock.json
  * アプリケーションが依存する npm モジュールのバージョンを記載
* package.json
  * アプリケーションが依存する npm モジュールを記載

プロジェクトを操作するコマンドとしてこれらを利用できます。

* npm start
  * 開発用のサーバープログラムを利用してプログラムを実行します。
* npm run build
  * プロジェクトをビルドします。
* npm test
  * テストプログラムを実行します。
* npm run eject
  * プロジェクトの依存関係をプロジェクト内に移動します。

下記コマンドを実行することで、作成したプロジェクトを起動します。

```powershell
> npm start
```

```powershell
> react_sample@0.1.0 start D:\Develop\Git\react_sample
> react-scripts start

i ｢wds｣: Project is running at http://192.168.1.22/
i ｢wds｣: webpack output is served from
i ｢wds｣: Content not from webpack is served from D:\Develop\Git\react_sample\public
i ｢wds｣: 404s will fallback to /
Starting the development server...
Compiled successfully!

You can now view react_sample in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.1.22:3000

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

Windows でファイアウォールのブロック確認が表示された場合はアクセスを許可します。

ブラウザが起動し、作成したプロジェクトの実行結果が表示されます。
Ctrl + C で実行を停止します。

### Visual Studio Code の Node 拡張機能をインストール

eslint や Intellisense や IntelliCode を有効化するための拡張機能をインスト―ルしておきます。

1. Visual Studio Code を起動し、拡張機能ウィンドウを開きます。(Ctrl + Shift + X)

1. 拡張機能 ウィンドウの上部にある検索ボックスに「Node Extension Pack」と入力します。

1. 「Node Extension Pack」の[インストール]をクリックしてインストールします。

1. インストールが完了すると、拡張機能ウィンドウの[有効]フォルダーに表示されます。

### Chrome の React Developer Tools をインストール

React のデバッグツールをブラウザの拡張機能としてインストールしておきます。

1. [Chrome ウェブストア](https://chrome.google.com/webstore/)に移動します。

1. [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) を検索します。

1. React Developer Tools を Chrome に追加します。

1. React アプリケーションの実行中、Chrome のデベロッパーツールを起動（F12キー）し、Components でコンポーネントの構造確認や、Profiler でプロファイリングについて確認することができます。

## 少しだけ React を利用してみる

HTML ファイルを作成して下記コードを記述し、ブラウザから参照して JSX で記述した内容が描画されることを確認します。
Visual Studio Code でコードを記述した場合は、F5 キーを押下することでブラウザでデバッグ実行できます。

```html
<!DOCTYPE html>
<html>
<head>
    <!-- 文字コード（UTF-8）の指定 -->
    <meta charset="UTF-8" />
    <!-- タイトルの指定 -->
    <title>React Sample</title>
    <!-- スタイルシート（bootstrap）を参照 -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" crossorigin="anonymous">
    <!-- React 本体のスクリプト読み込み -->
    <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <!-- React の仮想DOMのスクリプト読み込み -->
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <!-- babel の読み込み（JSXタグをJavaScriptコードに変換） -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
    <h1 class="bg-primary text-white display-4">React Sample</h1>
    <div class="container mt-3">
        <!-- ここに React（下記JSX）を描画 -->
        <div id="root">wait...</div>
    </div>
    <script type="text/babel">
    // React の表示を組み込むタグの Element オブジェクトを取得 -->
    let dom = document.querySelector('#root');

    // JSX に値を埋め込む変数
    let title = "React page.";
    let message = "This is React sample.";
    let flag1 = true;
    let flag2 = false;
    let data = [
        {name:'太郎', mail:'taro@example.com', age:20},
        {name:'次郎', mail:'jiro@example.com', age:23},
        {name:'三郎', mail:'saburo@example.com', age:21},
        {name:'四郎', mail:'shiro@example.com', age:26},
        {name:'五郎', mail:'goro@example.com', age:24}
    ]

    // JSX に値を埋め込む関数
    let printMsg = function(msg, size, color) {
        const style = {
            fontSize: size + "pt",
            fontWeight: '700',
            color: color,
            border: "1px solid " + color
        }
        return <p style={style}>{msg}</p>
    }

    // リストを生成する関数
    let funcList = function() {
        const items = data.map((value, index) => (
            // key を設定する必要あり
            <li key={index} className="list-group-item"><a href={'mailto:'+value.mail}>{value.name}({value.age})</a></li>
        ))
        return(<ul className="list-group mt-4">{items}</ul>);
    }

    // JSX（タグをテキストではなく値として記述していることに注意）
    // ※ ルートエレメントは１つだけ
    // ※ class は JavaScript の予約語であるため className とする
    let el = (
        <div>
            {/* 関数 */}
            {(()=>
                <div>
                    <h4>{title}</h4>
                    <h6>{message}</h6>
                </div>
            )()}
            {/* 条件分岐と関数呼び出し */}
            {flag1 && 
                <div className="alert alert-secondary mt-3">
                {printMsg('条件分岐：真', 24, '#333')}
                </div>
            }
            {/* 三項演算子 */}
            {flag2 ? 
                <div className="alert alert-secondary mt-3">
                {printMsg('三項演算子：真', 24, '#333')}
                </div>
            :
                <div className="alert alert-secondary mt-3">
                {printMsg('三項演算子：偽', 24, '#333')}
                </div>
            }
            {/* リスト表示（map） */}
            {funcList()}
        </div>
    )
    // JSX → 仮想 Element を、指定した Element オブジェクトに描画
    ReactDOM.render(el, dom)
    </script>
</body>
</html>
```

これらの環境を利用して引き続き学習を進めていきます。

## 参考資料

予想外にマイクロソフトの情報が役に立ちました。最近はこのような情報も増えてきて助かります。

* [React の概要](https://docs.microsoft.com/ja-jp/windows/dev-environment/javascript/react-overview)

* [NodeJS とは何か](https://docs.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-overview)

* [Windows での NodeJS のインストール](https://docs.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-windows)

MDN Web Docs

* [JavaScript 「再」入門](https://developer.mozilla.org/ja/docs/Web/JavaScript/A_re-introduction_to_JavaScript)

* [JavaScript オブジェクトの基本](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Basics)

* [初心者のためのオブジェクト指向 JavaScript](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Object-oriented_JS)

* [Object のプロトタイプ](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Object_prototypes)

* [JavaScript での継承](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Inheritance)

その他（書籍など）

* [JavaScript Primer](https://jsprimer.net/)

* [改訂新版JavaScript本格入門 ～モダンスタイルによる基礎から現場での応用まで](https://gihyo.jp/book/2016/978-4-7741-8411-1)

* [React.js&Next.js超入門 第2版](https://www.shuwasystem.co.jp/book/9784798063980.html)