5
3

More than 1 year has passed since last update.

Vue + Dotenv で環境別の開発・運用を考える

Posted at

Vue.js で SPA のフロントを構築し始めると、開発・検証・本番と環境別に違う情報を管理することになるかと思います。

そこで環境別の情報を .env ファイルに記述し、CI/CD に乗せて運用していく中で、ソース管理やファイル構成に困ったことはないでしょうか?

そんな時の一例を紹介しますので、何かの一助になれば幸いです!

※ 一個人の見解ですので必ずしも正解や正攻法ではありません。より良い方法があればお気軽にフィードバック頂ければと思います。

.env ファイルに環境別の情報(サーバー情報や接続情報など)を記述して、Vue.js のフロントエンドを構築しました。

しかし、運用していくと以下のような課題が発生してきました。

  • Git のブランチを環境別に作っているため、環境設定ファイルを管理しにくい develop ブランチ内に、 staging 環境の環境設定ファイルがある…等
  • 環境別ファイルをソースコードと別リポジトリで管理すると、今度は開発がやりにくい
  • ソースコードリポジトリのブランチを切り替えたら、環境設定リポジトリも切り替える必要がある…等
  • ├─ .env.development # 追加 ├─ .env.production # 追加 ├─ .env.staging # 追加 ├─ .gitignore ├─ babel.config.js └─ package.json

    ルートディレクトリ( app )下に .env.[mode] ファイルが環境分並びます

    .env ファイル内容

    例として、 .env.staging の内容を記載します。

    .env.staging
    NODE_ENV='production'
    VUE_APP_MODE='staging'
      "scripts": {
        "serve": "vue-cli-service serve --mode staging",
        "build-development": "vue-cli-service build --mode development",
        "build-staging": "vue-cli-service build --mode staging",
        "build-production": "vue-cli-service build --mode production",
        "lint": "vue-cli-service lint"
    環境変数の確認
    main.js
    

    確認のため、環境変数としてビルドされた process.env.VUE_APP_MODE の値を出力します。

    main.js
    import Vue from 'vue'
    import App from './App.vue'
    Vue.config.productionTip = false
    console.log(process.env)  // 追加
    new Vue({
      render: h => h(App),
    }).$mount('#app')
    ローカルサーバー起動
    

    モードを staging に指定してローカルサーバーを起動します。

    NODE_ENVVUE_APP_MODE が出力されました(他のキーはデフォルトで設定されます)。

    この時点で、環境別ファイルの設定は完了しているので、これでも問題なく開発していけます。

    しかし、上述している運用的な課題を解決するべく、もう少し手を加えます。

    環境別の構成(Git管理向け)

    今回は「環境別ファイルを独立した別のリポジトリで、かつ環境ごとのブランチで管理したい。」という要件がありました。
    しかし、標準機能として扱える .env.[mode] ファイルは、ルートディレクトリに配置する必要があります。
    そこで、Node.js のライブラリである dotenv と、dotenv-expand を用いて、ファイル構成や環境別ファイルを変更していきます。

    dotenv + dotenv-expand

    プロジェクトに dotenv と dotenv-expand をインストールします。

    npm install dotenv --save-dev
    npm install dotenv-expand --save-dev
    envフォルダ
    

    環境別ファイルを格納するフォルダおよび環境別ファイルを新規作成します。

    ファイル構成 ├─ env # 追加 │ ├─ development # 追加 │ │ └─ .env # 追加 │ │ │ ├─ production # 追加 │ │ └─ .env # 追加 │ │ │ └─ staging # 追加 │ └─ .env # 追加 ├─ public (以下省略) vue.config.js

    vue.config.js をルートディレクトリ下に追加します。

    vue-cli-service 実行時に自動で読み込まれるファイルです。

    vue.config.js
    var dotenv = require('dotenv').config({ path: `./env/${process.env.VUE_APP_MODE}/.env` })
    if (dotenv.error) {
      throw dotenv.error
    require('dotenv-expand')(dotenv)
    # Vue environment variables
    VUE_APP_API_URL='https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/${CLIENT_ID}/${VUE_APP_MODE}'
    

    ※ 環境変数を設定した場合は、サーバーを再起動してください。

  • 4行目: CLIENT_ID はこの .env ファイル内でのみ使用可能です。
    埋め込み変数として使用したいけれど、Vue アプリケーション上に必要ないという場合に有用です
  • 7行目: 例として VUE_APP_API_URL というキーで、環境別のAPIのURLを設定してみました。
    ここでは、.env.staging 内で定義している環境変数も使用できるので、${VUE_APP_MODE} を埋め込んでいます
  • 同じ js ファイルで混同しやすいですが、src フォルダ以下(main.js など)が Vue.js のモジュールです
    vue.config.js は Node.js のモジュールになります
  • Vue CLI のドキュメント通り、Vue.js の環境変数は、プレフィックスとして VUE_APP_ を付加してください
  • 埋め込み文字列が不要な方は、dotenv-expand のセットアップが不要となります
  • ソースコードリポジトリ

    Vue アプリケーションのソースコードを管理するリポジトリは、下記の通り環境別にブランチを切ります。

    なお、ブランチ間(環境間)ではソースコードや、ファイル構成の差異は発生しません。

    ソースコードリポジトリ構成
    SourceCodeRepository           # ソースコード用のリポジトリ
    ├─ development               # 開発環境ブランチ
    │   └─ (省略: 下記ファイル構成の通り)
    ├─ production                # 本番環境ブランチ
    │   └─ (省略: 下記ファイル構成の通り)
    └─ staging                   # 検証環境ブランチ
        └─ (省略: 下記ファイル構成の通り)
    env フォルダ下の除外
    

    ソースコードリポジトリから、env フォルダ下の .env ファイルをGit管理対象外とします。

    .gitignore

    app/.gitignore に追記します。

    .gitignore
    ...(省略)
    env/*.env
    ...(省略)
    ファイル構成
    

    最終的なソースコードリポジトリのファイル構成は以下の通りです。

    ソースコードリポジトリ・ファイル構成
    ├─ env │ └─ .gitkeep # フォルダ構成を保つために追加 ├─ node_modules ├─ public │ ├─ favicon.ico │ └─ index.html ├─ src │ ├─ assets │ │ └─ logo.png │ │ │ ├─ components │ │ └─ HelloWorld.vue │ │ │ ├─ App.vue │ └─ main.js ├─ .env.development # 全環境残したままです ├─ .env.production # 全環境残したままです ├─ .env.staging # 全環境残したままです ├─ .gitignore ├─ babel.config.js ├─ package.json └─ vue.config.js 環境ファイルリポジトリ

    env フォルダ下の環境別ファイルは、ソースコードとは別のGitリポジトリで管理します。

    構成は以下の通りです。

    環境ファイルリポジトリ構成
        EnvironmentRepository   # 環境ファイル用のリポジトリ
        ├─ development          # developmentブランチ
        │   └─ .env             # 環境別ファイル
        ├─ production           # productionブランチ
        │   └─ .env             # 環境別ファイル
        └─ staging              # stagingブランチ
            └─ .env             # 環境別ファイル
    Git運用例
    

    ここまでの設定によって、環境別の情報を管理する際の気持ち悪さが解消できました。
    ただ、リポジトリを2つ運用することになるので、その点はご注意ください。

    ソースコードリポジトリ

    ソースコードリポジトリは、プルリクエストを基本としたよくある運用です。
    プルリク→マージ→リリースとステージングしていきます。

    環境ファイルリポジトリ

    環境間の .env ファイルは必ず差分があるので、マニュアルで比較しながら各ブランチにマージします。

    development ブランチの .env ファイル修正 development ブランチと比較しながら、staging ブランチの .env ファイル修正 staging ブランチと比較しながら、production ブランチの .env ファイル修正 CI/CD設定例

    各環境のパイプラインでは、下記のような手順でビルドします。
    development 環境を例示します

  • ソースコードリポジトリの development ブランチを clone
  • 1.の app/env/ 下にディレクトリ指定で、環境ファイルリポジトリを clone
  • git clone -b development https://{host}/app.git development
  • vue-cli-service build --mode development でソースコードをビルド

    最後に、開発方法についても記載します。

    env フォルダ下に環境ファイルリポジトリを clone すれば良いようにも感じますが、Gitリポジトリの中に別のGitリポジトリがあるのは望ましくありません。

    よって、ここではシンボリックリンクを使用します。

    環境ファイルを集約

    ローカルで開発しているソースコードリポジトリとは別のディレクトリに、各ブランチを clone します。

    ここでは C:\Dev\environments を作成します。

    コマンドプロンプト
    cd c:\Dev\environments
    git clone -b development https://{host}/app.git development
    git clone -b staging https://{host}/app.git staging
    git clone -b production https://{host}/app.git production
    クローン結果
    

    environments フォルダ内。

    各ブランチフォルダ内は、.env ファイルのみ。

    シンボリックリンク作成

    ローカルで開発しているソースコードリポジトリの env フォルダ内でコマンドプロンプトを開き、以下のコマンドを実行します。

    ※ 例では development 環境でローカルサーバーを起動しています。

    コマンドプロンプト
    mklink /j development c:\Dev\environments\development
    mklink /j staging c:\Dev\environments\staging
    mklink /j production c:\Dev\environments\production
    

    シンボリックリンク(ジャンクション)を作成することで、env フォルダ下を除外する前の構成に戻りました。

    開発方法まとめ

    env フォルダ下はGit管理対象外なので、もし他のブランチにチェックアウトしても、env フォルダ下は消えたりしません。

    ソースコードのブランチを変えるたびに、環境別ファイルをコピーしてきたりする手間を省くことができます。

    5
    3
    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
    Sign up Login
    5
    3