Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Les projets ASP.NET 5 – partie 3/4

Poster un commentaire

Important 28/11/2016: Remise à jour et beaucoup améliorations de l’article d’origine. La version testée est Asp.Net Core 1.0

 

Les deux articles précédents nous ont permit de découvrir l’architecture des projets Core et de voir comment on construisait un site MVC et WebApi.

On a découvert la classe Startup et l’injection de dépendance qui est maintenant obligatoire.

Voyons maintenant comment Core intègre des outils tels Node, Bower, Grunt…

Les outils clients: scripts, Node, Bower, Grunt…

Préparation de la démo

Core offre un support intégré, en tout cas facilité pour divers outils tels Bower ou Grunt.
Je propose d’attaquer direct la démo.
On va tout d’abord modifier notre méthode d’action:
public IActionResult Index()
{
   return View();
}
On ne peut pas faire plus dépouillé. On ajoute la vue correspondante:
<div>
Cliquez moi dessus!!!!
</div>
2016-11-30_11-08-14
C’est pas spectaculairement, mais une démo doit savoir rester à sa place et ne pas masquer l’essentiel sans être trop « hello world ».
Un petit JavaScript JQuery pour terminer:
$(function()  {
   var clickHandler = function() { alert('Hello Amethyste'); }
   $("div").click(clickHandler);
});
L’idée est de cliquer sur la DIV de la vue et afficher un petit message.
Et à la fin les choses ressemblent à ceci:
2016-11-30_11-13-08
Pour l’instant seule la vue s’affiche, le script n’est pas encore intégré.

Installation de JQuery avec Bower

Nous avons une librairie JQuery à référencer dans notre projet. Tout comme le code .Net, la bonne pratique dans Core est de passer par des packages. On pourrait donc  songer à Nuget. Mais Nuget n’est pas le meilleur choix pour installer les librairies clientes:
La solution standard est Bower.
L’installation est classique, on n’oublie pas l’attribut -g pour faire une installation globale.
npm install bower -g
Normalement Node est installé en même temps que VS 2015.
On peut se demander pourquoi utiliser Bower alors que l’on a déjà Node, lisez cette discussion intéressante:
L’installation devrait se faire dans le répertoire:
C:\Users\<VOTRE LOGING>\AppData\Roaming\npm
Ajoutez le à PATH et relancez la console. Normalement la commande:
Bower
Devrait afficher ceci:
as59
Il ne reste plus qu’à configurer les dépendances JQuery dans la configuration Bower. Au niveau du projet, faire clic droit puis Add:
2016-11-30_11-17-59
Et on obtient:
as61
On n’a plus qu’à ajouter la dépendance à JQuery. On peut le faire à la main comme avec project.json, mais aussi en lançant cette ligne de commande depuis le répertoire projet:
Bower install jquery –save
as62
 Et le fichier de configuration ressemble à:
as63
Pour des raisons que j’ignore le fichier bower.json n’est pas affiché par VS par défaut, mais il est bien présent dans le projet:
2016-11-30_13-18-04
Côté application il y a quelques transformations:
 as64
JQuery est déployé dans wwwroot/lib. C’est le répertoire déclaré dans .bowerrc:
as65
Essayez maintenant de supprimer le répertoire wwwroot/lib/query et son contenu. Pour le reconstituer il suffit de lancer:
Bower install
La commande part lire le fichier bower.json et installe/réinstalle les dépendances trouvées.
On a fait le travail manuellement. Comme on est développeur on préfèrerai l’automatiser. Il y a justement un support à l’automatisation de tâches dans Core via des scripts.
Tout se passe dans project.json. La section scripts permet d’attacher des actions à divers événements comme création d’un package, publication, restauration des packages…. Les évènements existent en version PRE et POST.:
as66
On va pouvoir associer des scripts à ces propriétés, scripts qui seront lancés au moment voulu par VS. Nous souhaitons envoyer la commande qui suffira puisque le fichier de configuration Bower est renseigné:
Bower install
Un endroit possible est celui-ci:
"scripts": {
"precompile": "bower install"
}
Note: il existaient des événements comme prerestore qui a mon avis auraient constitué un meilleur choix. Mais dans les versions récente de project.json ils ont disparus:
IntelliSense les affiche toujours, mais je ne les voit se déclencher.
On pourrait avoir plusieurs commandes, il suffit d’utiliser la syntaxe tableau.
"scripts": {
"precompile": ["command 1", "command 2"]
}
Ainsi si un développeur récupère le projet, il n’a qu’à lancer un « Package restore » comme nous avons appris à le faire et la commande restaurera également les dépendances Bower dont il aura besoin sans avoir à lancer une ligne de commande supplémentaire.
Essayons!
Vider wwwroot/lib et lancez un restore package.
 as67
