const fs = require('fs'); const { resolve } = require('path'); const isDev = process.env.NODE_ENV !== 'production'; const parse = src => { const obj = {}; // convert Buffers before splitting into lines and processing src .toString() .split('\n') .forEach(line => { // matching "KEY' and 'VAL' in 'KEY=VAL' const keyValueArr = line.match(/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/); // matched? if (keyValueArr != null) { const key = keyValueArr[1]; // default undefined or missing values to empty string let value = keyValueArr[2] || ''; // expand newlines in quoted values const len = value ? value.length : 0; if ( len > 0 && value.charAt(0) === '"' && value.charAt(len - 1) === '"' ) { value = value.replace(/\\n/gm, '\n'); } // remove any surrounding quotes and extra spaces value = value.replace(/(^['"]|['"]$)/g, '').trim(); obj[key] = value; } }); return obj; }; const dotenvPath = [ resolve(process.cwd(), '.env'), isDev && resolve(process.cwd(), '.env.local'), ].filter(Boolean); const env = dotenvPath .filter(path => fs.existsSync(path)) .map(path => parse(fs.readFileSync(path))) .reduce((envObj, parsed) => Object.assign(envObj, parsed), {}); // eslint-disable-next-line array-callback-return Object.keys(env).map(key => { // eslint-disable-next-line no-prototype-builtins if (!process.env.hasOwnProperty(key)) process.env[key] = env[key]; });