Remplacer Web Essentials sur Visual Studio 2015

Web essentials 2015 : disparition de fonction

J'ai été un peu surpris par la suppression de bon nombres de fonctionnalités de web essentials lorsque nous sommes passé sous visual studio 2015. Heureusement pour nous on avait anticipé tout cela sans le savoir.
Web essentials est un addin visual studio, très prisé des développeurs web sous visual studio il ajoute tout un tas de fonctionnalités facilitant la vie du développeur web.

Plus de compilation LESS

C'est tout bête mais avant web essentials permettait de compiler ses fichiers less à la volée. ça n'est maintenant plus le cas.

Plus de minification javascript

La encore une fonctionnalité bien utile qui disparaît. Avant la minification et la génération des fichiers map se faisait à la volée.

Il y a encore quelque chose d'utile ???

Oui heureusement, par exemple la possibilité de retrouver toutes les références sur une fonction javascript.
Ou encore la possibilité de faire des regions comme en c#

    //#region helps functions
    function help(){
      return 'help function';
    }
    //#endregion

L'addin génère également des aperçus d'images directement depuis le HTML lorsque l'on passe la souris au dessus de l'image :

Et encore beaucoup d'autres fonctionnalités que vous retrouverez sur le site du composant :
Web essentials

Retrouver la compilation less et la minification de css

Bon c'est bien beau tout ça mais comment je fais pour compiler les mes fichiers LESS moi ?
Microsoft recommande un autre addin présent dans la galery visualstudio :
WebCompiler

Il s'agit d'un compilateur LESS, Sass, JSX, ES6 et CoffeeScript
Il gère également la recompilation automatique des fichiers après modification, la minification, l'intégration dans MSBuild, des options de compilation personnalisées par fichier.
Un menu contextuel est ajouté dans le solution explorer pour recompiler/activer la compilation sur vos fichiers LESS :
Ici on retrouve donc toutes les fonctionnalités de Web Essentials concernant les fichiers LESS.

Grunt : l'automatisation dans un fichier ou le retour du makefile

Grunt et son équivalent Gulp sont des automatiseurs de tâches. On s'en sert notamment pour le déploiement de site web grâce à l’exécution de tâche comme la concaténation de fichiers javascripts ou encore la compilation de fichiers LESS en CSS.

C'est donc avec ce type d'outil que l'on peut remplacer les tâches que l'on effectuait sous visual studio 2013 avec Web Essentials.

Grunt par l'exemple

Je vais décrire ci dessous un fichier grunt permettant d'effectuer les tâches suivantes :

  • compilation de fichier less en css
  • minification de fichier css
  • concaténation de fichiers javascript
  • minification de fichier javascript

On peut faire beaucoup plus de choses avec Grunt (je m'en sers par exemple au travail pour générer des fichiers de traductions à partir d'une base de données) mais ça n'est pas le sujet de cet article.

Dans Visual Studio 2015, tous les outils pour utiliser grunt sont présents de base à savoir :

  • Task Runner Explorer
  • Node JS (en version 0.10)

Node est associé à un gestionnaire de paquets fort sympathique : npm.

Pour commencer, ouvrir une invite de commande (j'utilise conEmu plutôt que l'invite de commande windows).
Placez vous dans le dossier de votre site web (ASP.net 4.5.2 pour cet exemple) et tapez la commande

npm init  

cela va avoir pour effet de créer le fichier package.json, l'assistant va vous demander tout un tas d'informations sur votre projets permettant de clairement l'identifier.
Ce fichier va contenir tous les paquets qui seront nécessaire à votre projet, gros avantage c'est que vous n'avez plus besoin de stoker sur votre gestionnaire de sources toutes les librairies open sources externes à votre projet et dans notre cas il s'agit de grunt.

Ce qui a pour conséquence direct qu'il ne faudra pas envoyer sur votre git( ou autre gestionnaires de source) le répertoire node_modules présent dans votre solution.
C'est très important, cela évite lorsque l'on fait de la code review de voir passer tout un tas de fichiers inutiles non liés à votre code.

Un nouveau dev qui arrive dans votre équipe n'aura qu'à taper la commande

    npm install

Pour récupérer l'ensemble des paquets/librairies nécessaires à votre solution web.
Le revers de la médaille : pas d'internet, pas de moyen de compiler une solution fraîchement clonée. C'est un risque à prendre en compte.

Mais revenons à Grunt, nous allons donc l'ajouter en tant que dépendance à votre projet et comme il s'agit d'un outil uniquement lié au développement nous allons utiliser l'option --save-dev qui indique que le paquet à installer doit être installé comme dépendance au développement, en d'autres termes ces paquets ne servent qu'au développement mais ne seront pas déployés sur le serveur de production.

npm install grunt --save-dev  

Notre fichier package.json a maintenant cette forme :

{
  "name": "ArticleGrunt",
  "version": "1.0.0",
  "description": "solution de démonstration pour l'article web essentials",
  "main": "gruntfile.js",
  "dependencies": {    
  },
  "devDependencies": {
    "grunt": "^0.4.5"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "David Verrière",
  "license": "ISC"
}

grunt a été ajouté dans la section devDependcies
Maintenant que grunt est installé vous pouvez créer le fichier gruntfile.js dans votre projet web visual studio qui va contenir toutes les tâches à effectuer.
Un fichier vide grunt.js a cette tête la :
On peut remarquer que le fichier est reconnu par Web essentials grâce à la petite tête de sanglier en bas à droite, au delà de cette petite attention c'est surtout la prise en charge de l'intellisense qui nous intéresse ici.

Commençons par écrire une règle de compilation less, le but du jeu va être de compiler nos fichiers less en css.
Pour faire cela nous avons besoin du paquet grunt dédié à cette tâche grunt-contrib-less, il faut donc l'installer pour notre projet.
Taper la commande :

npm install grunt-contrib-less --save-dev  

Ouvrir le fichier gruntfile.js et modifiez le de la façon suivante :

module.exports = function (grunt) {

    grunt.initConfig({
        less: {
            development: {
                options: {
                    compress: true,
                    yuicompress: true,
                    optimization: 2
                },
                files: {
                    "Content/site.min.css": "Content/site.less"
                }
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.registerTask('default', ['less']);
};

Nous avons rajouté dans le fichier la tâche less, cette tâche décompose en une sous tâche development (vous pouvez avoir autant de sous tâche que vous voulez).
Cette tâche development contient les paramètres nécessaire à la compilation LESS :

  • les options (compression, optimization,etc)
  • les fichiers à prendre en entrée
  • le fichier de sortie "Content/site.min.css"

à la fin de fichier grunt il est nécessaire d'indiquer quels sont les paquets nécessaires à grunt :

    grunt.loadNpmTasks('grunt-contrib-less');

Il n'y a plus qu'à executer notre tâche grunt grâce au task explorer de visual studio via un clique droit sur la tâche :
Si vous regardez dans votre solution un fichier site.min.css a été créé.

Plusieurs choses à ajouter, il est possible de "binder" des événements pour lancer automatiquement les tâches grunt par exemple avant une build visual studio il peut être intéressent de lancer une tâche dédié à la minification javascript plus l'offuscation de code.
Il est également possible d'ajouter des watcher afin que les tâches s'executent dès qu'un fichier est modifié dans un répertoire :
exemple vous avez tout un tas de controller liés séparés dans des fichiers , une tâche permet de concaténer tous ces fichiers en un seul qui est référencé par votre page web. En phase de développement il peut être fastidieux de devoir à chaque modification d'un des fichiers controller devoir reéxécuter à la main la règle de concaténation. On ajoute donc un watcher dédié à cet effet.

le mot de la fin

Grunt est un formidable outil pour gagner du temps dans ses développements web, il serait dommage de s'en passer.
On peut créer de l'industrialisation de processus à moindre frais. L'outil est relativement facile à prendre en place.

J'espère que cet article vous a plu/aidé, si vous souhaitez avoir des exemples dédiés sur certaines problématique je pourrais écrire des articles en rapport.