Chargement dynamique d’environnements avec AngularJs

Afin de pouvoir automatiser le passage de l’environnement de développement à l’environnent déployé. J’ai utilisé quelques astuces afin de gagner du temps lors de la production de version.

La solution consiste à générer un fichier env.js contenant les variables de déploiement. C’est Grunt qui fera le travail de configuration.

Installation de grunt-ng-constant

npm install --save-dev

Ecriture des configurations

Dans un répertoire config, on placera le template. Ce template sera utilisé pour générer le fichier de configuration. Dans ce script on stockera les différentes variables dans comme variable d’environnements (window.__env).

/**** DO NOT MODIFY DIRECLTY - THIS FILE IS AUTO GENERATED ***/ 
'use strict'; 


(function (window) {
  window.__env = window.__env || {};

  {% constants.forEach(function (constant){ %}
  window.__env.{%- constant.name %}={%= constant.value %};
  {% }) %}

}(this));



Et les fichiers de configurations…

Pour le développement :

{
  "APIEndpoint": {
    "protocol": null,
    "host": null,
    "port": null
  }
}

Pour la production :

{
  "APIEndpoint": {
    "protocol": "http",
    "host": "api.host.fr",
    "port": 80
  }
}

Chargement de la configuration

Maintenant nous allons configurer notre module. En chargeant les variables d’environnement (window.__env) .

/**
 * Configuration for module.
 */
'use strict';

angular.module('MyModule')
   .constant('Config', {
    API: {
      useMocks: true,
      fakeDelay: 2000,
      protocol: window.__env.APIEndpoint.protocol || window.location.protocol
        .split(':')[0],
      host: window.__env.APIEndpoint.host || window.location.hostname,
      //port: String(window.location.port || 80),
      port: window.__env.APIEndpoint.port || 3000
    }
  });

On n’oubliera pas d’inclure le fichier env.js à nos scripts.

Script de production

On enregistre une tache ngConstant chargée de générer le fichier env.js

// Automatically load required Grunt tasks
  require('jit-grunt')(grunt, {
    useminPrepare: 'grunt-usemin',
    ngtemplates: 'grunt-angular-templates',
    cdnify: 'grunt-google-cdn',
    ngconstant: 'grunt-ng-constant'
  });

/* ... */ 

 ngconstant: {
      options: {
        // Name of our Angular module with configuration data.
        name: 'env',
        // Place where we need to create new file with our config module.
        dest: '<%= yeoman.app %>/scripts/env.js',
        // This object will be merged to all config files.
        constants: 'config/default.json',
        // Template to create config module.
        template: grunt.file.read('config/env-template.ejs')
      },
      // Environments
      development: {
        constants: 'config/development.json'
      },
      production: {
        constants: 'config/production.json'
      }
    }

/* ... */

  grunt.registerTask('build', function(target) {
    var ngconstantTask = 'ngconstant:development';

    if (target === 'production') {
      ngconstantTask = 'ngconstant:production';
    }

    grunt.task.run([
      ngconstantTask,
      'clean:dist',
      'wiredep',
      'useminPrepare',
      'concurrent:dist',
      'postcss',
      'ngtemplates',
      'concat',
      'ngAnnotate',
      'copy:dist',
      'cdnify',
      'cssmin',
      'uglify',
      'filerev',
      'usemin',
      'htmlmin'
    ]);
  });

  grunt.registerTask('default', [
    'newer:jshint',
    'newer:jscs',
    'test',
    'build'
  ]);

Sources :

http://www.jvandemo.com/how-to-configure-your-angularjs-application-using-environment-variables/

http://cayugasoft.com/configuring-multiple-environments-angular-js-using-grunt-ng-constant/

Installer NodeJS, NPM et Bower sous Debian

node.js-bower

Pour une installation d’un environnement de développement sous Debian.

Installer les dépendances

sudo apt-get update 
sudo apt-get install git-core curl build-essential openssl libssl-dev

Télécharger NodeJS

Et lancer la compilation

tar xvf node-v5.4.0.tar.gz
cd node-v5.4.0
configure
make

Editer le fichier /etc/profiles ou ~/.profile

# PATH
NODEJS_HOME=$HOME/prgm/node-v5.4.0-linux-x64

PATH="$NODEJS_HOME/bin:$PATH"

Tester l’installation

node -v
npm -v

Installer Bower

npm install -g bower

Installer Grunt

npm install -g grunt

Let’s Hack !

Matomo encountered an error: Uncaught Error: Class "Piwik\Plugins\CustomVariables\CustomVariables" not found in /var/www/piwik/core/Tracker/TrackerCodeGenerator.php:101 Stack trace: #0 /var/www/piwik/plugins/SitesManager/API.php(160): Piwik\Tracker\TrackerCodeGenerator->generate() #1 [internal function]: Piwik\Plugins\SitesManager\API->getJavascriptTag() #2 /var/www/piwik/core/API/Proxy.php(255): call_user_func_array() #3 /var/www/piwik/core/Context.php(29): Piwik\API\Proxy->Piwik\API\{closure}() #4 /var/www/piwik/core/API/Proxy.php(158): Piwik\Context::executeWithQueryParameters() #5 /var/www/piwik/core/API/Request.php(274): Piwik\API\Proxy->call() #6 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request/Php.php(46): Piwik\API\Request->process() #7 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request/Php.php(18): WP_Piwik\Request\Php->call() #8 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/Request.php(63): WP_Piwik\Request\Php->request() #9 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(1038): WP_Piwik\Request->perform() #10 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(1205): WP_Piwik->request() #11 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik/TrackingCode.php(16): WP_Piwik->updateTrackingCode() #12 /var/www/thegtricks/wp-content/plugins/wp-piwik/classes/WP_Piwik.php(296): WP_Piwik\TrackingCode->__construct() #13 /var/www/thegtricks/wp-includes/class-wp-hook.php(324): WP_Piwik->addJavascriptCode() #14 /var/www/thegtricks/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters() #15 /var/www/thegtricks/wp-includes/plugin.php(517): WP_Hook->do_action() #16 /var/www/thegtricks/wp-includes/general-template.php(3080): do_action() #17 /var/www/thegtricks/wp-content/themes/twentyfifteen-child/footer.php(45): wp_footer() #18 /var/www/thegtricks/wp-includes/template.php(810): require_once('...') #19 /var/www/thegtricks/wp-includes/template.php(745): load_template() #20 /var/www/thegtricks/wp-includes/general-template.php(92): locate_template() #21 /var/www/thegtricks/wp-content/themes/twentyfifteen/archive.php(68): get_footer() #22 /var/www/thegtricks/wp-includes/template-loader.php(106): include('...') #23 /var/www/thegtricks/wp-blog-header.php(19): require_once('...') #24 /var/www/thegtricks/index.php(17): require('...') #25 {main} thrown (which lead to: Session must be started before any output has been sent to the browser; output started in /var/www/thegtricks/wp-includes/script-loader.php/2938)