Node.jsでの環境変数の操作

February 10, 2022
執筆者
レビュー担当者

数行のコードだけで、Node.jsアプリケーションをターミナルから直接実行し、Twilioを使用してTwilio Programmable SMSでテキストメッセージを送受信できます。

Node.jsの環境変数の基本

Node.jsは、Rails以降で、Web開発コミュニティで最も話題のフレームワークです。Node.jsはまだ歴史は非常に若いものの、高速で拡張性が高く効率的であることが実証されています。この理由は、イベント駆動型のノンブロッキング入出力構造です。

Twilioと組み合わせることにより、テレフォニーアプリケーションを簡単に構築できます。ただし、例えばSMSを送信する場合は、Node.jsモジュールとTwilio Node.jsモジュールをインストールする必要があります。

Node.js言語(およびそのモジュール)のもう1つの優れた機能は、環境変数を操作する方法があることです。環境変数は、多くのクラウドホスト(Heroku、Azure、AWS、Now.shなど)で使用されます。これにより、Node.jsアプリケーションのさまざまな側面を設定する方法がいくつか可能になります。ホストでサーバーがリッスンするポートを指定するPORT変数を設定している場合でも、モジュールではNODE_ENV変数の値に応じて異なる動作(ロギングなど)をする場合があります。

このブログでは、Node.jsで環境変数を操作する際のいくつかのテクニックとツールを確認します。

最初に、Node.js環境があることを確認する必要があります。次に、MacでTwilioを使用するためのNode.jsの設定の基本について説明します。これには、Macにnpmをインストールし、Twilioプロジェクトの環境準備を整えることが含まれます。

Node.jsがインストールされているかどうかを確認する方法

ターミナルを開き、以下を実行すると、マシンにNode.jsがすでにインストールされているかを確認できます。

node -v

Node.jsがインストールされていない場合は、次の手順でNode.jsをインストールします。

  1. Node.jsダウンロードページに移動します。
  2. Macintoshインストーラーのオプションをクリックし、macOS用Node.jsをダウンロードします。
  3. ダウンロードしたNode.js.pkgインストーラーを実行します。
  4. インストーラーを実行し、ライセンスの同意、インストール先の選択、インストールの認証を実行します。

インストーラーが完了したら、ターミナルでNode.jsが「node -v」で実行されることを確認します。上記のように、現在のバージョン番号が表示されているはずです。

インストールされたNode.jsバージョンが表示されない場合は、ターミナルの再起動が必要になる場合があります。

インストールが正しく実行され、「npm -v」を実行できることを確認するには、バージョンを通してインストールを確認します。

これで、Twilioモジュールをインストールし、現在のディレクトリのNode.jsスクリプトがモジュールを使用できるようにMac環境が整いました。

.envファイルからの明示的な変数の読み込み 

Node.jsの環境変数にはすぐにアクセスできます。Node.jsプロセスが起動すると、プロセスグローバルオブジェクト内にenvオブジェクトが作成され、既存のすべての環境変数へのアクセスが自動的に提供されます。 

オブジェクトを確認する場合は、コマンドラインに「node」と入力してNode.js REPLをで実行し、以下を入力します。

console.log(process.env);

このコードは、このNode.jsプロセスが取得できるすべての環境変数を出力します。1つの特定の変数にアクセスするには、オブジェクトの任意のプロパティと同様にしてアクセスします。

console.log('The value of PORT is:', process.env.PORT);

ここでは、PORTの値がコンピューター上で定義されていないことがわかります。しかし、HerokuやAzureなどのクラウドホストでは、このPORT変数を使用し、ルーティングが正常に動作するようにサーバーが待機するポートを指定します。したがって、次回Webサーバーを設定するときに、PORTを最初にチェックしてその後でデフォルト値を指定することにより、待機するポートを決定できます。

const app = require('http').createServer((req, res) => res.send('Ahoy!'));
const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

強調表示された行は、PORTの値が使用可能な場合はその値を使用し、使用できない場合はデフォルトで3000をフォールバックポートとしてリッスンします。ファイルserver.jsにコードを保存し、以下のように記述してコードを実行してみます。

node server.js

出力は、「Server is listening on port 3000」というメッセージになります。Ctrl+Cでサーバーを停止し、以下のコマンドで再起動します。

PORT=9999 node server.js

これで、「Server is listening on port 9999」というメッセージが表示されます。これは、この実行ではノードの前にPORT変数がPORT=9999に一時的に設定されたことを意味します。 

process.envは通常のオブジェクトなので、値を設定/上書きできます。

process.env.MY_VARIABLE = 'ahoy';

上記のコードは、MY_VARIABLEの値を設定または上書きします。ただし、この値はこのNode.jsプロセスの実行時にのみ設定され、このプロセスによって生成された子プロセスでのみ使用可能であることに注意してください。全体として、環境変数のオーバーライドはできるだけ避ける必要があります。PORTの例に示すように、設定変数を初期化するだけにしてください。

1台のコンピューター上で複数のNode.jsプロジェクトを開発する場合は、環境変数名が重複している可能性があります。例えば、異なるメッセージングアプリケーションには異なるTwilio Messaging Service SIDが必要な場合がありますが、両方ともTWILIO_MESSAGE_SERVICE_SIDと呼ばれることになります。プロジェクト固有の構成を実現するには、.envファイルを使用するのが最適です。これらのファイルを使用すると、さまざまな環境変数と関連する値を指定できます。

通常は、これらのファイルをソース管理にチェックインしません。作成する場合は、.gitignoreファイルに.envを追加します。多くのTwilioデモアプリケーションの.env.exampleファイルを使用して、.envファイルにコピーして自分で値を設定できます。プロジェクト内の他のユーザーとテンプレートファイルを共有する場合は、.env.exampleまたは同様のファイルを持つことが一般的な方法です。

このファイルから値を読み込むにはどうすればよいでしょうか。最も迅速な方法は、dotenvというnpmモジュールを使用することです。npm経由でモジュールをインストールします。

npm install dotenv --save

その後、エントリファイルの先頭に次の行を追加します。

require('dotenv').config();

このコードでは、プロジェクトのルートに.envファイルが自動的に読み込まれ、値が初期化され、すでにプリセットされている変数はスキップされます。ただし、本番環境で.envファイルを使用しないように注意してください。代わりに、値をそれぞれのホストに直接設定します。そこで、以下のように読み込みのステートメントをifステートメントで囲むことができます。

if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config();
}

このコードでは、サーバーがまだ本番モードになっていない場合にのみ.envファイルを読み込みます。

実際の動作を見てみましょう。上記のように、dotenvをディレクトリにインストールします。次に、同じディレクトリにdotenv-example.jsファイルを作成し、以下の行を配置します。

console.log('No value for FOO yet:', process.env.FOO);

if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config();
}

console.log('Now the value for FOO is:', process.env.FOO);

その後、同じディレクトリに、以下の内容を含む.envファイルを作成します。

FOO=bar

スクリプトを実行します。

node dotenv-example.js

出力は次のようになります。

No value for FOO yet: undefined
Now the value for FOO is: bar

ご覧のように、値はdotenvを使用して読み込まれ、定義されています。NODE_ENVをproductionに設定して同じコマンドを再実行すると、未定義のままになります。

NODE_ENV=production node dotenv-example.js

出力は次のようになります。

No value for FOO yet: undefined
Now the value for FOO is: undefined

実際のコードを変更しない場合は、スクリプトの実行時にNodeの-r引数を使用してdotenvを読み込むこともできます。これを行うには、dotenv-example.jsファイルを以下のように変更します。

console.log('The value for FOO is:', process.env.FOO);

次に、通常どおりにファイルを実行します。

node dotenv-example.js

スクリプトの出力は、FOOの現在の値がundefinedとなります。次に、dotenvを要求するフラグを付けて実行します。

node -r dotenv/config dotenv-example.js

結果は、.envファイルが読み込まれているためFOObarに設定されます。dotenvの詳細については、そのドキュメントをご覧ください。

.envファイルを読み込む別の方法

環境変数の読み込みをより便利にするための、dotenvをベースとした別のモジュールもあります。それがnode-env-runまたはnodenvです。このコマンドラインツールは、.envファイルを読み込み、dotenvを使用して値を初期化し、スクリプトを実行します。

グローバルにインストールできますが、これは開発目的でのみ、プロジェクトにローカルにインストールすることをお勧めします。次のコマンドを実行してインストールします。

npm install node-env-run --save-dev

その後、ファイルnodenv-example.jsを作成し、以下のコードをファイルに配置します。

console.log('The value for FOO is:', process.env.FOO);

ご覧のように、ここではアプリケーションロジックだけであるため、何も要求する必要はありません。実行するには、以下のようにnodeを使用します。

node nodenv-example.js

この実行されたコードからは、「The value for FOO is: undefined」と出力されます。次に、以下を実行してnode-env-runを使用します。

node_modules/.bin/nodenv nodenv-example.js

結果は「The value for FOO is: bar」になります。これは、.envファイルが読み込まれたためです。

node-env-runを使用すると、これらの既存の値を上書きできます。動作を確認するには、まず次のコマンドを実行します。

FOO=foo node_modules/.bin/nodenv nodenv-example.js

コマンドラインの出力では、「The value for FOO is: foo」と表示されます。強制モードを有効にすると、既存の値を上書きできます。

FOO=foo node_modules/.bin/nodenv --force nodenv.js

その結果、「The value for FOO is: bar」という元の結果に戻ります。

このツールを定期的に使用する場合は、以下のようにpackage.jsonに追加してnpmスクリプトにラップすることをお勧めします。

{
  "name": "twilio-blog",
  "version": "1.0.0",
  "description": "",
  "main": "nodenv-example.js",
  "scripts": {
    "start": "node .",
    "start:dev": "nodenv -f ."
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "node-env-run": "^2.0.1"
  }
}

このようにして、以下を実行できます。

npm run start:dev

node-env-runの詳細については、そのドキュメントをご覧ください。

環境変数とnpmスクリプト

npmスクリプトでNode.jsアプリケーションを入力する前に環境変数の値を確認すると便利な場合もあります。例えば、開発環境ではnode-env-runを使用し、本番モードではnodeを使用する場合などです。この場合はif-envツールを使用します。次のコマンドを実行してインストールします。

npm install if-env --save

ただし、本番環境でも必要になるため、これを「dev dependency」としてインストールしないようにしてください。

次に、package.jsonでnpmスクリプトを変更します。

 "scripts": {
    "start": "if-env NODE_ENV=production ?? npm run start:prod || npm run start:dev",
    "start:dev": "nodenv -f .",
    "start:prod": "node ."
  }

このスクリプトは、npm run start:prodを実行し、その後nodeを実行します。NODE_ENVの値がproductionの場合、npm run start:devを実行し、その後nodenv -fを実行できます。これは、その他のどの環境変数でも実行できます。

次のコマンドを実行して試してください。

# should output "The value of FOO is: bar"
npm start
# should output "The value of FOO is: undefined"
NODE_ENV=production npm start

if-envの詳細については、そのドキュメントをご覧ください。

Macにnpmをインストールする方法

通常、これは上記のインストールの一部として自動的にインストールされます。これは、ターミナルでnpmコマンドを実行して確認できます。インストールされている場合は、使用方法の一覧が表示されます。インストールされていない場合は、以下を実行します。

sudo apt install npm

Node.jsでのデバッグ

次はデバッグについてです。多くのことを解決するのに役立つ1つの戦略は、DEBUG環境変数を使用して、多数のモジュールのより詳細なログを受信することです。例えば、次のような基本的なexpressサーバーを使用します。

const app = require('express')();
const bodyParser = require('body-parser');
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

app.post('/', (req, res, next) => {
console.log(req);
});

app.listen(3000);

DEBUG変数を*に設定して起動します。

DEBUG=* node server.js

次のような詳細なログが表示されます。

その背後にある仕掛けはdebugと呼ばれる軽量モジュールです。使用するには、名前空間を使用して初期化するだけです。その後、その名前空間にログを記録できます。他の場所で出力を確認する必要がある場合は、DEBUG変数でその名前空間を有効にするだけです。この場合、expressは一連のサブ名前空間を使用します。そのため、expressルーターからすべてを取得する場合は、適切なワイルドカードを使用してDEBUGを設定するだけで済みます。

DEBUG=express:router* node server.js

モジュールでdebugを使用する場合は、まずモジュールをインストールする必要があります。

npm install debug --save

その後、次の方法で適用します。

const debug = require('debug')('myApp:someComponent');

debug('Here is a pretty object %o', { someObject: true });

debugの詳細については、そのドキュメントをご覧ください。

Node.jsのすべてのNode.js環境変数をTwilioで使用する

これらは、環境変数と存在するすべてのツールで実行できることの一部にすぎません。Node.jsの環境変数について少し詳しく学習したので、SMSクイックスタートを含むTwilioのNode.jsクイックスタートをお試しください。無料で開始できます。