🕌

【Node.js】dotenv みたいな物を自作する

2022/01/06に公開

dotenv とは、ルートディレクトリに置いた .env ファイルを
require("dotenv").config() するだけで、
process.env.XXXXXX に環境変数が入る便利なやつである。

https://www.npmjs.com/package/dotenv

でも個人的には、JSON や YAML ファイルを使いたいし、
1行で複数の環境変数変えたりとか、そういうなんかカスタマイズがしたい。

というわけで自作することにした。

JSON で設定できる dotenv を作った

こんな感じになった。

env.js
const { spawn } = require("child_process");
const { readFileSync } = require("fs");

Object.entries(
  JSON.parse(readFileSync("./env.json", { encoding: "utf8" }))
).forEach(([key, value]) => {
  process.env[key] = value;
});
spawn(process.argv[2], { stdio: "inherit", shell: true });

使い方は、ルートディレクトリに以下のような JSON ファイルを作り・・・

{
  "ANDROID_SDK_ROOT": "C:\\Android\\Sdk",
}

node env "npm start" というように実行することにより、
環境変数が適用された状態でコマンドが実行される。

基本的に process.env を書き換えた状態で spawn 実行することで、
環境変数を維持したままコマンド実行できるっぽいので、わりと自由度が高そう。

YAML で設定できるようにしてみた

今度は env.yml で読み込めるようにして、以下のような docker ライクな書き方で
環境変数だけじゃなく、スクリプトのエイリアスまで書けるようにしてみた。
node env reset という具合に実行できる。

env.yaml
env:
  ANDROID_SDK_ROOT: C:\Android\Sdk
scripts:
  device:
    - cordova run android
  emulate:
    - cordova emulate android
  reset:
    - rimraf platforms
    - npm run install

ソースは以下のような感じ。

npm i yaml
env.js
const { spawn } = require("child_process");
const { readFileSync } = require("fs");
const { parse } = require("yaml");

const { env, scripts } = parse(readFileSync("./env.yml", { encoding: "utf8" }));
const exec = (commands) =>
  new Promise((resolve) => {
    spawn(command, { stdio: "inherit", shell: true }).on("exit", resolve);
  });

Object.entries(env).forEach(([key, value]) => {
  process.env[key] = value;
});
(async () => {
  for (let command of scripts[process.argv[2]]) {
    await exec(command);
  }
})();

このように結構いろいろできるので、dotenv も cross-env も
痒いところに手が届かないなーと思ったら、ぜひ自作してみよう。

Discussion