添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
纯真的冲锋衣  ·  npm: ...·  4 月前    · 
面冷心慈的熊猫  ·  请问,用 Electron ...·  2 月前    · 
含蓄的领带  ·  我也写了一个creator to ...·  2 月前    · 
一身肌肉的杯子  ·  Node 接口 | webpack ...·  1 月前    · 
温文尔雅的烤面包  ·  Android Room - ...·  1 年前    · 
叛逆的警车  ·  WPF ...·  2 年前    · 
胡子拉碴的课本  ·  mac 安装 sass-掘金·  2 年前    · 

dotenvの GitHub リポジトリ ーは、こちら。

GitHub - joho/godotenv: A Go port of Ruby's dotenv library (Loads environment variables from .env files)

dotenvをベースにしているdotenv-vaultというプロダクトのWebサイトを見ると、

Simplify Your Secrets | Dotenv

dotenvはNode.js以外にも存在しているようです。

  • GitHub - joho/godotenv: A Go port of Ruby's dotenv library (Loads environment variables from .env files)
  • Kotlin
  • GitHub - cdimascio/dotenv-kotlin: 🗝️ Dotenv is a module that loads environment variables from a .env file
  • Node.js
  • Simplify Your Secrets | Dotenv
  • GitHub - vlucas/phpdotenv: Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.
  • Python
  • GitHub - theskumar/python-dotenv: Reads key-value pairs from a .env file and can set them as environment variables. It helps in developing applications following the 12-factor principles.
  • GitHub - bkeepers/dotenv: A Ruby gem to load environment variables from `.env`.
  • オプションを コマンドライン 引数で指定したり

    $ node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env dotenv_config_debug=true

    環境変数 で指定することもできるようです。

    $ DOTENV_CONFIG_<OPTION>=value node -r dotenv/config your_script.js
    $ DOTENV_CONFIG_ENCODING=latin1 DOTENV_CONFIG_DEBUG=true node -r dotenv/config your_script.js dotenv_config_path=/custom/path/to/.env

    とりあえず、試していってみることにしましょう。

    今回の環境は、こちら。

    $ node --version
    v18.16.1
    $ npm --version
    9.5.1

    dotenvを使ってみる

    では、dotenvを使ってみましょう。

    Node.jsプロジェクトを作成。

    $ npm init -y
    $ npm i -D prettier

    Prettierも入れています。

      "devDependencies": {
        "prettier": "^2.8.8"
    

    .prettierrc.json

    "singleQuote": true, "printWidth": 120

    とりあえず、環境変数を標準出力に書き出すJavaScriptを書いてみます。

    print-env.js

    console.log(`get env: MY_ENV_VAR = ${process.env.MY_ENV_VAR}`);
    
    $ node print-env.js
    get env: MY_ENV_VAR = undefined

    この状態だと環境変数を設定していないので当然undefinedです。

    環境変数を設定すれば当然ながら参照します。

    $ MY_ENV_VAR=Hello node print-env.js
    get env: MY_ENV_VAR = Hello

    これでもいいのですが、環境変数が複数あったり使用する値を切り替えたかったりすると煩雑になってきますね。
    こういう時にdotenvを使うとよいのだろうと思います。

    というわけで、dotenvをインストール。

    $ npm i dotenv

    インストールされたdotenvのバージョン。

      "dependencies": {
        "dotenv": "^16.3.1"
    

    使い方としては、まずは.envというファイルを用意するようです。

    dotenv / Usage

    MY_ENV_VAR=Hello from dotenv

    次に、先ほどのJavaScriptファイルにdotenvのロードを追加します。

    print-env.js

    require('dotenv').config();
    console.log(`get env: MY_ENV_VAR = ${process.env.MY_ENV_VAR}`);
    

    これで実行すると、.envファイルに設定した内容を環境変数に追加してくれます。

    $ node print-env.js
    get env: MY_ENV_VAR = Hello from dotenv

    明示的な追加が必要なので、dotenvをロードしている部分をコメントアウトすると

    print-env.js

    // require('dotenv').config();
    console.log(`get env: MY_ENV_VAR = ${process.env.MY_ENV_VAR}`);
    

    .envファイルを読み込まなくなります。

    $ node print-env.js
    get env: MY_ENV_VAR = undefined

    個人的にはこの「ソースコードにdotenvの使用を明示的に追加する」という方法はちょっと嫌なので、
    Node.jsの--require-r)オプションを使ったプリロードの方が良いかなと思います。
    コンテナ環境とかだと、環境変数はコンテナ側の設定で行うことが多いと思いますし。

    dotenv / Preload

    こうすると、ソースコードにdotenvのロードを書かなくとも動作させることができます。

    $ node -r dotenv/config print-env.js
    get env: MY_ENV_VAR = Hello from dotenv

    ちなみに、.envファイルに書かれている環境変数がすでに存在した場合は、あらかじめ環境変数として定義されている値が優先される
    ようです。

    $ MY_ENV_VAR=Hello node -r dotenv/config print-env.js
    get env: MY_ENV_VAR = Hello

    読み込むファイルを切り替える

    dotenvはデフォルトで.envというファイルを読み込みますが、これを別のファイルに切り替えることができます。

    こんなファイルを用意。

    .env-other

    MY_ENV_VAR=Hello from dotenv other

    dotenvの設定は、コマンドラインオプションでdotenv_config_<option>=valueと指定するか、
    環境変数DOTENV_CONFIG_<OPTION>=valueで指定することができます。

    今回は環境変数を使いましょう。読み込むファイルを.env以外にするにはDOTENV_CONFIG_PATH環境変数を指定します。

    $ DOTENV_CONFIG_PATH=.env-other  node -r dotenv/config print-env.js
    get env: MY_ENV_VAR = Hello from dotenv other

    読み込むファイルが切り替わりました。

    コメントや複数行の環境変数を書く

    dotenvで読み込むファイルには、コメントを書いたり、環境変数を複数行で定義できたりします。

  • dotenv/ Multiline values
  • dotenv / Comments
  • 複数行の環境変数を定義するには、"または'で囲って複数行で書きます。コメントは#で書けばOKです。

    こんな感じですね。

    .env-multiple

    # これは、シンプルな環境変数定義です
    MY_ENV_VAR=Hello World!!
    # これは、複数行の環境変数定義です
    MY_ENV_MULTILINE_VAR="begin
    \"クォートは\でエスケープして記述\"
    

    読み込むソースコード

    print-env-multiple.js

    console.log(`get env: MY_ENV_VAR = ${process.env.MY_ENV_VAR}`);
    console.log();
    console.log(`get env: MY_ENV_MULTILINE_VAR = ${process.env.MY_ENV_MULTILINE_VAR}`);
    
    $ DOTENV_CONFIG_PATH=.env-multiple  node -r dotenv/config print-env-multiple.js
    get env: MY_ENV_VAR = Hello World!!
    get env: MY_ENV_MULTILINE_VAR = begin
    \"クォートは\でエスケープして記述\"
    

    OKですね。

    Jestと組み合わせる

    最後は、dotenvをJestを組み合わせて使ってみましょう。

    新しくNode.jsプロジェクトを作成。

    $ npm init -y
    $ npm i -D prettier
    $ npm i dotenv
    $ npm i -D jest

    依存関係は、こんな感じになりました。

      "devDependencies": {
        "jest": "^29.5.0",
        "prettier": "^2.8.8"
      "dependencies": {
        "dotenv": "^16.3.1"
    

    scriptsはこうしておきます。

      "scripts": {
        "format": "prettier  --write **/*.js",
        "test": "jest"
    

    .envファイルを用意。

    MY_ENV_VAR=Hello dotenv

    テストコード。

    use-dotenv.test.js

    test('use dotenv', () => {
      expect(process.env.MY_ENV_VAR).toBe('Hello dotenv');
    

    このテストはこのまま実行しても失敗します。

    $ npm run test
    > [email protected] test
     FAIL  ./use-dotenv.test.js
      ✕ use dotenv (4 ms)
      ● use dotenv
        expect(received).toBe(expected) // Object.is equality
        Expected: "Hello dotenv"
        Received: undefined
          1 | test('use dotenv', () => {
        > 2 |   expect(process.env.MY_ENV_VAR).toBe('Hello dotenv');
            |                                  ^
          3 | });
          at Object.toBe (use-dotenv.test.js:2:34)
    Test Suites: 1 failed, 1 total
    Tests:       1 failed, 1 total
    Snapshots:   0 total
    Time:        0.288 s, estimated 1 s
    Ran all test suites.

    こうすれば動作しますが、それもちょっと違う気がします…。

    use-dotenv.test.js

    require('dotenv').config();
    test('use dotenv', () => {
      expect(process.env.MY_ENV_VAR).toBe('Hello dotenv');
    

    どうしたらいいかですが、Jestの設定ファイルでsetupFilesというものを使えば良さそうです。

    Configuring Jest / setupFiles

    dotenvを使う分にはでもよさそうでしたが。

    Configuring Jest / setupFilesAfterEnv

    jest.config.js

    module.exports = {
      setupFiles: ['dotenv/config'],
      testEnvironment: 'node',
    

    これでdotenvが動作するようになります。

    $ npm run test
    > [email protected] test
     PASS  ./use-dotenv.test.js
      ✓ use dotenv (3 ms)
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        0.236 s, estimated 1 s
    Ran all test suites.

    別のファイルを読み込ませたい場合は

    .env-other

    MY_ENV_VAR=Hello dotenv other

    環境変数の指定をscriptsに含めればよいのかな、と。

      "scripts": {
        "format": "prettier  --write **/*.js",
        "test": "jest",
        "test-other": "DOTENV_CONFIG_PATH=.env-other jest"
    
    $ npm run test-other
    > [email protected] test-other
    > DOTENV_CONFIG_PATH=.env-other jest
     FAIL  ./use-dotenv.test.js
      ✕ use dotenv (4 ms)
      ● use dotenv
        expect(received).toBe(expected) // Object.is equality
        Expected: "Hello dotenv"
        Received: "Hello dotenv other"
          3 | test('use dotenv', () => {
        > 4 |   expect(process.env.MY_ENV_VAR).toBe('Hello dotenv');
            |                                  ^
          5 | });
          at Object.toBe (use-dotenv.test.js:4:34)
    Test Suites: 1 failed, 1 total
    Tests:       1 failed, 1 total
    Snapshots:   0 total
    Time:        0.251 s, estimated 1 s
    Ran all test suites.

    こんなところでしょうか。

    最後に少しdotenvのソースコードを眺めておきます。

    小さなライブラリーなので、中身を見るのもそう苦労しないでしょう。

    オプションを環境変数およびコマンドラインオプションから解決している部分。

    https://github.com/motdotla/dotenv/blob/v16.3.1/config.js

    https://github.com/motdotla/dotenv/blob/v16.3.1/lib/env-options.js

    https://github.com/motdotla/dotenv/blob/v16.3.1/lib/cli-options.js

    .envファイルのパース。

    https://github.com/motdotla/dotenv/blob/v16.3.1/lib/main.js#L12-L48

    Node.jsで環境変数をファイルから読み込むdotenvを試してみました。

    なんとなくこういうものがあるというのは知っていましたが、実際に使ったことはなかったので確認しておいてよかったです。
    他の言語にも同じようなものがあることもわかりましたし。