kriasoft / react-starter-kit

The web's most popular Jamstack front-end template (boilerplate) for building web applications with React
https://reactstarter.com
MIT License
22.75k stars 4.16k forks source link

Environment variables in config file are ugly, how about use node-config? #1240

Closed Stupidism closed 3 years ago

Stupidism commented 7 years ago

https://github.com/lorenwest/node-config

I've successfully done it in my own project. Mainly benifits dev operators

langpavel commented 7 years ago

I'm not sure that this should be included in RSK. I'm using dotenv with minimal changes in code for development.

Stupidism commented 7 years ago

image Environment config files, local config file will be like this. It's very easy to override and cutomize.

Stupidism commented 7 years ago

image Environment variables are easy to customize, too.

Stupidism commented 7 years ago

Also, it will throw an error if some necessary config is undefined. For example, you can set some simple auth.jwt.secret only in development env and leave it blank in production env. When config.get('auth.jwt.secret') is called in production env and the dev operator didn't set the environment vairable, an error will be thrown. @langpavel

koistya commented 7 years ago

@Stupidism many developers use RSK just for front-end (React+server-side rendering), there is no much environment variables, just API_URL, GOOGLE_TRACKING_ID etc. I would rather have dotenv integrated as @langpavel suggested, in order to be able to override these env variables (e.g. being able to test the front-end either with a local API http://localhost:8080/graphql or a remote one, e.g. https://reactstarter.com/graphql).

Stupidism commented 7 years ago

@koistya Can dotenv be used in frontend? I thought dotenv and node-config both only work on server side.

I used environment variables because I used the server of RSK as a api-proxy gateway, too. And for our dev oprator, it's a save to have different config files for different deploy environments(develop, release, production).

langpavel commented 7 years ago

@Stupidism There is no library which can work on frontend as for dynamic configuration..Do you have an idea how it should work? You must pass your config to client from server yourself.. it is just a part of state..

Stupidism commented 7 years ago

@langpavel Agreed, I misunderstood @koistya 's words

many developers use RSK just for front-end

langpavel commented 7 years ago

BTW integrating dotenv is easy and clean and library itself is few bytes.

Stupidism commented 7 years ago

@langpavel Agreed, here's the trade-off:

Current code

  1. environment variables in code are implicit, someone may even use them in application code.
  2. default values and overrides are not clear
  3. can't handle related config variables decently
  4. determined when server is started
  5. hard to require some env_variables
  6. hard to handle local env_variables
    
    // config.js
    const port = process.env.PORT || 3000;
    const host = process.env.HOST || 'localhost';

if (process.env.NODE_ENV === 'production' && !process.env.JWT_SECRET) { throw new Error('JWT_SECRET is required in production!'); }

module.exports = { // Node.js app port, host, exampleUrl: process.env.EXAMPLE_URL || `${host}:${port}, auth: { jwt: { secret: process.env.JWT_SECRET || 'React Starter Kit' }, } };

// usage import { exampleUrl } from '../config';


Use node-config:

// config/default.js const defer = require('config/defer').deferConfig;

module.exports = { port: 3000, host: 'localhost', exampleUrl: defer(cfg => `${cfg.host}:${cf.gport}), auth: { jwt: undefined, } };

// config/development.js module.exports = { // avoid port conflict port: 3009, auth: { jwt: 'React Starter Kit', } };

// .gitignore src/config/local

// config/local.js module.exports = { exampleUrl: 'What ever I want. Won\'t affect the repo.' };

// config/custom-environment-variables.js module.exports = { host: 'HOST', port: 'PORT', exampleUrl: 'EXAMPLE_URL',

auth: { jwt: 'JWT_SECRET', }, };

// usage1 import config from 'config';

// will throw error in production-env config.get('auth.jwt.secret');

// usage2 process.env.exampleUrl = 'Change in runtime'; const config = require('config');

ulani commented 3 years ago

@Stupidism thank you very much for crating this issue! Unfortunately, we have close it due to inactivity. Feel free to re-open it or join our Discord channel for discussion.

NOTE: The main branch has been updated with React Starter Kit v2, using JAM-style architecture.