{
    "componentChunkName": "component---src-templates-blog-post-jsx",
    "path": "/post/you-might-not-need-dotenv-in-source/",
    "result": {"data":{"site":{"siteMetadata":{"title":"WEB EGG","author":"Leko - CTO at Yuimedi"}},"markdownRemark":{"id":"6bab5e52-2388-5b55-8a11-d34f44e4a9fe","excerpt":"dotenvというRuby発のOSSがあります。 .envって名前のファイルに環境変数を列挙してライブラリを読み込むと、それらの値をプロセス内の環境変数として値を展開してくれるというツールです。\nもちろんNode.js版の実装も存在します。 Heroku…","html":"<p><a href=\"https://github.com/bkeepers/dotenv\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">dotenv</a>というRuby発のOSSがあります。<br>\n<code>.env</code>って名前のファイルに環境変数を列挙してライブラリを読み込むと、それらの値をプロセス内の環境変数として値を展開してくれるというツールです。\nもちろん<a href=\"https://github.com/motdotla/dotenv\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Node.js版</a>の実装も存在します。</p>\n<p>Herokuを愛用していた時期によく使っていたのですが、何年か使ってみた結果プロセスの中で<code>require('dotenv').config()</code>と書くのではなく、そのプロセスを起動するときに<code>node --require dotenv/config</code>とrequireオプションを用いてdotenvとプログラムの依存をなくす方向に落ち着きました。<br>\nなぜそちらの方がいいのか考えていることを残しておく。</p>\n<h2 id=\"コードがコミットされてないはずのファイルに依存している\" style=\"position:relative;\"><a href=\"#%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8C%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%95%E3%82%8C%E3%81%A6%E3%81%AA%E3%81%84%E3%81%AF%E3%81%9A%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AB%E4%BE%9D%E5%AD%98%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B\" aria-label=\"コードがコミットされてないはずのファイルに依存している permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>コードがコミットされてない（はずの）ファイルに依存している</h2>\n<p>当然ですが、dotenvがソースに書かれているということは<code>.env</code>という名前のファイルが存在していることに依存しています。\nしかし.envはコミットすべきではないファイルなので、基本的にignoreされているはずです。</p>\n<blockquote>\n<p>Should I commit my .env file?\nNo. We strongly recommend against committing your .env file to version control.</p>\n<p>— <a href=\"https://github.com/motdotla/dotenv#should-i-commit-my-env-file\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">motdotla/dotenv: Loads environment variables from .env for nodejs projects.</a></p>\n</blockquote>\n<p>公式のREADMEにも.envはコミットしないことを強く推奨しています。<br>\nCIやデプロイ先でcheckoutしたときに.envって名前のファイルを作らないといけないのでプログラム内で読み込む方法は汎用的でないと思います。\n例えば以下のように環境変数を見たりして回避できますが、わざわざ環境別のifを書かずに済みます。</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>process<span class=\"token punctuation\">.</span>env<span class=\"token punctuation\">.</span><span class=\"token constant\">NODE_ENV</span> <span class=\"token operator\">===</span> <span class=\"token string\">'development'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'dotenv'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">config</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"いずれenvがコミットされ始める\" style=\"position:relative;\"><a href=\"#%E3%81%84%E3%81%9A%E3%82%8Cenv%E3%81%8C%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%95%E3%82%8C%E5%A7%8B%E3%82%81%E3%82%8B\" aria-label=\"いずれenvがコミットされ始める permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>いずれ.envがコミットされ始める</h2>\n<blockquote>\n<p>Should I have multiple .env files?\nNo. We strongly recommend against having a “main” .env file and an “environment” .env file</p>\n<p>— <a href=\"https://github.com/motdotla/dotenv#should-i-have-multiple-env-files\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">motdotla/dotenv: Loads environment variables from .env for nodejs projects.</a></p>\n</blockquote>\n<p>公式のREADMEにも.env.testなどのように環境別の.envは作成しないことを強く推奨しています。<br>\n<code>.env.test</code>、<code>.env.production</code>のように環境別のファイルが次々登場してもはや設定ファイル化しているdotenvのプロジェクトを多く見かけたことがあります。\n以下のようなファイル名を環境ごとにずらして読み込むコード見たことないでしょうか。私はあります。</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>process<span class=\"token punctuation\">.</span>env<span class=\"token punctuation\">.</span><span class=\"token constant\">NODE_ENV</span> <span class=\"token operator\">===</span> <span class=\"token string\">'development'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'dotenv'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">config</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        path<span class=\"token operator\">:</span> path<span class=\"token punctuation\">.</span><span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>process<span class=\"token punctuation\">.</span><span class=\"token function\">cwd</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">.env.</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>process<span class=\"token punctuation\">.</span>env<span class=\"token punctuation\">.</span><span class=\"token constant\">NODE_ENV</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>そしてテンプレート化した設定ファイルをメンバーが増えるたびにいちいち手動で作るのも面倒なので、便宜上の理由からコミットしてしまうパターンもよく見ます。\nGit管理する設定ファイルとしてdotenvはかなり質素なので、設定ファイルとして扱いたいならそもそも.envをやめて別の仕組み（AWSのKMSやHashicorpのVaultなど）を使ったほうがいいと思います。</p>\n<h2 id=\"dotenvをコードから追い出す\" style=\"position:relative;\"><a href=\"#dotenv%E3%82%92%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8B%E3%82%89%E8%BF%BD%E3%81%84%E5%87%BA%E3%81%99\" aria-label=\"dotenvをコードから追い出す permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>dotenvをコードから追い出す</h2>\n<p><code>node -r dotenv/config hoge.js</code>のように、nodeの<code>-r(--require)</code>オプションを利用すると、プログラム本体からdotenvを切り離せるようになります。\n上記のコマンドだと先にdotenvが読み込まれてprocess.envに環境変数がセットされ手から<code>hoge.js</code>が実行されます。<code>DATABASE_URL=xxx node hoge.js</code>のようにシェルから環境変数を指定してプロセスを起動した時と実質的には同じになります。</p>\n<p>requireオプションは、<a href=\"https://babeljs.io/docs/en/babel-register\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@babel/register</a>や<a href=\"https://github.com/TypeStrong/ts-node#programmatic\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ts-node/register</a>などでもrequireオプションは使うので馴染み深い方もいると思います。</p>\n<p>プログラムからdotenvの依存を剥がしておけばCIやデプロイ先では管理画面から環境変数を設定し、開発中はローカルにある.envを参照するなどの使い分けが容易になります。</p>","timeToRead":4,"frontmatter":{"title":"プログラム内でdotenvを読み込むのをやめた話","tags":["Node.js","JavaScript"],"date":"January 05, 2019","featuredImage":null}}},"pageContext":{"slug":"/you-might-not-need-dotenv-in-source/","previous":{"fields":{"slug":"/lets-start-lerna-changelog-to-easy-publish/"},"frontmatter":{"title":"lerna-changelogで始める頑張りすぎないリリースノート自動生成","tags":["npm","JavaScript","monorepo","Lerna"]}},"next":{"fields":{"slug":"/impression-comparison-of-middleman-and-gatsby/"},"frontmatter":{"title":"ブログをMiddlemanからGatsbyに乗り換えた雑感","tags":["JavaScript","Gatsby","Middleman"]}}}},
    "staticQueryHashes": ["2585454260","2954598359"]}