はじめに
Vue.js で SPA のフロントを構築し始めると、開発・検証・本番と環境別に違う情報を管理することになるかと思います。
そこで環境別の情報を .env
ファイルに記述し、CI/CD に乗せて運用していく中で、ソース管理やファイル構成に困ったことはないでしょうか?
そんな時の一例を紹介しますので、何かの一助になれば幸いです!
※ 一個人の見解ですので必ずしも正解や正攻法ではありません。より良い方法があればお気軽にフィードバック頂ければと思います。
課題
.env
ファイルに環境別の情報(サーバー情報や接続情報など)を記述して、Vue.js のフロントエンドを構築しました。
しかし、運用していくと以下のような課題が発生してきました。
- Git のブランチを環境別に作っているため、環境設定ファイルを管理しにくい
-
develop
ブランチ内に、staging
環境の環境設定ファイルがある…等
-
- 環境別ファイルをソースコードと別リポジトリで管理すると、今度は開発がやりにくい
- ソースコードリポジトリのブランチを切り替えたら、環境設定リポジトリも切り替える必要がある…等
解決方法
本記事では下記のステップで各課題を解決していきます。
- 環境別の変数をファイルごとに管理する
1.1. 環境別の構成 - 環境別ファイルをGitで管理する
2.1. 環境別の構成(Git管理向け)
2.2. 運用例
2.3. 開発方法
構成・前提
Vue CLI で SPA として構築します。
項目 | バージョン |
---|---|
Vue CLI | 4.5.9 |
Vue.js | 2.6.11 |
npm | 8.1.0 |
なお、ローカル開発環境のOSは、Windows10を想定しています。
環境別の構成
環境別ファイルを構成する上で、Vue CLI の「モードと環境変数」を参考にします。
Qiita記事だと下記が参考になります。
環境
本記事では下記の環境を想定します。
環境名 | 内容 |
---|---|
development | 開発環境 |
staging | 検証環境 |
production | 本番環境 |
.env ファイル
環境に従って、モードごとの .env
ファイルを作成します。
作成した .env
ファイルは下記のファイル構成の通り配置します。
ファイル構成
app
├─ 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
ルートディレクトリ(app
)下に .env.[mode]
ファイルが環境分並びます
.env ファイル内容
例として、.env.staging
の内容を記載します。
NODE_ENV='production'
VUE_APP_MODE='staging'
ポイント
環境変数 VUE_APP_MODE
がモードを表す変数になります。
.env.[mode]
の [mode]
部分を変数の値として設定します。
注意点
紛らわしいですが、NODE_ENV
は Node.js の環境変数となるため、値('production'
)は関係ありません。
package.json
モードを適用してビルドできるように package.json
を編集します。
...
"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
の値を出力します。
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フォルダ
環境別ファイルを格納するフォルダおよび環境別ファイルを新規作成します。
ファイル構成
app
├─ env # 追加
│ ├─ development # 追加
│ │ └─ .env # 追加
│ │
│ ├─ production # 追加
│ │ └─ .env # 追加
│ │
│ └─ staging # 追加
│ └─ .env # 追加
│
├─ public
(以下省略)
vue.config.js
vue.config.js をルートディレクトリ下に追加します。
vue-cli-service
実行時に自動で読み込まれるファイルです。
var dotenv = require('dotenv').config({ path: `./env/${process.env.VUE_APP_MODE}/.env` })
if (dotenv.error) {
throw dotenv.error
}
require('dotenv-expand')(dotenv)
ポイント
- 1行目: 環境変数
VUE_APP_MODE
を用いて、上記で作成したenv
フォルダ下の.env
ファイルをパスに指定 - 5行目:
dotenv
をdotenv-expand
で拡張
これで、環境別フォルダ下(app/env/
)に、環境別ファイル(.env
)を配置することができました。
env/{環境名}/.env
ファイルの中身の書き方としては、dotenv
や、dotenv-expand
に習います。
# Can use $VUE_APP_MODE, $NODE_ENV
# .env local variables
CLIENT_ID='abcde'
# 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}
を埋め込んでいます
環境変数の確認
ローカルサーバーを再起動して環境変数を確認します。
VUE_APP_API_URL
が出力されました。埋め込み文字列も変換されています。
注意点
- 同じ js ファイルで混同しやすいですが、
src
フォルダ以下(main.js
など)が Vue.js のモジュールです
vue.config.js
は Node.js のモジュールになります - Vue CLI のドキュメント通り、Vue.js の環境変数は、プレフィックスとして
VUE_APP_
を付加してください - 埋め込み文字列が不要な方は、
dotenv-expand
のセットアップが不要となります
運用例
それでは「環境別の構成(Git管理向け)」にて基盤を整えたところで、Git の運用例や CI/CD の設定例を見ていきます。
ソースコードリポジトリ
Vue アプリケーションのソースコードを管理するリポジトリは、下記の通り環境別にブランチを切ります。
なお、ブランチ間(環境間)ではソースコードや、ファイル構成の差異は発生しません。
SourceCodeRepository # ソースコード用のリポジトリ
├─ development # 開発環境ブランチ
│ └─ (省略: 下記ファイル構成の通り)
│
├─ production # 本番環境ブランチ
│ └─ (省略: 下記ファイル構成の通り)
│
└─ staging # 検証環境ブランチ
└─ (省略: 下記ファイル構成の通り)
env フォルダ下の除外
ソースコードリポジトリから、env
フォルダ下の .env
ファイルをGit管理対象外とします。
.gitignore
app/.gitignore
に追記します。
...(省略)
# 追加
env/*.env
...(省略)
ファイル構成
最終的なソースコードリポジトリのファイル構成は以下の通りです。
app
├─ 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
フォルダ下は消えたりしません。
ソースコードのブランチを変えるたびに、環境別ファイルをコピーしてきたりする手間を省くことができます。