シングル ページ アプリのランタイム環境変数


シングル ページ アプリケーション (SPA) はすべて、ブラウザー ランタイム環境内で静的ページとして実行されます.ブラウザー内では、SPA で使用できるランタイム変数のようなものはありません.ただし、SPA に動的環境変数を実装できるハックはほとんどありません.

しかし、問題は、静的ページにランタイム変数が必要な理由です.私の経験では、SPA のランタイム変数または動的変数を探す必要があるケースはほとんどありません.たとえば、ローカル、本番前、本番用の異なる API エンドポイント、本番前と本番用の異なる API キーなどです.

ローカル開発を開始するには、いくつかの構成が必要です。


  • 環境ファイル
  • Bash スクリプト
  • NPM スクリプト
  • public/index.html に script タグを含める
  • ランタイム変数が必要なスクリプト


  • 1. 環境ファイル

    env.preprod ファイルを作成し、このファイルを/public/env/の場所に作成します./public/env/env.preprod
    これはランタイム環境変数が格納されるファイルで、ファイル内に複数の変数が存在する可能性があります.なぜ公開ディレクトリの下にあるのですか?ビルド プロセス中に tarball にバンドルされるため

    //Filename: env.preprod
    APP_RUNTIME_PREPROD_KEY=xyz
    




    2. Bash スクリプト

    ローカルの npm start 中に実行される Bash スクリプト.これにより、env.preprod ファイルのコンテンツを使用して env-config.js が作成され、展開中に pre-prod の場合も同じになります. prod には、デフォルトの env-config.js ファイルがあります.

    ファイル名: env.sh

    #!/bin/bash
    
    # look for runtime env file
    if [ ! -z "${2}" ]; then
      envFile="${1}"/env."${2}"
    fi
    
    #If can't find it then exit
    if [[ ! -f "$envFile" ]]; then
    echo "Env file doesn't exist!"
    exit 1;
    fi
    
    
    # create runtime env JS file
    if [[ ! -z "${1}" ]]; then
      envJs="${1}/env-config.js"
    fi
    
    #Recreate config file
    rm -rf ${envJs}
    touch ${envJs}
    
    # Add assignment 
    echo "window._env_ = {" >> ${envJs}
    
    # Read each line in .env file
    # Each line represents key=value pairs
    while read -r line || [[ -n "$line" ]];
    do
      # Split env variables by character `=`
      if printf '%s\n' "$line" | grep -q -e '='; then
        varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')
        varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')
      fi
    
      # Read value of current variable if exists as Environment variable
      value=$(printf '%s\n' "${!varname}")
      # Otherwise use value from .env file
      [[ -z $value ]] && value=${varvalue}
    
      # Append configuration property to JS file
      echo "  $varname: \"$value\"," >> ${envJs}
    done < ${envFile}
    
    echo "};" >> "${envJs}"
    
    echo "generated ${envJs} with content"
    cat ${envJs}
    




    3. NPM スクリプト

    これは prestart npm script として接続され、bash スクリプトを実行します.

    //Change in package.json file
    "prestart" : "chmod +x ./public/env/env.sh && ./public/env/env.sh ./public/env preprod"
    




    4. public/index.html に script タグを含めます.

    これまでに作成した env-config.js を index.html にロードする必要があります.ロードしないと使用できません. env-config.js が作成されると、ブラウザーのウィンドウ オブジェクトにランタイム変数が割り当てられます.

    <!--Change in index.html-->
    <head>
      <script src="%PUBLIC_URL%/env/env-config.js?d=20210529"></script>
    </head>
    




    5. ランタイム変数を実際に使用するスクリプト

    これまでの大変な作業が終わったので、今度はランタイム変数を熟成/使用します.変数はウィンドウ オブジェクトとして割り当てられているため、必要な方法で使用できます.バニラ JS ファイル ファイルでも使用できます.チェックアウト Sample Code

    //Filename: some-important.js
    const RUNTIME_ENV_KEY = window?._env_?.APP_RUNTIME_PROD_KEY ? window._env_.APP_RUNTIME_PROD_KEY : window?._env_?.APP_RUNTIME_PREPROD_KEY;
    
    


    また、index.html の head タグに some-important.js を含めます.

    <!--Change in index.html-->
    <head>
      <script src="%PUBLIC_URL%/some-important.js?d=20210529"></script>
    </head>
    


    プリプロ用


  • 展開中にスクリプトを実行する
  • location.conf (NGINX 使用時)


  • 1. デプロイ中にスクリプトを実行する

    展開プロセスに env.sh を実行するスクリプトを含めます. Docker イメージの詳細については、末尾の参照セクションを確認してください.

    ファイル名: preprod-deployment.sh

    bash ./public/env/env.sh ./public/env preprod
    




    2. location.conf(NGINX利用時)

    Nginx サーバーを Web サーバーとして使用する場合は、env-config.js ファイルへのアクセスを許可します.

    ファイル名: location.conf

    location ~ /env/(.+\.(?:js))$ {
      expires -1;
      add_header Cache-Control "public"
    }
    


    生産用




    1. デフォルトの env-config.js を作成する

    デフォルトを作成すると、本番環境へのデプロイ中に必要な手順を構成する労力が軽減されます.ただし、必要に応じて、env.prod などの別の env ファイルを作成し、本番環境のデプロイ中に同じものを実行できます.ただし、これは完全にあなた次第です!

    ファイル名: env-config.js

    window._env_ = {
      APP_RUNTIME_PROD_KEY=runtime-env-value
    };
    


    サンプルコード



    このブログで紹介されているコード スニペットは、Github の Sample Code で入手できます.

    あなたがここにたどり着いたなら、私はあなたが読み続けられるように十分な努力をしました.コメントを残していただくか、修正を依頼してください.ハッピーコーディング!


    参考文献:

  • https://www.freecodecamp.org/news/how-to-implement-runtime-environment-variables-with-create-react-app-docker-and-nginx-7f9d42a91d70/


  • 私の他のブログ: