Node.jsで開発をしていると、APIキーやデータベースの認証情報などをソースコードに直接書いてしまいそうになることがあります。
しかし、そのままの状態でGitHubに公開してしまうと、外部に機密情報が流出してしまい大きなトラブルに発展する危険性があります。
そこで役立つのがdotenvというライブラリです。
この記事では『dotenv』について、以下の内容をサンプルコードを用いてわかりやすく解説します。
- dotenvとは?
.env
ファイルの例- 環境変数を直接書かない理由
- dotenvの使い方
- dotenvを使うときの注意点
.env
ファイルの書き方ルールdotenv.config()
の返り値- dotenvで既存の環境変数を上書きする方法
- dotenvで複数環境で切り替える方法
dotenvとは?
dotenv(ドットエンブ)は、Node.jsでよく利用される便利なライブラリのひとつです。このライブラリを使うことで、.env
という専用の外部ファイルに環境変数をまとめて記述し、それをプログラムの中から簡単に読み込めるようになります。
Webアプリケーションやシステムを開発するときには、「開発環境」「テスト環境」「本番環境」など、環境ごとに異なる設定値を切り替える必要があります。具体的には次のような値です。
- APIキー(外部サービスと連携するための秘密のキー)
- データベースの接続先(ホスト名やユーザー名、パスワードなど)
- サーバーが動作するポート番号
- AWS、Stripe、Firebaseなどの外部サービスの認証情報
これらをソースコードに直接書き込んでしまうと、セキュリティ上のリスク(GitHubに誤って公開してしまうなど)が高くなるだけでなく、環境ごとにコードを書き換える手間も発生してしまいます。そこで、dotenvを使って外部ファイルに設定値を切り出しておくと、ソースコードを汚さず安全・便利に管理できます。
.envファイルの例
例えば、次のような.env
ファイルを用意したとします。
# .env
PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASS=secret
このファイルには、アプリを動かすために必要な設定値(ポート番号やデータベースの接続情報など)が環境変数という形で保存されています。dotenvを利用すると、この.env
ファイルに書かれた値は自動的にprocess.env
オブジェクトに展開されます。つまり、プログラム内では次のように呼び出せるようになります。
console.log(process.env.PORT); // 3000
console.log(process.env.DB_HOST); // localhost
console.log(process.env.DB_USER); // root
console.log(process.env.DB_PASS); // secret
このようにprocess.env.変数名
で簡単にアクセスできるため、環境ごとに設定を切り替える作業がとても楽になります。例えば、開発環境ではローカルのデータベース、本番環境ではクラウド上のデータベースを使用する、といった切り替えを.env
ファイルの入れ替えだけで行うことが可能です。
要するに、dotenvを利用すれば、アプリの設定を「従来どおり環境変数を直接渡す方法」と「.env
ファイルで環境変数を直接渡す方法」のどちらでも使えるようになるのです。
従来どおり環境変数を直接渡す方法
.env
を使わずに従来の方法で環境変数を設定することもできます。LinuxやmacOSのターミナルでは、以下のように入力すれば、環境変数を設定できます。
export PORT=3000
export DB_HOST=localhost
export DB_USER=root
export DB_PASS=secret
このように設定してからNode.jsアプリを起動すれば、プログラム内でprocess.env.PORT
などを通じて環境変数の値を参照できます。
環境変数を直接書かない理由
環境変数をコードの中に直接書いてしまえば一見手っ取り早いように思えますが、環境変数を外部ファイル(.env
)に分離するのには以下のメリットがあります。
- セキュリティ面
- もしAPIキーや認証情報をソースコードに直書きしてしまうと、そのコードを誤ってGitHubなどに公開した瞬間に機密情報が漏洩する危険があります。
.env
ファイルに分離すれば、ソースコードと一緒に公開されることはなく、安全に管理できます。
- もしAPIキーや認証情報をソースコードに直書きしてしまうと、そのコードを誤ってGitHubなどに公開した瞬間に機密情報が漏洩する危険があります。
- 可搬性(環境ごとの切り替えが簡単)
- 開発環境と本番環境では設定が異なります。
- 例えばデータベースの接続先は次のように変わります。
- 開発環境 →
DB_HOST=localhost
- 本番環境 →
DB_HOST=prod-db.example.com
- 開発環境 →
.env
ファイルを切り替えるだけで済むので、同じコードをそのまま使い回せるのが大きな利点です。
- 保守性
- 設定値を一か所(
.env
)にまとめておけるので、後から修正や見直しをするときも楽になります。もしコードのあちこちに設定値を書いていたら、修正漏れやミスにつながりやすいですが、.env
にまとめておけばその心配が減ります。
- 設定値を一か所(
dotenvの使い方
では、これからdotenvの使い方について解説します。
dotenvをインストールする
dotenvはNode.jsのライブラリなので、まずはプロジェクトに追加します。プロジェクト配下で以下のコマンドを実行してインストールしましょう。
# npm を使う場合
npm install dotenv
# yarn を使う場合
yarn add dotenv
.envファイルを作成する
次に、プロジェクトのルートディレクトリに.env
という名前のファイルを作ります。ここに環境変数を書いていきます。
# .env
PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASS=secret
プログラムで環境変数を使用する
最後にdotenvを使って.env
を読み込みます。読み込み方法は「require
を使うCommonJS方式」と「import
を使うESM方式」の2種類があります。自分のプロジェクトの記法に合わせて選択してください。
// CommonJS(requireを使う場合)
require("dotenv").config();
console.log(process.env.PORT); // 3000
console.log(process.env.DB_USER); // root
// ESM(importを使う場合)
import dotenv from "dotenv";
// .env を読み込む
dotenv.config();
console.log(process.env.PORT); // 3000
console.log(process.env.DB_USER); // root
dotenvを使うときの注意点
.env
ファイルは必ず.gitignore
に追加してください。誤って公開リポジトリにアップロードすると、APIキーや外部サービスの認証情報などが流出して大変なことになります。
# .gitignore
.env
チーム開発では、.env
を共有する代わりに、変数名だけを書いた雛形ファイル(.env.example
など)を共有すると便利です。
# .env.example
PORT=
DB_HOST=
DB_USER=
DB_PASS=
これを見れば、他の開発者が「どんな環境変数が必要なのか」がわかります。
.envファイルの書き方ルール
.env
ファイルには以下のルールがあります。
空行は無視される
何も書いていない行は読み込まれません。そのため、見やすさのために区切りとして空行を入れても大丈夫です。
# .env
PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASS=secret
#で始まる行はコメント
#
で始めた行はコメント扱いになります。
# これはコメント
PORT=3000
値にスペースを含んでもOK
値の中にスペースがあっても、そのまま読み込まれます。クォーテーションで囲んでも囲まなくてもOKです。
KEY1=AAA BBB CCC
KEY2="AAA BBB CCC"
KEY3='AAA BBB CCC'
値を省略すると空文字になる
値を書かずに終わると、空文字として扱われます。
KEY1=
読み込むと{ KEY1: '' }
になります。
キーや値の前後の空白は削除される
=
の前後に空白を入れても、自動で削除されます。
KEY1 = AAA
実際にはAAA
として読み込まれます。空白を残したい場合はクォーテーションで囲む必要があります。
KEY2=" AAA "
KEY3=' AAA '
文字コードはUTF-8で保存する
通常はUTF-8で保存しておけば問題ありません。もし他の文字コードを使いたい場合は、config
のオプションで指定できます。
require("dotenv").config({ encoding: "latin1" });
dotenv.config()の返り値
dotenv.config()
を呼び出すと、返り値として結果オブジェクトが返ってきます。このオブジェクトには.parsed
プロパティがあり、.env
ファイルに書かれた内容をキーと値のオブジェクトとして参照できます。
import dotenv from "dotenv";
const result = dotenv.config();
console.log(result.parsed);
実行結果
{
PORT: '3000',
DB_HOST: 'localhost',
DB_USER: 'root',
DB_PASS: 'secret'
}
config()
は{ parsed: {...} }
や{ error: Error }
を返します。
「.envの中身が空の場合」と「.env自体が無い場合」
.env
の中身が空の場合result.parsed
は
になります。{}
(空オブジェクト)result.error
はundefined
になります。
.env
自体が無い場合result.parsed
は
になります。{}
(空オブジェクト)result.error
は
になります。Error オブジェクト
.env
自体が無い場合、result.error
は以下のようになります。
Error: ENOENT: no such file or directory, open 'C:\Users\user01\test\.env'
at Object.readFileSync (node:fs:441:20)
at ...
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'C:\\Users\\user01\\test\\.env'
}
dotenvで既存の環境変数を上書きする方法
override
オプションは、既にPCに設定されている環境変数を.env
の値で上書きするかどうかを決めます。デフォルトはfalse
なので、既にPCに設定されている環境変数が優先されます。
override: false
(デフォルト) → 既にPCに設定されている環境変数を使うoverride: true
→.env
に書かれた値で上書きする
import dotenv from "dotenv";
dotenv.config({ override: true });
これで、PCに設定済みの環境変数も.env
の値で強制的に上書きされます。
dotenvで複数環境で切り替える方法
実際のプロジェクトでは、以下のように環境ごとに設定を分けたいことが多いです。
.env.development
→ 開発用.env.production
→ 本番用.env.test
→ テスト用
通常のdotenv.config()
では.env
が読み込まれますが、path
オプションを指定すれば別ファイルを読み込むことができます。
import dotenv from "dotenv";
// NODE_ENV の値に応じて.envファイルを切り替える
const envFile =
process.env.NODE_ENV === "production"
? ".env.production"
: ".env.development";
dotenv.config({ path: envFile });
console.log("DB_HOST:", process.env.DB_HOST);
- 開発時:
NODE_ENV=development
→.env.development
を読み込む - 本番時:
NODE_ENV=production
→.env.production
を読み込む
このようにすれば、環境変数の切り替えを自動化できます。
本記事のまとめ
この記事では『dotenv』について、以下の内容を説明しました。
- dotenvとは?
.env
ファイルの例- 環境変数を直接書かない理由
- dotenvの使い方
- dotenvを使うときの注意点
.env
ファイルの書き方ルールdotenv.config()
の返り値- dotenvで既存の環境変数を上書きする方法
- dotenvで複数環境で切り替える方法
APIキーやデータベースの接続情報などをソースコードに直書きしてしまうのは非常に危険ですが、dotenvを使えば安全かつ便利に管理できます。また、開発環境・テスト環境・本番環境といった複数の環境でも、.env
ファイルを切り替えるだけで簡単に設定を反映できるため、チーム開発や本番運用でも大いに役立ちます。ぜひあなたのプロジェクトでも、dotenvを導入して安全で効率的な開発環境を整えてみてください。
お読み頂きありがとうございました。
dotenvについて、さらに詳しく知りたい方は、以下の公式のGitHubリポジトリ等をご覧ください。