Vous constatez que les dépendances sont toutes restaurées.
Il ne reste qu’une dernière étape et on a terminé: charger JQuery et le script dans la vue puis tester.

<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/scripts/demo.js"></script>
 
 <div>
Cliquez moi dessus!!!!
 </div>
Et:
 as68

Ça marche!

 

Dans la vraie vie on ne ferai pas exactement ainsi. On essayerai de concaténer tous les scripts et les minifier. C’est ce que nous allons faire maintenant.

 

Concaténer et minifier

Le besoin est l’automatisation d’une suite de tâches. Il existe deux outils très utilisés: Gulp et Grunt.

https://blogs.msdn.microsoft.com/webdev/2016/01/06/task-runners-in-visual-studio-2015/

Gulp est installé par défaut avec VS, mais je préfère Grunt dont la syntaxe me semble plus claire.

 

Mise en place de la plomberie

Avant d’utiliser Grunt, on devra installer Node.

 

La première étape est d’installer l’interface de ligne de commande Grunt (la CLI):

npm install grunt-cli -g

 

On oublie pas la mise à jour de PATH avec un chemin du style:

C:\Users\<LOGIN>\AppData\Roaming\npm\node_modules\grunt-cli

 

Le travail de la CLI est uniquement de lancer le lanceur de tâche Grunt déclaré localement dans le projet. Chaque projet peut avoir sa version. Cette déclaration fait partie des dépendances Node.

 

C’est le premier module Node du projet, il faut donc créer son fichier de configuration. Il s’appelle package.json.

 

as69
Le fichier proposé ressemble à celui-ci:
2016-11-30_14-40-20
On déclare le lanceur de tâche Grunt dans les dépendances exactement comme on l’a fait pour Bower.
A la fin on a ceci:
{
   "version": "1.0.0",
   "name": "asp.net",
   "private": true,
   "devDependencies": {
      "grunt": "1.0.1"
    }
}
 Et on doit aussi trouver Grunt présents dans les dépendances Node:
as71
Et bien entendu on complète project.json:
2016-11-30_14-44-11
La plomberie est en place, mais pour qu’elle soit utile il faut créer des tâches à jouer.

Création des tâches

Toujours dans package.json on déclare grunt-contrib-uglify.
2016-11-30_14-51-49
 De nouvelles dépendances sont chargées:
as73
Nous sommes prêt à créer notre premier script Grunt, on appelle ça un GruntFile. VS fournit des modèles:
as74
Le fichier généré ressemble à celui-ci:

module.exports = function (grunt) {
// script Grunt
 
grunt.initConfig({
// initialise la tâche
});
 
// charge la tâche
};
 
On créée la tâche de minification, elle s’appellera uglify.

module.exports = function (grunt) {
var uglifyConfig = {
   files: {
      src: "wwwroot/scripts/demo.js",
      dest: "wwwroot/scripts/demo.min.js"
         } 
   };
 
   // configure le projet
   grunt.initConfig({
   // création de la tâche uglify
   uglify: uglifyConfig
});
 
// charge le plugin grunt-contrib-uglify dans le contexte de la tâche
grunt.loadNpmTasks("grunt-contrib-uglify");
};
 
Puis on lance depuis la ligne de commande pour tester:
Grunt uglify
 as75
Côté VS:
as76
On pourrait aussi lancer la tâche autrement. Le menu contextuel attaché au gruntfile permet de lancer un exécuteur de tâche:
as77
Qui ouvre un panneau qui doit ressembler à ceci:
as78
Je ne suis pas parvenu à le faire fonctionner.
Dans le cas où l’on a plusieurs tâches, il est peut-être utile de les rassembler en une seule comme par exemple:
 
module.exports = function (grunt) {
   // configure le projet
   // …
 
   // charge le plugin grunt-contrib-uglify dans le contexte de la tâche
   // ….
 

   // creation de la tâche build
   grunt.registerTask("build", ["concat", "uglify"]);
};

On créée une tâche build qui lance successivement concat puis uglify.
On peut ensuite aller plus loin dans l’automatisation en créant un script dans project.json:
"scripts": {
   "precompile": [ "bower install", "npm install" ],
   "postcompile": ["grunt uglify"]
}
Lancez ensuite un build de la solution et vérifiez que ça fonctionne.
Note: le nom des tâches est sensible à la casse.
Lecture complémentaire:

 Bibliographie

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s