LoginSignup
39
26

More than 5 years have passed since last update.

Reactにおける環境変数を設定について、ようやく理解したので原因と共にまとめてみる_100DaysOfCodeチャレンジ38日目(Day_38:#100DaysOfCode)

Posted at

はじめに

これまでRailsでdotenvを使っていたので、同じ感覚で使えるだろと思い、今回の個人開発Reactでも採用することに。

ところが、どうも設定がうまくいかず、一時期ずっと悩んでいました。

つい最近、ようやく問題が解決したので、原因となっていた問題と共にアウトプットとして記事に残します。

また、この記事はTwitterで人気のハッシュタグ#100DaysOfCodeをつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した38日目の記録です。

動作環境

  • react-scripts: 1.1.4

前提条件

create-react-appでReactプロジェクトを立ち上げていること

今までの設定方法

下記のdotenv公式サイトを参考に、READMEにならってプロジェクト直下に.envを作成しました。

当時のdotenvのファイル内容はこんな感じ。

YOUTUBE_API_KEY=hogehogehugahuga485732

で、dotenvで設定したファイルを次のようにコンポーネントで読み込んでました。

ここでは、youtube-api-searchのAPIキーをdotenvで管理しようとしていました。

import React, { Component } from "react";
import YTSearch from "youtube-api-search";
import dotenv from "dotenv";

const API_KEY = dotenv.config(process.env.YOUTUBE_API_KEY);
console.log(API_KEY);

YTSearch({ key: API_KEY, term: "水族館" }, function(data) {
  console.log(data);
});

結果、コンソールで次のようなエラーが発生していました。

{error: TypeError: fs.readFileSync is not a function
    at Object.config (http://localhost:3000/static/js/b…}
xhr.js:115 GET https://www.googleapis.com/youtube/v3/search?part=snippet&key=%7B%22error%22:%7B%7D%7D&q=%E6%B0%B4%E6%97%8F%E9%A4%A8&type=video 400 ()
xhrAdapter @ xhr.js:115
(anonymous) @ dispatchRequest.js:15
dispatchRequest @ dispatchRequest.js:11
Promise.then (async)
../node_modules/axios/lib/axios.js.module.exports @ axios.js:40
axios.(anonymous function) @ axios.js:66
../node_modules/youtube-api-search/index.js.module.exports @ index.js:17
./src/components/Youtube/youtube_search_bar.js @ youtube_search_bar.js:9
__webpack_require__ @ bootstrap cce4570accfe85501067:678
fn @ bootstrap cce4570accfe85501067:88
./src/App.js @ App.css?9a66:26
__webpack_require__ @ bootstrap cce4570accfe85501067:678
fn @ bootstrap cce4570accfe85501067:88
./src/index.js @ index.css?f255:26
__webpack_require__ @ bootstrap cce4570accfe85501067:678
fn @ bootstrap cce4570accfe85501067:88
0 @ registerServiceWorker.js:117
__webpack_require__ @ bootstrap cce4570accfe85501067:678
(anonymous) @ bootstrap cce4570accfe85501067:724
(anonymous) @ bootstrap cce4570accfe85501067:724
index.js:2178 {data: {}, status: 400, statusText: "", headers: {}, config: {}}

どうやら、dotenvに設定したはずの、APIキーの値が読みこまれていないようです。

解決に向けてやったこと

  • dotenvリポジトリのcloseされたissueの中から、関連したものがないか検索してみる
  • create-react-appのソースコードを読んでみる

いくつか検索していくうちに、create-react-appのUsers Guideに、次のような一文があることを発見。

Note: this feature is available with react-scripts@0.5.0 and higher.

To define permanent environment variables, create a file called .env in the root of your project:

REACT_APP_SECRET_CODE=abcdef

Note: You must create custom environment variables beginning with REACT_APP_. Any other variables except NODE_ENV will be ignored to avoid accidentally exposing a private key on the machine that could have the same name. Changing any environment variables will require you to restart the development server if it is running.

ここによると、create-react-appで作成したプロジェクトでdotenvを使用する場合、prefixにREACT_APP_をつける必要があるとのこと。

ということは、もしやcreate-react-app自体に、すでにdotenvが組み込まれているのでは?

ソースコードを調べてみると。。

packages/react-scripts/config/env.js

var dotenvFiles = [ 
 `${paths.dotenv}.${NODE_ENV}.local`, 
 `${paths.dotenv}.${NODE_ENV}`, 

すでにenv.jsがあるじゃないですか!

つまり、わざわざdotenv.config(process.env.YOUTUBE_API_KEY);のように書かなくても、create-react-appでは、すでにdotenvを使えるようにお膳立てしてくれているので、それに任せればいいということ。

改修後のコード

というわけで、最終的に動くようになったコードがこちら。

import React, { Component } from "react";
import YTSearch from "youtube-api-search";

const API_KEY = process.env.REACT_APP_YOUTUBE_API_KEY;
console.log(API_KEY);

YTSearch({ key: API_KEY, term: "水族館" }, function(data) {
  console.log(data);
});
REACT_APP_YOUTUBE_API_KEY=hogehogehugahuga485732

これでコンソールでもエラーは出ずに、無事API経由で値を取ることができました!

(5) [{}, {}, {}, {}, {}]
0
:
{kind: "youtube#searchResult", etag: ""XI7nbFXulYBIpL0ayR_gDh3eu1k/5XPZmUCd7jo1pdJ1-CDdosFeI-Y"", id: {}, snippet: {}}
1
:
{kind: "youtube#searchResult", etag: ""XI7nbFXulYBIpL0ayR_gDh3eu1k/0UIYPKhKX74Bsl8caKN0h2CyjnI"", id: {}, snippet: {}}
2
:
{kind: "youtube#searchResult", etag: ""XI7nbFXulYBIpL0ayR_gDh3eu1k/Kq9VGmwBXKns6SFyEP9eOBvDYoU"", id: {}, snippet: {}}
3
:
{kind: "youtube#searchResult", etag: ""XI7nbFXulYBIpL0ayR_gDh3eu1k/dgrrAw4tSfS0I0Tm_3HAWMZikC4"", id: {}, snippet: {}}
4
:
{kind: "youtube#searchResult", etag: ""XI7nbFXulYBIpL0ayR_gDh3eu1k/9cZ31PrsKQHnbREvITl_0hnheMY"", id: {}, snippet: {}}
length
:
5
__proto__
:
Array(0)

最後に

答えは常に公式リファレンスと公式リポジトリに書いてある。

39
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
26