Nuxt.jsでdotenv-moduleを使い、nuxt.config.jsから値が読み取れないときの原因と対応

.envのファイル名を変更したり、パスを変更しているとnuxt.config.jsrequire('dotenv').config()しても設定を読み込めない。 require('dotenv').config({ path: envPath })のように、config()の引数でファイルのパスを指定すれば読み込めるようになる。

以下検証。

Nuxt.jsでローカル環境、dev環境、本番環境でそれぞれ異なるAPIのURLを使いたい。
環境依存のものは環境ごとのファイルで管理したかったので、nuxt-community/dotenv-moduleを使うことにした。しかし、nuxt.config.jsaxiosbaseURLを設定する際にハマったので記事を残しておく。

ディレクトリ構成としては、ローカル環境用の.env.local、dev環境用の.env.development、本番環境用の.env.productionを用意し、configディレクトリにまとめる形にした。

 
 
 
 














├── config
│   ├── .env.development
│   ├── .env.local
│   └── .env.production
├── README.md
├── assets
├── components
├── layouts
├── middleware
├── node_modules
├── nuxt.config.js
├── package-lock.json
├── package.json
├── pages
├── plugins
├── static
└── store

Nuxt.jsのインストール

実際にNuxt.jsで環境ごとに異なるファイルを読み込むプロジェクトを作る。
まずはcreate-nuxt-appでNuxt.jsのプロジェクトを作成する。
APIのURLを確認するためaxiosをインストールする。自分はSPAで使うのでrendering modeSingle Page Appを選んでいる。
他は特に設定しない。

$ npx create-nuxt-app nuxt-dotenv-test
> Generating Nuxt.js project in /path/to/project
? Project name nuxt-dotenv-test
? Project description My ace Nuxt.js project
? Use a custom server framework none
? Choose features to install Axios
? Use a custom UI framework none
? Use a custom test framework none
? Choose rendering mode Single Page App
? Author name nansystem
? Choose a package manager npm

コマンドラインに表示されている通りに、起動の確認を行う。

$ cd nuxt-dotenv-test
$ npm run dev

@nuxtjs/dotenvのインストールとnuxt.config.jsの設定

@nuxtjs/dotenvをインストールする。

$ npm install @nuxtjs/dotenv

nuxt.config.jsmodules@nuxtjs/dotenvを追加する。


 



  modules: [
    '@nuxtjs/dotenv',
    '@nuxtjs/axios',
  ],

Nuxt.js.envファイルが読み込めることを確認するため、プロジェクトのルート階層に.envファイルを用意する。

.env

MESSAGE="hello!"

componentからprocess.envで設定した値が取得できることを確認する

pages/index.vuemounted()を追加し、process.envから追加した値が取得できるか確認する。








 
 
 



<script>
import Logo from '~/components/Logo.vue'

export default {
  components: {
    Logo
  },
  mounted() {
    console.log(process.env.MESSAGE)
  }
}
</script>

ChromeのConsoleを開くとhello!と表示されており、.envから値を取得できている。

nuxt.config.jsからprocess.envで設定した値が取得できることを確認する

次に、nuxt.config.jsから.envの値を読み取れることを確認していく。

nuxt.config.jsに次の記述を追加する。1行目のimport pkgcreate-nuxt-appで生成した際に記述されていたので無視して、require('dotenv').config()を追加し、console.infoで値が取得できるか確認する。


 
 

import pkg from './package'
require('dotenv').config()
console.info('nuxt.config.js MESSAGE:', process.env.MESSAGE)

起動ログに.envで設定したとおりhello!が表示されていればOK。

↻ Updated nuxt.config.js
ℹ nuxt.config.js MESSAGE: hello!

configディレクトリに.env.local、.env.development、.env.productionを作成し、それぞれ取得できることを確認する

package.jsonscriptsにローカル環境、dev環境、本番環境用のビルドスクリプトを追加する。






 
 
 


  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "build-local": "ENV=local nuxt build",
    "build-development": "ENV=development nuxt build",
    "build-production": "ENV=production nuxt build"
  },

環境ごとの.envファイルを用意する。

.env.local

BASE_URL="http://localhost:8080"

.env.development

BASE_URL="http://example.com/dev"

.env.production

BASE_URL="http://example.com/prod"

nuxt.config.jsを書き換えて、configディレクトリ下の.envファイルを参照するようにする。
自分はここでハマった。ドキュメントに

just append require('dotenv').config() to your nuxt.config.js と書かれているからconfig()の引数に何も指定していなかったのだけど、pathを指定してやる必要がある。 キー名はfilenameではなくpathなのも注意ポイント。
あとはaxiosbaseURLを指定すればよい。

nuxt.config.js

...略
const envPath = `config/.env.${process.env.ENV || 'local'}`
require('dotenv').config({ path: envPath })
...略
  modules: [
    '@nuxtjs/dotenv',
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
  ],
  dotenv: {
    filename: envPath
  },
  axios: {
    baseURL: process.env.BASE_URL,
  },

axiosにURLを設定できていることを確認するため、index.vuethis.$axios.defaults.baseURLを表示するようにしておく。

  mounted() {
    console.info('this.$axios.defaults.baseURL:', this.$axios.defaults.baseURL)
  }

ローカル用にビルドして、サーバを立ち上げる。

$ npm run build-local
$ npm start

トップ画面のコンソールを表示すると、baseURLが設定できている。

this.$axios.defaults.baseURL: http://localhost:8080

同様にdev環境用、本番環境用にビルドしても、baseURLが設定できている。

$ npm run build-development
$ npm start
this.$axios.defaults.baseURL: http://example.com/dev

ちなみに...

dotenvのREADMEには.envファイルをコミットすべきではないし、.envファイルを複数持つべきじゃないと書かれてる。

Should I commit my .env file? No. We strongly recommend against committing your .env file to version control.

Should I have multiple .env files? No. We strongly recommend against having a "main" .env file and an "environment" .env file like .env.test. https://github.com/motdotla/dotenv#readme