[Edit]
+
0
-
0

Node.js - custom simple solution to read .env file

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
// --------------------------------------------------------- // index.js file: // --------------------------------------------------------- const {initializeVariables, ENV_PATH} = require('./env'); const ENV_CONSTANTS = exports.ENV_CONSTANTS = { __dirname: () => __dirname, // use it in `.env` file as %__dirname% __filename: () => __filename // use it in `.env` file as %__filename% }; initializeVariables(ENV_PATH, ENV_CONSTANTS); // ENV_CONSTANTS enables constant values injection (we can use e.g. VARIABLE_NAME=%CONSTANT_NAME%) console.log(process.env.BACKEND_PATH); console.log(process.env.FRONTEND_PATH); // Example output: // // /opt/my-website/backend // /opt/my-website/frontend // --------------------------------------------------------- // .env file: // --------------------------------------------------------- APPLICATION_PATH=%__dirname% BACKEND_PATH=$APPLICATION_PATH$/backend FRONTEND_PATH=$APPLICATION_PATH$/frontend // --------------------------------------------------------- // env.js file: // --------------------------------------------------------- const fs = require('fs'); const NEWLINE_EXPRESSION = /\r?\n/g; // Syntax: // // %NODE_CONSTANT_NAME% - constant defined in application source code // $LOCAL_VARIABLE_NAME$ - variable defined in `.env` file // *GLOBAL_VARIABLE_NAME* - variable defined in `process.env` object // const REFERENCE_EXPRESSION = /%%|%([^%*$]+)%|%|\*\*|\*([^%*$]+)\*|\*|\$\$|\$([^%*$]+)\$|\$/g; const ENV_PATH = exports.ENV_PATH = '.env'; const iterateVariables = exports.iterateVariables = (text, callback) => { const lines = text.split(NEWLINE_EXPRESSION); for (let i = 0; i < lines.length; ++i) { const line = lines[i]; if (line) { const index = line.indexOf('='); if (index !== -1) { const name = line.substring(0, index); if (name) { const value = line.substring(index + 1); callback(name, value, i); } } } } }; const readVariables = exports.readVariables = (path = ENV_PATH, constants = {}) => { const text = fs.readFileSync(path, 'utf-8'); const variables = []; const environment = process.env; iterateVariables(text, (name, value, index) => { const action = (match, group1, group2, group3) => { switch (match) { case '%': throw new Error(`Incorrect '%' character usage in 'name=${value}' line (line number: ${index + 1}).`); case '*': throw new Error(`Incorrect '*' character usage in 'name=${value}' line (line number: ${index + 1}).`); case '$': throw new Error(`Incorrect '$' character usage in 'name=${value}' line (line number: ${index + 1}).`); case '%%': return '%'; case '**': return '*'; case '$$': return '$'; default: switch (match[0]) { case '%': { const constant = constants[group1]; if (constant) { return constant(); } throw new Error(`Unknown '%${group1}%' environment constant.`); } case '*': { const variable = environment[group2]; if (variable == null) { // null or undefined throw new Error(`Unknown '%${group2}%' environment variable.`); } return variable; } case '$': { const variable = variables[group3]; if (variable == null) { // null or undefined throw new Error(`Unknown '$${group3}$' environment variable.`); } return variable; } default: throw new Error(`Unknown constant/variable type.`); } } }; variables[name] = value.replace(REFERENCE_EXPRESSION, action); }); return variables; }; const initializeVariables = exports.initializeVariables = (path = ENV_PATH, constants = null) => { const variables = readVariables(path, constants); const keys = Object.keys(variables); for (const key of keys) { process.env[key] = variables[key]; } };