NERM (Node.js + Express + React + Material-UI) ベースなWebアプリ開発用のシンプルなビルド環境 2019年3月版

Node.js + Express で Web アプリを開発するのはもう一般的だと思いますが、ちょっと凝ったアプリを作成しようとすると、フロントエンドの UI で何を使おうか悩みますね。

個人的には React + Material-UI あたりが使いやすいと思います。(勝手に)名付けて NERM (Node.js + Express + React + Material-UI) 環境！で、この環境用にシンプルなビルド環境を用意してみました。

2017年に投稿した [browserify+babelifyでReactアプリをトランスコンパイルできるシンプルなビルド環境を用意する](https://qiita.com/yamachan360/items/1ad29bf8a64e50801ca9) が進化した2019年版です。Node.js ベースのWebアプリを気軽に作成したい場合に、スケルトンとして使っていただければ、嬉しいです。

# 準備

node と npm は利用できるよう準備しておいてください。私はWindows環境なので [nodist](https://qiita.com/maitake9116/items/d14a50214305aeb2194c) を使っています。

まずは作業用のディレクトリ(フォルダ)を作成します。今回は "rtk-nerm" としました。そして src, public のサブディレクトリを作成しておきます。

# シンプルな React + Material-UI サンプル

今回も非常にシンプルなサンプルを用意しましょう。

src ディレクトリに App.jsx ファイルを用意します。内容は以下をコピペしてください。

```jsx:src/App.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import Button from '@material-ui/core/Button';

function App() {
  return (
    <Button variant="contained" color="primary">
      Hello World
    </Button>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('react-root')
);
```

また public ディレクトリに index.html ファイルを用意します。内容は以下をコピペしてください。

```html:public/index.html
<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
  <title>rtk-nerm</title>
</head>
<body>
  <div id="react-root"></div>
  <script type="text/javascript" src="./App.js"></script>
</body>
</html>
```

サンプルはこれで準備できましたので、いよいよ環境の構築を始めましょう。

# トランスコンパイル環境の構築

作業ディレクトリに package.json ファイルを用意します。内容は以下をコピペしてください。

```json:package.json
{
  "name": "rtk-nerm",
  "version": "1.0.0",
  "description": "Simple transcode environment for NERM (Node.js + Express + React + Material-UI) application.",
  "scripts": {
    "build": "browserify -t [ babelify --presets [ @babel/preset-env @babel/preset-react ] ] src/App.jsx -o public/App.js",
    "start": "node Server.js"
  },
  "engines": { "node": ">= 8" },
  "author": "yamachan / Toshio Yamashita",
  "license": "MIT"
}
```

※ scripts 要素以外は自由に変更してok

そして以下のコマンドで必要なパッケージを導入します。

```
npm install --save express
npm install --save react react-dom @material-ui/core @material-ui/icons
npm install --save-dev browserify babelify
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react
```

ちなみに私は以下のようなバージョンのモジュールが導入されました。

```json:package.json
  "dependencies": {
    "@material-ui/core": "^3.9.2",
    "@material-ui/icons": "^3.0.2",
    "express": "^4.16.4",
    "react": "^16.8.3",
    "react-dom": "^16.8.3"
  },
  "devDependencies": {
    "@babel/core": "^7.3.4",
    "@babel/preset-env": "^7.3.4",
    "@babel/preset-react": "^7.0.0",
    "babelify": "^10.0.0",
    "browserify": "^16.2.3"
  }
```

以下のコマンドを実行して public/App.js ファイルが生成されれば ok です。

```
npm run build
```

# Node.js + Express サーバーを起動

プロジェクトのルートディレクトリに Server.js ファイルを用意し、内容は以下をコピペしてください。

```javascript:Server.js
const express = require("express");
const app = express();

app.use(express.static('public'));

let port = process.env.PORT || 3000;
app.listen(port);
```

以下のコマンドで Server.js コードを実行し、ローカルで Web サーバーを起動します。

```
npm start
```

ブラウザで http://localhost:3000/ にアクセスすれば、Material-UI を使った React ページが表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/e0c1b792-daaa-fa90-5719-a97410f2f7a6.png)

# さあアプリ開発を開始しましょう

Server.js にはバックエンドのロジックを実装しましょう。こちらを更新した時には npm start で起動するWeb サーバーを再起動(終了して再実行)することを忘れずに。

src/App.jsx にはフロントエンドの UI を実装し、npm run build で public/App.js を更新しましょう。

それぞれ拡張し、自分なりの Web アプリケーションを作成してみてください。


# IBM Cloud の Node.js 環境で動かしてみる

ついでにプロジェクトを[IBM Cloud](https://www.ibm.com/cloud-computing/jp/ja/) (Cloud Foundry) の Node.js 環境で動かしてみましょう。

>IBM Cloudアカウントをお持ちでない方は、[こちら](https://console.bluemix.net/registration/free?)からすぐに使える無料アカウント登録をしてください。

プロジェクトのルートディレクトリに .cfignore ファイルを用意し、内容は以下をコピペしてください。このファイルが無くても動作しますが、用意したほうが push 動作が軽くなります。

```:.cfignore
node_modules
src
README.md
.gitignore
```

さあ、IBM Cloud にログインして、アプリを push しましょう。(アプリ名 rtk-nerm はユニークなものに変更する必要があります)

>アプリ名はWebサイトを公開した時のURLの一部になります。IBM Cloudの場合、https://<アプリ名>.mybluemix.netとなります。

```
cf login
cf push -m 128M rtk-nerm
```

【追記】package.json に start コマンドを記載したので -c "node Server.js" オプションは不要になりました

[IBM Cloud ダッシュボード](https://cloud.ibm.com/)でアプリの開始を確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/3034a7de-3bfe-bad8-62c7-6bc6b5c39274.png)
「アプリURLにアクセス」リンクから、実際の表示を確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/15138518-22d6-2c8b-f48c-22dd64b684e7.png)

# 関連ファイルのダウンロード

[rtk-nerm](https://github.com/yamachan/rtk-nerm) というGitHubリポジトリに今回のファイルを置いておきましたので、面倒な方はそちらからダウンロード/clone してお使いください。

具体的にダウンロードしてセットアップする [記事](https://qiita.com/yamachan360/items/d5c4fb2e07d3b9693c37) も公開しましたので、そちらも参考にしてみてください。 

# Enjoy!

Node.js でロジックを実装し、Express + React + Material-UI ベースで開発したWebアプリをビルドするための、できるだけシンプルな環境を構築してみました。これを出発点として自分なりのアプリやビルド環境を構築する助けになれば嬉しいです。

ではまた！