ここまでご紹介してきたサンプルは学習やちょっとした検証には使えるのですが、実際に本番環境で動かすのには向いていません。というわけで今回は本番環境で動かすコードを作成するための開発環境を準備してみたいと思います。
Reactの開発環境
Node.jsのインストール
まず最初にNode.jsを入れる必要があるのですが、アップデートに対応しやすくするためバージョン切り替えが手軽に行えるツールをインストールした上でNode.jsの最新版を入れます。
MacやLinuxならnodebrew
blog.katsubemakito.net
Windowsならnodist
qiita.com
今回は以下のバージョンで構築を開始します。npmはNodejs用のパッケージマネージャーで、これを使って様々な便利ライブラリやツールをインストールすることができます。
$ node --version v11.7.0 $ npm --version 6.5.0
create-react-appのインストール
Reactの開発環境をゼロから作ろうとすると中々に面倒なのですが、コマンド一発で必要な物を一式揃えてくれる便利ツールがfacebookより公式に提供されているので今回はこちらを利用してみます。 github.com
では先ほどインストールしたnpmコマンドを利用してこのcreate-react-app
を入れます。npmを利用するとコマンド一発で入ります。
$ npm install -g create-react-app
今回は以下のバージョンが入りました。
$ create-react-app --version 2.1.3
開発サイクル
プロジェクトの作成
create-react-app
に続きプロジェクト名を入力すると、プロジェクト名のフォルダが作成されその中に必要なファイルがガンガン生成されます。このコマンドの実行は数分かかりますので気長に待ちます。
$ create-react-app hello
隠しファイルになっているのでls -a
コマンドなどを打たないと最初は気が付かないのですが、すでにGitのローカルリポジトリとなっており.gitignore
ファイルも準備されています。気が利きますな!
$ ls -la hello total 1352 drwxr-xr-x 10 katsube staff 320 1 23 01:29 ./ drwx------+ 33 katsube staff 1056 1 23 01:27 ../ drwxr-xr-x 13 katsube staff 416 1 23 01:29 .git/ -rwxr-xr-x 1 katsube staff 310 10 26 1985 .gitignore* -rwxr-xr-x 1 katsube staff 2881 10 26 1985 README.md* drwxr-xr-x 1018 katsube staff 32576 1 23 01:29 node_modules/ -rw-r--r-- 1 katsube staff 676454 1 23 01:29 package-lock.json -rw-r--r-- 1 katsube staff 478 1 23 01:29 package.json drwxr-xr-x 5 katsube staff 160 1 23 01:29 public/ drwxr-xr-x 9 katsube staff 288 1 23 01:29 src/
node_modules
ディレクトリをのぞくと、ReactはもちろんBabelやESLintにWebpackなどが入ったことがわかります。
これでひとまず準備が概ね終わりました。あっという間でしたねw
それぞれのディレクトリやファイルの役割は以下の通り。
- src/
- 開発で利用しているJavaScriptやCSSを置きます。基本的にこの中で開発を行っていきます。
- public/
- JavaScriptなどから直接利用しない画像やHTMLなどを置きます
- node_modules/
- インストールした外部のNode.js用のモジュールが入っています
- package.json, package-lock.json
- プロジェクトの設定ファイル
- README.md
- このプロジェクトの簡単な説明などを記述しておきます。
- .gitignore
- Gitに登録したくないファイルがあればここに記述します。
- .git/
- Gitのリポジトリを管理しているフォルダ。用がない限り触りません。
実行してみる
雛形が作成された際にも表示されているので気が付かれた方も多いと思いますが、現在のプロジェクトの実行はコマンド一発です。カレントディレクトリを移動し、npm start
と打つだけです。
$ cd hello $ npm start
するとビルドが開始され、ローカルで開発用HTTPサーバが起動、最終的にブラウザが起動しHTTPサーバへ自動的にアクセスされます。ビルドからサーバ起動にちょっとだけ時間がかかるので口笛でも吹きながら待ちます。
ここで適当なテキストエディタでsrc/App.js
を開いてみましょう。これまで取り上げてきたコードと冒頭のimport
部分が異なるだけであとはほぼ同じですね。
試しにLearn React
の部分を適当な文字列に変更してみます。ここではLearnをEnjoyに変えました。
import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; class App extends Component { render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Enjoy! React </a> </header> </div> ); } } export default App;
src/App.js
を保存した瞬間に(実際には多少ラグはありますが)、ブラウザの表示が自動的に切り替わります。便利ですね!デュアルディスプレイにしておけば開発が捗るというものです。
注意点としては、Terminalにも表示されている通り、現時点では開発用にプレビューしているだけで、本番用のファイルはまだ出来上がっていません。
Note that the development build is not optimized. To create a production build, use npm run build.
開発用HTTPサーバはいったんCtrl+Cなどで停止しておきます。
テストコードを動かす
Facebook製のテストツールJestがデフォルトだと入っていますので、通常はこいつでユニットテストを行います。
TDDでの開発スタイルを前提として設定がされているらしく、常時バックエンドでJestが動き続けており、src
配下のファイルを更新すると自動でユニットテストが動作するwatch
モードで起動します。Jest用のTerminalウィンドウかタブを新たに開いてそこで動かすのが良さそうですね。自分のタイミングで行うこともできますのでご安心を。
コマンド一発で起動します。
$ npm test
Jestが起動すると以下のような選択を求めてきますので、いずれかのキーを押します。
キー | 動作 |
---|---|
a | ファイルが更新される度にすべてのテストケースを実行 |
f | "失敗"したテストケースのみを実行 |
t | 指定したテストケースのみを実行 |
p | 指定したテストファイルのみを実行 |
q | watchモードを終了する |
Enter | watchモードではなく即時ユニットテストを実行する |
今回は試しにa
キーを押してみます。するとプロジェクト内のファイルからテスト用ファイルが検索され実行されます。今回はsrc/App.test.js
のみが該当しますので、このファイルのテストが実行されます。
ここでsrc/App.js
を更新すると自動的にテストが実行されます。上のTerminalでtouch
コマンドを実行しファイルの更新日を現在の物にすると同時に、下のTerminalでJestが実行されているのがわかります。
https://youtu.be/2028egDCSe0
実際に実行するとわかるのですが、Jestは全部入りの重量級のツールなので起動が非常に遅く、毎回立ち上げるのはかなりストレスです。watchモードで裏側で起動しておくか、commit/pushと同時にJenkinsなどで自動的にテストするのがおすすめです。
本番用のファイルを作成する
では本番用のファイルをビルドしてみましょう。これもコマンド一発です。
$ npm run build
最終的に以下のようにCompiled successfully.
とメッセージが表示されれば成功です。
Creating an optimized production build... Compiled successfully.
プロジェクト内に新たにbuild
というフォルダが生成されているのでのぞいてみます。ここにあるファイルが本番用に最適化されたファイル郡になります。アプリが仕上がった段階でこいつをWebサーバなどにアップして公開することになります。
本番用のファイルをローカルで確認する
とはいえ、いきなり何の確認もなしにアップするのは恐ろしいので、まずは自分自身の環境で動作確認をしたいところなので、簡易的なWebサーバをインストールして動かしてみます。
Node.js製のserve
コマンドをインストールします。今回は10.1.1が入りました。
$ npm install -g serve $ serve --version 10.1.1
このserveコマンドに、先ほどbuildしたファイルがあるフォルダをオプションで渡してやります。
$ serve -s build
最後にTerminalで指定された通りlocalhost:5000
にブラウザからアクセスすれば確認を行うことができます。
確認して問題なければ、Gitでコミットなどを行ったり、サーバにデプロイするなどすることになります。
Gitへpushする
GitHubなどのリモートリポジトリへpushしたい場合、最初の一回だけどこに送信するのかremoteの設定を行う必要があります。
今回はGitHubにhello
とう名前のリポジトリを作成しました。この下の方にあるコマンドを打ってやります。
言わずもがなですが2行目のgit push
した時点で実際にpushされます。
$ git remote add origin git@github.com:katsube/hello.git
$ git push -u origin master
念の為に以下のコマンドで登録状況を確認しておきます。
$ git remote -v origin git@github.com:katsube/hello.git (fetch) origin git@github.com:katsube/hello.git (push)
これ以降は普通にcommit/push/pullなどしてやることができます。
その他
build時に相対パスで出力したい
npm run build
すると通常は絶対パスでCSSやJavaScriptが呼び出されるHTMLが出力されます。これを相対パスに変更したい場合は、package.json
にhomepage
という項目を追加してあげます。
package.json
を適当なエディタで開きどこでも良いので追加します。ここでは一番下に記述しました。
{ "name": "picbook", "version": "0.1.0", "private": true, "dependencies": { "react": "^16.8.6", "react-dom": "^16.8.6", "react-router-dom": "^5.0.0", "react-scripts": "2.1.8" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": [ ">0.2%", "not dead", "not ie <= 11", "not op_mini all" ], "homepage": "./" }
これで、以下のように相対パスにすることができました。
<script src="./static/js/2.9aeef01b.chunk.js"></script>
もちろん./foo/
などとディレクトリも指定すれば以下のようにパスも書き換わってくれます。
<script src="./foo/static/js/2.9aeef01b.chunk.js"></script>
TypeScriptで雛形を作成
プロジェクト名の後ろに--typescript
オプションをつけてあげればTypeScriptで雛形が作成されます。
$ create-react-app hellots --typescript
実行するコマンドはこれまでと同じです。
npm start
でブラウザで確認、npm test
でユニットテスト、npm run build
で本番用のファイルを作成
TypeScriptのオプションを付けない場合は、トランスパイラにBabelが利用されます。お好みのトランスパイラで開発が行えます。
裏側で動いているファイルを出現
create-react-app
で作成した雛形には、必要最小限のファイルしか表には出てきません。初心者に優しくといった心遣いだと思うのですが、ある程度慣れてきたりcreate-react-app
が死んで他のツールに移りたい場合など諸々カスタマイズがしたくなってくると思います。そんなときはコマンド一発で各種ファイルを出現させることができます。
$ npm run eject
途中で確認を求められたらYes
と入力。
? Are you sure you want to eject? This action is permanent. Yes
すると新たにconfig
ディレクトリが作成され、その中に設定ファイルが生成されています。またscripts
ディレクトリにはこれまでnpm
コマンド経由で実行していたスクリプトも出現していますね。
$ ls README.md* config/ package-lock.json public/ src/ build/ node_modules/ package.json scripts/ $ ls config env.js paths.js webpackDevServer.config.js jest/ webpack.config.js
Webpackなどの知識は必要になりますが、万が一の場合はこのコマンドを利用して脱出やカスタマイズを行うことになります。