Help us understand the problem. What is going on with this article?

知っていると捗るcreate-react-appの設定

More than 1 year has passed since last update.

はじめに

NTTテクノクロス Advent Calendar 2018の8日目担当 @geek_duck です🦆

最近はReact.jsでフロント側、SpringBoot/GrailsでAPI側を作るプロジェクトに関わっています。

そのプロジェクトの中で調べた、知っていると捗るcreate-react-appの設定を紹介したいと思います。

この投稿で使用している言語、ライブラリのバージョン

  • Node.js v10.14.1
  • npm v6.4.1
  • create-react-app v2.1.1
  • react.js v16.6.3

create-react-app基本の使い方

最初にcreate-react-appの基本的な使い方をサッと紹介します。

create-react-appは、React.jsのアプリのひな形を作成してくれるツールです。

以下のnpxコマンド経由でcreate-react-appを実行するとsampleという名前のReactアプリが出来上がります。

$ npx create-react-app sample
$ cd sample

create-react-appで作成したプロジェクトはbabelやwebpackやESLintの設定が済んでおり、

以下のnpm startコマンドを実行することで開発サーバをlocalhost:3000で起動しつつブラウザで開いてくれます。

$ npm start

本番環境用にJSファイルを1つにまとめたい場合はnpm run buildを実行するとbuildディレクトリにまとめてくれます。

$ npm run build
$ ls build

babelやwebpackやESLintの設定を細かく変更したい場合はnpm run ejectを実行します。

configディレクトリ以下にwebpackの設定ファイルが作成され細かく設定できるようになります。

$ npm run eject
$ ls config

開発中にAPIサーバにリクエストを投げたい

SPAアプリを構築する場合、フロントエンドのReactアプリからバックエンドのAPIサーバを叩きにいくことになります。

ローカルで開発している最中は、APIサーバのURLがSameOriginポリシーに引っかかってそのままではAPIサーバにアクセスできないことが多々あります。

例えばローカルで以下のようなURLでReactアプリとAPIサーバを動かす場合は、ポート部分が異なるためブラウザのSameOriginポリシーに引っかかります。

このような場合、package.jsonにproxyプロパティを追加することでSameOriginポリシーを回避できます。

package.json
  "proxy": "http://localhost:8080",

こうするとhttp://localhost:3000に対するリクエストのうち、Acceptヘッダがtext/html以外のリクエストを全てhttp://localhost:8080にproxyします。

Reactアプリからfetch("/api/auth")を実行した場合、ブラウザはhttp://localhost:3000/api/authにリクエストを投げ、開発サーバがhttp://localhost:8080/api/authにproxyします。

ブラウザから見ればhttp://localhost:3000/apiにアクセスしているように見えるのでSameOriginポリシーに引っかかりません。

もしAPIサーバが複数種類ある場合はproxyプロパティではなく、http-proxy-middlewareを使います。

$ npm i -D http-proxy-middleware

src/setupProxy.jsを作成し、proxyの詳細な設定を書きます。(内部的にはexpressのmiddlewareとして動作します。)

src/setupProxy.js
const proxy = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(proxy("/api/auth", { target: "http://localhost:8080/" }));
  app.use(proxy("/api/users", { target: "http://localhost:8081/" }));
};

上記のように設定することで、Reactアプリからfetch("/api/auth")を実行した場合はhttp://localhost:8080/へ、fetch("/api/users")を実行した場合はhttp://localhost:808/にproxyされます。

注意点としてproxy設定はnpm startの時だけ有効で、npm run buildした後は効きません。

参考
Proxying API Requests in Development

開発環境、本番環境でアプリに渡す環境変数を切り替えたい

開発環境や本番環境それぞれの環境で設定値を切り替えたい場合は、各環境に合わせた.envファイルを用意するのが簡単です。

  • .env : デフォルト

  • .env.local: ローカル環境用(Environmentモードがtestの場合は読み込まれない)

  • .env.development, .env.test, .env.production: それぞれのEnvironmentモードで読み込まれる

  • .env.development.local, .env.test.local, .env.production.local: ローカル環境用

create-react-appはdotenvを利用しており、.envファイルで指定した設定値はReactアプリ内からprocess.env経由でアクセスできます。

.envファイルには、REACT_APP_から始まる変数名=値 の形式で記述します。

.env
REACT_APP_SOME_VALUE=hogehoge

アプリからはprocess.env.REACT_APP_xxxxで値を取得します。

App.js
render() {
  return {
    <div>{process.env.REACT_APP_SOME_VALUE}</div>
  }
}

.envファイルを使わずにnpm startnpm run build実行時の環境変数として指定することも可能です。

$ REACT_APP_SOME_VALUE=hogehoge npm start

例として、あるコンポーネントについて開発環境とステージング環境では表示したいが、本番環境ではまだ表示したくない場合は以下のように実現できます。

App.js
render() {
  // REACT_APP_SHOW_SOME_COMPONENTで表示/非表示をコントロール
  const flag = process.env.REACT_APP_SHOW_SOME_COMPONENT && process.env.REACT_APP_SHOW_SOME_COMPONENT.toLowerCase() === "true";
  return {
    <div>
      {flag && <SomeComponent />}
    </div>
  }
}

環境変数で表示するかどうかを指定してビルドします。

$ REACT_APP_SHOW_SOME_COMPONENT=true npm run build

注意点として、create-react-appはアプリ実行時やビルド時にNODE_ENVを指定できず(ソースコードはこの辺)、

  • npm startを実行した時はdevelopmentモード

  • npm run testを実行した時はtestモード

  • npm run buildを実行した時はproductionモード

と実行方法でEnvironmentモードが固定されてしまいます。

そのためnpm run build時に環境変数NODE_ENV=developmentを指定して.env.developmentを読み込ませる、といったことはできません。

参考
Adding Custom Environment Variables

オートリロード機能をタブごとに無効化したい

別投稿: https://qiita.com/geek_duck/items/fda968e3bf0453082760

おわりに

APIとの連携や、環境変数で設定値を渡す方法はよくやりたくなるので知っておくと捗ると思います💪

明日の担当は @nobeans です。お楽しみに🎉

geek_duck
Hello world.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away