Skip to content

Instantly share code, notes, and snippets.

@idudinov
Created September 20, 2019 10:47
Show Gist options
  • Save idudinov/bc4c51d789cdbf8914d938ac1ba3133c to your computer and use it in GitHub Desktop.
Save idudinov/bc4c51d789cdbf8914d938ac1ba3133c to your computer and use it in GitHub Desktop.
Expo & webpack compatible Environment configuration
// Babel config that can be used in Expo
const appConfig = require('../config.js');
const envConfig = appConfig.generateVariables('.env', './package.json', true);
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
['transform-define', envConfig], // babel-plugin-transform-define
],
};
};
/*
Algorithm:
1. Read local .env file, if exists
2.
*/
const fs = require('fs');
const dotenv = require('dotenv');
/** @typedef {(import ('common/services/firebase').FirebaseConfig)} FirebaseConfig */
const DefaultEnvironment = 'development';
/** @type {{ [env: string]: FirebaseConfig}} */
const FirebaseConfigs = {
production: {
/* ... */
},
get staging() { return FirebaseConfigs.production; },
get development() { return FirebaseConfigs.staging; },
};
/** @type {{ [env: string]: FirebaseConfig}} */
const GoogleConfigs = {
production: {
/* ... */
},
get staging() { return GoogleConfigs.production; },
get development() { return GoogleConfigs.staging; },
};
// fill *required* env variables here. they might not exist, but should be listed anyway
const requiredEnv = {
APP_ENV: process.env.APP_ENV || process.env.NODE_ENV || DefaultEnvironment,
API_KEY: process.env.API_KEY,
};
function generateVariables(pathToEnv, pathToPackage, flat = false, stringify = false) {
const envResult = {};
let envLocal = {};
if (pathToEnv && fs.existsSync(pathToEnv)) {
envLocal = dotenv.parse(fs.readFileSync(pathToEnv));
}
// override envLocal with system env variables (only for known keys from requiredEnv)
Object.keys(requiredEnv).forEach(k => {
const v = requiredEnv[k] || envLocal[k];
if (v) {
envLocal[k] = v;
}
});
// generate correct keys for resulting envConfig, allowing to override with system values
Object.keys(envLocal).forEach(k => {
const resValue = process.env[k] || envLocal[k];
envResult[k] = (resValue && stringify)
? JSON.stringify(resValue)
: resValue;
});
const currentEnv = process.env.APP_ENV || envLocal['APP_ENV'];
const firebase = getConfig(FirebaseConfigs, currentEnv, stringify);
const google = getConfig(GoogleConfigs, currentEnv, stringify);
let appVersion = null;
if (pathToPackage) {
const pckg = require(pathToPackage);
appVersion = pckg.version;
if (appVersion && stringify) {
appVersion = JSON.stringify(appVersion);
}
}
if (flat) {
const flat = {};
Object.keys(envResult).forEach(k => {
flat[`process.env.${k}`] = envResult[k];
});
flat['process.firebase'] = firebase;
if (appVersion) {
flat['process.appVersion'] = appVersion;
}
return flat;
}
const result = {
env: envResult,
firebase: firebase,
google: google,
};
if (appVersion) {
result.appVersion = appVersion;
}
return result;
}
function getConfig(obj, environment, stringify = false) {
const env = environment || DefaultEnvironment;
const config = obj[env];
if (!config) {
throw new Error('Config not found for environment: ' + env);
}
return stringify
? JSON.stringify(config)
: config;
}
module.exports = {
generateVariables,
};
// Webpack config for web project
const webpack = require('webpack');
const appConfig = require('../config');
const envConfig = appConfig.generateVariables('.env', './package.json', true, true);
const definePlugin = new webpack.DefinePlugin(envConfig); // use it in plugins
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment