Nuxt.jsとServerlessでdotenvを共有する

Nuxt.jsとServerlessとで同じ`.env` ファイルを共有できるようにしてみました。

Nuxt.jsのプロジェクトは下記をベースにしています。

jeehyukwon/nuxt-serverless: Nuxt.js Serverless SSR Starter on AWS (Lambda + API Gateway + S3) with Serverless Framework
https://github.com/jeehyukwon/nuxt-serverless


## 前提

- AWSアカウントがある
- serverlessがインストール・設定済み
- node.js、npm(、yarn)がインストール済み


## 環境構築

とりあえず`.env` が共有できるよねーってことが確認できたら良いので、上記リポジトリをシンプルにしたものをベースにします。

kai-kou/nuxt-serverless at feature/no-use-s3
https://github.com/kai-kou/nuxt-serverless/tree/feature/no-use-s3

ベースにするリポジトリに関しては下記に利用方法をまとめています。

Nuxt.js(v2.2.0)+TypeScriptなアプリをAWS Lambda+αにデプロイしてみた(S3なし版) - Qiita
https://qiita.com/kai_kou/items/ffc4b7780e61f740e5d2

今回のソースはGithubにアップしていますので、よろしければご参考ください。
https://github.com/kai-kou/nuxt-serverless/tree/feature/use-dotenv

```sh
> mkdir 任意のディレクトリ
> cd 任意のディレクトリ
> git clone https://github.com/kai-kou/nuxt-serverless.git
> cd nuxt-serverless
> git checkout feature/no-use-s3
> npm install
```

### Nuxt.jsのプラグインを追加する

Nuxt.jsで`.env` から環境変数を読み込むことができるプラグインを利用させてもらいます。

nuxt-community/dotenv-module: Loads your .env file into your application context
https://github.com/nuxt-community/dotenv-module


```sh
> npm install --save @nuxtjs/dotenv
```

`.env` ファイルを作成しておきます。

```sh
> touch .env
```

```txt:.env
HOGE=hoge
```

`nuxt.config.js` に設定を追加します。

```js:nuxt.config.js_一部抜粋
const express = require('express')
const cookieParser = require('cookie-parser')
require('dotenv').config()

module.exports = {
  (略)
  modules: [
    '@nuxtjs/dotenv',
  ],
  env: {
    HOGE: process.env.HOGE,
  },
}
```

`vue` ファイルで環境変数が利用できることを確認するのに、`index.vue` で`{{process.env.HOGE}}` を利用するようにします。
`<template>` 内で`{{process.env.HOGE}}` としてもエラーになるのでご注意ください。

```vue:src/pages/index.vue
<template>
  <div class="page-index">
    {{hoge}}
    <h1>Nuxt Serverless Template {{ this.version }}</h1>
    <p>{{ message }}</p>
    <nuxt-link to="/typescript">typescript</nuxt-link>
    <nuxt-link to="/nuxt">nuxt</nuxt-link>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import { State } from 'vuex-class'

@Component
export default class PageIndex extends Vue {

  private get hoge(): string {
    return process.env.HOGE;
  }
  /**
   * You can fetch data from remote server with 'asyncData()' method
   */
  private async asyncData() {
    return {
      message: 'Say Hello to Node.js 8.10 in AWS Lambda and Nuxt 2.0',
    }
  }

  /**
   * override tags in <head> with 'head()' method
   */
  private head() {
    return {
      title: 'Hello, Nuxt Serverless Template',
    }
  }

  @State((state) => state.version) private version: string
}
</script>

<style lang="scss">
.page-index {
  h1 {
    color: #087f5b;
  }
}
</style>
```

実行して確認してみます。

```sh
> npm run dev
> open http://localhost:3000/dev/
```

<img width="578" alt="スクリーンショット 2018-12-13 9.13.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/5a9396fa-c832-b0f9-e8ad-b6c95da8085d.png">


はい。`hoge` と表示されました。


### Serverlessのプラグインを追加する

続いて、Serverlessでも`.env` が利用できるようにします。こちらもプラグインがありましたので、それを利用させてもらいます。

colynb/serverless-dotenv-plugin: Preload Environment Variables with Dotenv into Serverless
https://github.com/colynb/serverless-dotenv-plugin#readme

```sh
> npm install --save-dev serverless-dotenv-plugin
```

`serverless.yml` で`.env` から環境変数を読み込めるようにします。環境変数は`${env:HOGE}` とすることでアクセスできるようになります。

```yaml:serverless.yml_一部抜粋
service: nuxt-serverless # 1. Edit whole service name

provider:
  name: aws
  runtime: nodejs8.10
  stage: ${opt:stage, 'dev'}
  region: ap-northeast-1 # 2. Edit AWS region name
  environment:
    NODE_ENV: production
    HOGE: ${env:HOGE}
(略)
plugins:
  - serverless-offline
  - serverless-apigw-binary
  - serverless-dotenv-plugin
```

デプロイは割愛します。


## ポイント

### `.env.{env}` ファイルを取り扱うのにひと手間かかる

serverless-dotenv-pluginはenvironmentから`.env.development` や`.env.production` などのファイルを自動で探してくれるのですが、@nuxtjs/dotenvの方は、`nuxt.config.js` で指定する必要があります。

```js:nuxt.config.js_一部抜粋
  modules: [
    ['@nuxtjs/dotenv', { filename: '.env.development' }],
  ]
```

### `.env` ファイルはコミットしないようにする

`.gitnore`に追加してからコミットしましょう。`.env` の代わりに`.env.example` などサンプルとなるファイルをリポジトリに含めておけばどんな環境変数を利用するのかわかりやすくなります。


## 参考

nuxt-community/dotenv-module: Loads your .env file into your application context
https://github.com/nuxt-community/dotenv-module

colynb/serverless-dotenv-plugin: Preload Environment Variables with Dotenv into Serverless
https://github.com/colynb/serverless-dotenv-plugin#readme

Nuxt.js で dotenv を活用する – chatbox.blog
https://chatboxinc.wordpress.com/2018/03/26/nuxt_js_with_dotenv/

API: env プロパティ - Nuxt.js
https://ja.nuxtjs.org/api/configuration-env/