Vue.js で SPA のフロントを構築し始めると、開発・検証・本番と環境別に違う情報を管理することになるかと思います。
そこで環境別の情報を
.env
ファイルに記述し、CI/CD に乗せて運用していく中で、ソース管理やファイル構成に困ったことはないでしょうか?
そんな時の一例を紹介しますので、何かの一助になれば幸いです!
※ 一個人の見解ですので必ずしも正解や正攻法ではありません。より良い方法があればお気軽にフィードバック頂ければと思います。
.env
ファイルに環境別の情報(サーバー情報や接続情報など)を記述して、Vue.js のフロントエンドを構築しました。
しかし、運用していくと以下のような課題が発生してきました。
develop
ブランチ内に、
staging
環境の環境設定ファイルがある…等
ルートディレクトリ(
app
)下に
.env.[mode]
ファイルが環境分並びます
例として、
.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_ENV
、VUE_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
フォルダ下は消えたりしません。
ソースコードのブランチを変えるたびに、環境別ファイルをコピーしてきたりする手間を省くことができます。