🕌
【Node.js】dotenv みたいな物を自作する
dotenv とは、ルートディレクトリに置いた .env
ファイルを
require("dotenv").config()
するだけで、
process.env.XXXXXX
に環境変数が入る便利なやつである。
でも個人的には、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