12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【nuxt, axios】nuxt build した後から環境変数を反映させたい【RuntimeConfig】

Last updated at Posted at 2020-07-14

TL; DR

  1. @nuxtjs/axios のバージョンが 5.12.0 以上であることを確認 (package.jsonを参照)
  2. Options | Axios Module#runtime-config をよく見て,nuxt.config.js に追記する.
  3. nuxt start 時に環境変数を渡しても読み込んでくれるようになる!
nuxt.config.js
export default {
  modules: [
    '@nuxtjs/axios'
  ],

  axios: {
    baseURL: 'http://localhost:4000', // Used as fallback if no runtime config is provided
  },

  publicRuntimeConfig: {
    axios: {
      browserBaseURL: process.env.BROWSER_BASE_URL
    }
  },

  privateRuntimeConfig: {
    axios: {
      baseURL: process.env.BASE_URL
    }
  },
}
$ BROWSER_BASE_URL=http://example.com BASE_URL=http://my-container nuxt start

※ 以下の方法でも渡せる

  • .env ファイル
  • docker の引数として渡す
  • docker-composeenvironment として渡す

背景:axiosに対して,ビルドした後に環境変数を渡したい

nuxtをdockerでデプロイしようとしたときに,サーバが貧弱すぎてビルド出来なかった.代わりにローカルでビルドしてからそれを docker image として焼いてから Docker Hub にプッシュして,サーバ側ではすでにビルド済みのイメージを引っ張ってくればいいと考えた.しかし,ビルド時に渡していた環境変数を読み込んでくれない という問題に直面した.具体的には,@nuxtjs/axiosproductiondevelopment 環境を切り分けたいと考えていたが,このままでは production 時の値をサーバ側で持てないことになる.

調査

axios のオプションで解決できないかな~~と調べていた矢先,前回見たときには絶対になかったであろう Runtime Config オプション を見つける.

Runtime Config
The use of runtime config is mandatory in case of using environment variables in production, otherwise, the values will be hard coded during build and won't change.

訳:本番環境で環境変数を使用する場合は,ランタイムコンフィグの使用が必須です.もし使わない場合は,その値はビルド中にハードコードされ,変更されることはありません.
cf. Runtime Config - NuxtJS (参照:2020/07/15)

まさしくやりたいことそのままでウケてしまった(フロントをやっているとこういう開発の最先端に居ることを実感して楽しいね)

で,RuntimeConfig とはなんぞやと思ってリンク先を参照すると,nuxt v2.13.x での新機能であることも判明した.

Nuxt.js supports env config to provide configuration via process.env. This is done by webpack's DefinePlugin.

This approach had two downsides:

  • Values are read during build time and persisted into webpack bundle. So for a change to process.env we need to rebuild which is against 12factor app design
  • It can easily mislead to expose secret keys to client-side bundle

You can learn more about why we are moving from @nuxtjs/dotenv to runtime config.

cf. Moving from @nuxtjs/dotenv to runtime config - NuxtJS (参照:2020/07/15)

だいたいの意味としては「今までのやり方だと欠点が2つほどあったから,RuntimeConfig に乗り換えることで改善しようぜ!」ということらしい.巷であふれる @nuxtjs/dotenv くんのやり方をウゼェと思って触れなかった直感が見事にあたってしまったな……

実践

 何も考えずドキュメントをコピペしてはビルドし,おかしいな~~と首を傾げてはビルドするという地獄をひたすら繰り返した後,こんなにも思い通りに行かないのはおかしいと思い始める.で,「実はまだ実装されていない未来の機能だったのでは?」あるいは「あまりにも古すぎる文献にあたってしまい破壊的変更があったのでは?」との結論にいたり,リリースノートを探し始める.
 そこまで手を動かし始めてから10時間が経っていたが,ようやくたどり着いた結論として「ごく最近になって実装された機能であり,誰も実践して文書にまとめていない」ものだったことが発覚.誰の意見も参考にならないはずだわ……

もちろん今のヴァージョンのままでは通用しないのであった.俺の10時間を返してくれ……

結論

  1. @nuxtjs/axios を最新のものにアップデートして,
  2. nuxt.config.jsRuntimeConfig に関する記述を追加して,
  3. どうにかしてビルドした後に環境変数を渡す!
  • .env ファイル
  • コマンドラインで nuxt start する直前に定義して渡す
  • docker の引数として渡す
  • docker-composeenvironment として渡す

Contributor からの提言

🚫 Don’t commit sensitive values or secret keys to git
🚫 Don't store secret keys or sensitive values in your nuxt.config or .env unless is gitignored
✅ Use default values for runtimeConfig such as process.env.baseURL || 'https://nuxt.js.org'
✅ Store secret keys correctly using your hosting platform such as on Heroku or Netlify etc
✅ Follow JS naming convention (secretKey rather than SECRET_KEY) for runtimeConfig
✅ Prefer using runtimeConfig rather than env option

# 小ワザ

baseURL に関する記述は RuntimeConfig.axios に移動できる.

 Used as fallback if no runtime config is provided となっているが,トップレベルでの axios以下に baseURL, browserBaseURLを指定すると,「ビルド時点での」値を渡すことになっているためである.もし指定しなかった場合,デフォルト値として「localhost:3000」をとる.
 しかし,RuntimeConfig に対して以下のように論理和を取れば,当該の環境変数(この例でいうと BROWSER_BASE_URL)が指定されなかったときの代理文字列(この例だとhttps://nuxtjs.org)を指定することが出来る.すなわち,ビルドの段階ではデフォルト値 localhost:3000 だったものを 代理文字列で上書きできる ため,以下の記法で指定するときは axios 直下の baseURL オプションが不要になる.

nuxt.config.js
  // RutimeCOnfig以下に論理和として書けば,axios オプションは省略可能
  // axios: {
  //  baseURL: 'http://localhost:4000', 
  // },
  publicRuntimeConfig: {
    axios: {
      browserBaseURL: process.env.BROWSER_BASE_URL || 'https://nuxtjs.org'
    }
  },

感想

 ローカルPCでビルドしてリモートサーバでイメージを引っ張ってくるだけで良くなったのが個人的には最高!って感じ(サーバ環境のスペックをあんまり意識しなくていいので)

きちんと原文にもあたりましょうという話でした( n 回目)

参考文献(参照:2020/07/15)

12
8
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
12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?