Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an angularjs application 12 factor compliant regarding configuration

I'm trying to make an angularjs app 12 factor compliant regarding config (http://12factor.net/config).

It should depend on the environment and I should not see the words development, test, production, etc. in the code.

Variables could be stored in bash env for example. I could pass them to a webserver.

I already thought of an .erb template file to erb config.js.erb > config.js, but if I change a variable while the application is running I'd have to redo this.

I already found this article http://mindthecode.com/how-to-use-environment-variables-in-your-angular-application/

But it's a big lie and Grunt.js to do this, really... Anyway.

I know 12factor philosophy wasn't made for frontend application but my angular application could be deployed in many different servers across many environment and it won't harm anyone to try to do things properly :).

Thanks !

Edit:

The config parameters I'd like to use would be some stuff like :

app:
   api:
       url: "The url of the api server"
       port: 8080
   cdn:
       images: "url of my images caching service"
   google:
       oauth:
           "api_key": "The api key used for that deployment"
   #other external frontend services

Other Edit:

This guy kinda went with an answer : http://bahmutov.calepin.co/inject-valid-constants-into-angular.html which I find kind of ugly and totally bound to angularjs; but it works !

like image 487
Azr Avatar asked May 30 '14 10:05

Azr


1 Answers

Here is the solution I found, it's totally bound to angularjs but it works for me on Heroku and it's very simple. I just append my conf module to the generated code.

Everytime I restart the app a new version of the code is copied therefore the Append only happens once.

The Append just redefines an already existing configuration variable. If someone find something more 'classy' I'd be happy to put it as the right solution !

var compression = require('compression');
var express = require('express');
var logfmt = require('logfmt');
var stdio = require('stdio');
var glob = require("glob");
var fs = require('fs');

// ------------------------
// Read config from args
var ops = stdio.getopt({
  'url': {
    key: 'u',
    args: 1,
    default: '',
    description: 'Url of api server'
  },
  'port': {
    key: 'p',
    args: 1,
    default: 5000,
    description: 'Port on which to listen'
  }
});


var port = ops.port || process.env.PORT;
ops.port = undefined;

// ------------------------
// Append config to js built file

var codeToAppend = 'angular.module("project.config",[]).constant("ApiConfig",' + JSON.stringify(ops) + ');';

glob(__dirname + '/dist/scripts/scripts.*.js', function(er, files) {
  fs.appendFile(files[0], codeToAppend, function(err) {
    if (err) {
      throw err;
    }
    console.log('The "conf code" was appended to file!');
  });
});

// ------------------------
// Start App :3

var app = express();

app.use(logfmt.requestLogger());
app.use(compression({
  threshold: 512
}));
app.use(express.static(__dirname + '/dist'));

app.get('/config', function(req, res) {
  res.json(ops);
});

app.listen(port);
like image 139
Azr Avatar answered Oct 18 '22 20:10

Azr