ごめんなさい最初に書いたやり方やっぱりそんなにイケてないです
下の方に追記したdotenv使う方法が一番よさげでした
ダメな例
<template>
<div>
{{ response }}
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'hello',
data () {
return {
response: '',
}
},
mounted () {
axios.defaults.baseURL =
process.env.VUE_APP_ENV === 'production' ? 'http://localhost:8001'
: process.env.VUE_APP_ENV === 'staging' ? 'http://localhost:8002'
: 'http://localhost:8003'
this.$axios.get('/get.json').then(response => (this.info = response))
}
}
</script>
$ export VUE_APP_ENV=production
$ npm run build
ビルドされたjsファイルにstagingやdevelopment用のAPIのホスト名も書かれてしまうのでこれはNG
ってことで以下のやり方にしましょう
いい例
const webpack = require('webpack')
module.exports = {
configureWebpack: {
plugins: [
new webpack.DefinePlugin({
'VUE_APP_API_ENDPOINT': JSON.stringify(
process.env.VUE_APP_ENV === 'production' ? 'http://localhost:8001'
: process.env.VUE_APP_ENV === 'staging' ? 'http://localhost:8002'
: 'http://localhost:8003'
)
})
]
},
<template>
<div>
{{ response }}
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'hello',
data () {
return {
response: '',
}
},
mounted () {
axios.defaults.baseURL = VUE_APP_API_ENDPOINT
this.$axios.get('/get.json').then(response => (this.info = response))
}
}
</script>
もしくは
これでもいい
module.exports = {
chainWebpack: config => {
config
.plugin('web-component-options')
.use(require('webpack/lib/DefinePlugin'), [{
'VUE_APP_API_ENDPOINT': JSON.stringify(
process.env.VUE_APP_ENV === 'production' ? 'http://localhost:8001'
: process.env.VUE_APP_ENV === 'staging' ? 'http://localhost:8002'
: 'http://localhost:8003'
)
}])
}
}
参考資料
- https://cli.vuejs.org/config/#configurewebpack
- https://cli.vuejs.org/guide/webpack.html#simple-configuration
- https://cli.vuejs.org/config/#chainwebpack
- https://cli.vuejs.org/guide/webpack.html#chaining-advanced
Vue CLI3は2系に比べるとWebpackの設定が隠されてて苦労しました
セキュリティ意識と給料は高いに越したことはないですね
追記
上記だと動作は問題ないけどLinterが
VUE_APP_API_ENDPOINT
が未定義だよって怒るので結局dotenvがいいのかもしれない
dotenvで環境ごとに切り替える方法
.env.[mode]
というファイルを用意する
例えば
-
.env.development
=> developmentモードの時に読み込まれる -
.env.staging
=> stagingモードの時に読み込まれる -
.env.production
=> productionモードの時に読み込まれる -
.env
=> モード関係なく読まれる(共通の項目を書くといい)
下に貼ったリンクの公式ドキュメント見るとdevelopment
/production
/test
だけが取り上げられてるけどstaging
もいけるみたい
ただ、環境変数NODE_ENV
はdevelopment
/production
のどちらかにしとかないとビルド時の設定が変わるらしい(optimizedとか)
modeの指定
serve
やbuild
の時に--mode development
とかってしてやればいいけど
$ npm run server --mode development
だと引数をちゃんと拾ってくれないので
$ ./node_modules/.bin/vue-cli-service serve --mode staging
と叩くか、もしくはpackage.json
にスクリプトを追加する
.
.
.
"scripts": {
"serve:dev": "vue-cli-service serve --mode development",
"serve:stg": "vue-cli-service serve --mode staging",
"serve:prd": "vue-cli-service serve --mode production",
"build:dev": "vue-cli-service build --mode development",
"build:stg": "vue-cli-service build --mode staging",
"build:prd": "vue-cli-service build --mode production",
"lint": "vue-cli-service lint"
},
.
.
.
環境変数の制約
基本定数にはプレフィックスVUE_APP_
をつけなきゃいけないけど
NODE_ENV
は許されるっぽい
以上を踏まえてどうしたらいいのかっていうと
1. 下記ファイルを作成
- .env.development
- .env.staging
- .env.production
- .env
2. 下記ファイルを修正
- package.json
3. vueソース内ではprocess.env.VUE_APP_API_ENDPOINT
をはめ込む
こんな感じかな
# 共通の設定を書く
VUE_APP_COMMON=common
# developmentの設定を書く
NODE_ENV=development
VUE_APP_API_ENDPOINT=http://localhost:3000
# stagingの設定を書く
NODE_ENV=production
VUE_APP_API_ENDPOINT=http://stg.api-server-domain
# productionの設定を書く
NODE_ENV=production
VUE_APP_API_ENDPOINT=http://api-server-domain
.
.
.
"scripts": {
"serve:dev": "vue-cli-service serve --mode development",
"serve:stg": "vue-cli-service serve --mode staging",
"serve:prd": "vue-cli-service serve --mode production",
"build:dev": "vue-cli-service build --mode development",
"build:stg": "vue-cli-service build --mode staging",
"build:prd": "vue-cli-service build --mode production",
"lint": "vue-cli-service lint"
},
.
.
.
<template>
<div>
{{ response }}
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'hello',
data () {
return {
response: '',
}
},
mounted () {
axios.defaults.baseURL = process.env.VUE_APP_API_ENDPOINT
this.$axios.get('/get.json').then(response => (this.info = response))
}
}
</script>
NODE_ENVについては
modeオプションとは別に、明示的に定義しないと
stagingはNODE_ENV=development
としてビルドされてしまうため
NODE_ENV=production
で定義してる
ローカルでビルドした結果を確認したい時には
.env.development
もNODE_ENV=production
にしたりしなきゃいけないだろうから
全部NODE_ENV=production
でもいいかも
それなら.env.development
にだけNODE_ENV
を書かずに
npm scriptsでexportしちゃうとか
.
.
.
"scripts": {
"serve:dev": "export NODE_ENV=development; vue-cli-service serve --mode development",
"serve:stg": "vue-cli-service serve --mode staging",
"serve:prd": "vue-cli-service serve --mode production",
"build:dev": "export NODE_ENV=production; vue-cli-service build --mode development",
"build:stg": "vue-cli-service build --mode staging",
"build:prd": "vue-cli-service build --mode production",
"lint": "vue-cli-service lint"
},
.
.
.
いっそのことstgもprdもNODE_ENV
はnpm scriptsに書いた方がいい気がしてきた
〆
ってことで
これでlinterに文句は言われず、ビルドされたjsにも他環境の情報が載らないのでこっちの方がよさげですね
他にいい方法あったら教えてくださいフロントエンドの神様
参考記事
- https://cli.vuejs.org/guide/mode-and-env.html#environment-variables