NodeJS: NODE_ENV dev || production

Taková ta uplná klasika: vyvíjíte aplikaci na svém stroji, kde máte samozřejmě úplně jinou konfiguraci, než na produkčním serveru, respektive také odlišnou od konfigurace kolegy, který se snaží psát pod Windejsi.
Tou jinou konfigirací může být cokoliv. Od propojení na externí služby až po způsob logování toho co a jak chcete vidět. Jasně že na developu vás zajíma víc věcí, které chcete na produkci vidět až když řešíte nějaký problém…

A řeči o tom, že byste měli kontejnerovat, dokrovat a tak vás taky nebaví. Nevidím jediný důvod, proč bych měl na svém lokále sestavovat nějaký dokr a pak spouštět virtuální stroj… WTF! Jediné co chci je spustit apku na mém mekovi prostě jinak nakonfigurovanou, ale funkčně pokud možná co nejvíc identickou s produkčním prostředím…

Dřív jsem rozdílnou konfiguraci do aplikace zaváděl skrze parametr příkazové řadky. Vstupní JS modul aplikace rozparsoval parametry příkazové řádky. Pokud našel parametr udávající soubor s konfigurací, pak se jej pokusil naimportovat. Pokud nic takové, pak natáhnul nějakou defaultní konfiguraci… Super. Funguje skvěle a umožnuje opravdu dobře nakonfigurovat kde co a to pokaždé úplně jinak. Prostě jak je libo…

Jenže jsem línější a línější a i tohle mi připadalo jako opruz. Je to přece jen nějaký kód navíc.. Já vím, že ne moc, ale je… Stačilo mi prostě něco lehčího.

NODE_ENV

A tak jsem se vrátil k NODE_ENV. Ne že bych o ní nevěděl, ale protože jsem vytvářel přece jen složitější struktury, mírně jsem podcenil možnosti této enviroment proměnné, a proto jí nějak moc rychle přeskočil. Chyba. NODE_ENV mi umožňuje dál lenošit a odpadl problém s konfigurací.

Jediné co jsem musel ořešit je jak NODE_ENV propašovat v různých způsobech spouštění, či využívání přímo do aplikace. Apku spouštím různě a nechtěl jsem se připravit o konfort kastomizovaných konfiguráků specifikovaných z příkazové řádky.

Základní implementace v package.json skrze sekci script:

{
    "scripts" : {
        "dev" : "NODE_ENV=dev nodemon index.js",
        "server": "nodemon index.js"
    }
}

Pokdud spouštíte apku z shellu, pak takto:

NODE_ENV=dev node index.js

No a pokud potřebujete NODE_ENV sdílet s dalšími nástroji, jako je gulp, nebo cokoliv jiného, pak:

export NODE_ENV='dev'
node index.js

Samotný JS kód se pak k proměnné prostředí dostane odkudkoliv skrze globální promenou process, která obsahuje celý ENV, včetně toho co sami nějak nadefinujete:

console.log(process.env.NODE_ENV);

Takže můj konfig dnes může vypadat i takto:

// Tohle je nejaka pokusna konfigurace...
'use strict';

const macConfig = {
    mode: process.env.NODE_ENV || 'dev',
    port: 8080,
};

const production = {
    mode: process.env.NODE_ENV || "production",
    port: 8080,
};

var exportConfig;
console.log(process.env.NODE_ENV);
switch (process.env.NODE_ENV) {
    case 'dev':
        exportConfig = macConfig;
        break;
    case 'production':
        exportConfig = production;
        break;
    default:
        exportConfig = macConfig;
}

module.exports = exportConfig;

//TEST: exportovana konfigurace
if (!module.parent) {
    console.log(JSON.stringify(exportConfig, null, 4));
}

Samozřejmě se i tohle dá napsát jinak, dle libosti… 🙂

Nicméně tohle je obecný přístup, kterým se dá do vaší apky propašovat jakákoliv proměnná z prostředí operačního systému…