Déployer une application Yeoman/AngularJS sur Heroku

|

Démonstration Sources

Beaucoup de tutoriels sur Internet vous expliquent comment déployer une application Yeoman/AngularJS avec Heroku. Cependant, elles ont toutes un souci, l’ajout du dossier dist (contenant les fichiers compilés) dans le repository Git. J’ai donc décidé d’écrire mon propre tutoriel en ayant à l’esprit que le repository Git ne doit contenir que les sources. La génération finale sera effectuée par Heroku.

Dans ce tutoriel, nous allons voir comment déployer une application AngularJS créée par le générateur generator-angular. Ce tutoriel est basé sur http://www.sitepoint.com/deploying-yeomanangular-app-heroku/.

Prérequis

Avant de continuer il vous faut les éléments suivants :

L’application

création du projet

On ouvre le terminal, on se créé un dossier et on lance la commande :

1
yo angular myApp

Suivez les instructions à l’écran pour finaliser la génération du projet.

Préparation du projet pour Heroku

Le souci de ce projet est qu’il ne contient que des pages statiques, il va donc falloir intégrer un serveur web pour qu’Heroku puisse le faire fonctionner correctement. Pour cela, nous allons utiliser Express, un framework NodeJS.

1
npm install gzippo express morgan --save

Ensuite, à la racine du projet, nous allons créer un fichier web.js :

1
2
3
4
5
6
7
8
var gzippo = require('gzippo');
var express = require('express');
var morgan = require('morgan');
var app = express();

app.use(morgan('dev'));
app.use(gzippo.staticGzip("" + __dirname + "/dist"));
app.listen(process.env.PORT || 5000);

Ce fichier va être lancé par Heroku et se charge de gérer le serveur web avec le contenu du dossier dist. Ce dossier va être généré par notre projet grunt.

Toujours à la racine du projet, veuillez créer un fichier Procfile avec le contenu suivant :

1
web: node web.js

Suppression de grunt-ngAnnotate

Pour ma part, je n’ai jamais réussi à faire fonctionner grunt-ngAnnotate avec Heroku, j’ai donc décidé de le supprimer. Cela va impliquer qu’il faudra préparer l’injection de dépendance à la main.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// changez ça
angular.module('myAppApp')
    .controller('MainCtrl', function ($scope) {
        $scope.awesomeThings = [
            'HTML5 Boilerplate',
            'AngularJS',
            'Karma'
        ];
    });

// en ça
angular.module('myAppApp')
    .controller('MainCtrl', ['$scope', function ($scope) {
        $scope.awesomeThings = [
            'HTML5 Boilerplate',
            'AngularJS',
            'Karma'
        ];
}]);

// ou en ça
// les deux éléments font la même chose
// seule la syntaxe diffère
angular.module('myAppApp')
    .controller('MainCtrl', MainCtrl);

MainCtrl.$inject = ['$scope'];
function MainCtrl($scope) {
    $scope.awesomeThings = [
        'HTML5 Boilerplate',
        'AngularJS',
        'Karma'
    ];
}

Répétez cette opération pour tous vos fichiers.

Ouvrez le fichier Gruntfile.js et supprimez tout ce qui a attrait à ngAnnotate.

Création du respository git

Il suffit d’entrer la commande suivante dans votre terminal :

1
git init

Heroku

Création de l’application dans Heroku

A l’heure actuelle, nous avons une application qui se trouve sur votre ordinateur, qui n’est ni sur Heroku, ni sur un serveur Git. Nous avons aussi un compte Heroku (sans application) et le Heroku toolbelt d’installé.

Pour créer une application dans Heroku, il vous faut entrer ceci dans votre terminal. Comme votre dossier comprend un fichier package.json, Heroku comprend qu’il s’agit d’un projet nodejs.

1
2
3
heroku login
heroku create myApp
heroku ps:scale web=1

Utilisation d’un buildpack personnalisé

Le souci premier du buildpack nodejs officiel est qu’il ne lance aucune commande au démarrage (pas de Bower ni de Grunt). Nous allons donc utiliser un buildpack personnalisé pour remédier à ce problème. Ce dernier va lancer la commande heroku:production à la compilation de l’application.

Veillez entrer les commandes suivantes dans votre terminal. La première se charge d’instancier l’application avec le bon buildpack, la seconde de mettre l’application en mode production.

1
2
heroku config:add BUILDPACK_URL=https://github.com/mbuchetics/heroku-buildpack-nodejs-grunt.git
heroku config:set NODE_ENV=production

Bower et Grunt pour Heroku

Il nous faut maintenant définir la commande heroku:production dans notre fichier Gruntfile.js.

Ajoutez ces lignes à la fin de votre fichier.

1
2
3
grunt.registerTask('heroku:production', [
  	'build'
]);

Par defaut, Bower ne sera pas lancé par Heroku, nous allons donc l’automatiser avec le plugin grunt-bower-task.

1
npm install grunt-bower-task --save

Ouvrez le fichier Gruntfile.js et ajoutez ceci :

1
2
3
4
5
6
7
grunt.initConfig({
  bower: {
    install: {
       //just run 'grunt bower:install' and you'll see files from your Bower packages in lib directory
    }
  }
});

ensuite ajoutez la tâche à la commande ‘heroku:production’ :

1
2
3
4
grunt.registerTask('heroku:production', [
    'bower:install',
    'build'
]);

Par défaut, Heroku ne va installer que les dépendances comprises dans ‘dev’ et non pas dans ‘devDependencies’. Vous avez donc deux choix :

  1. Dupliquer les dépendances
  2. Autoriser l’installation des dépendances ‘devDependencies’.

Si vous choisissez la seconde solution, il vous faudra écrire ceci dans la console :

1
heroku config:set NPM_CONFIG_PRODUCTION=false

Envoyer sur Heroku

Pour se faire, il faudra utiliser les commandes de Git. Ouvrez un terminal et entrez les commandes suivantes :

1
2
3
git add .
git commit -m "Initial commit"
git push heroku master

Conclusion

Ce déploiement permet de garder un repository Git propre avec seulement les sources. Vous avez toujours la possibilité de réaliser un ‘grunt build’ en local pour vous assurer que tout se passera bien une fois sur Heroku. Enfin, notre déploiement est automatisé et se chargera d’offrir une application légère avec des fichiers concaténés et minifiés.

Heroku vous propose même d’aller plus loin, avec un webhook sur un repository GitHub et de ne faire le déploiement seulement si vos tests passent. Utilisez donc le trio GitHub - Travis CI - Heroku et vous avez un système qui fonctionnera tout seul !