Ecrire des applications HTML5 Open Data en C# et les compiler en JavaScript
La plate-forme cliente HTML5 devient une plateforme de plus en plus centrale pour cibler le développement de l'interface utilisateur et notamment dans le contexte de données ouvertes (open data). Elle est non seulement prise en charge par un nombre sans cesse grandissant de dispositifs mobiles comme les Smartphones ou les tablettes, mais elle spécifie également un nouvel élément Canvas particulièrement intéressant pour celles et ceux qui souhaitent créer des visualisations de données riches sur toutes les plates-formes ; ce qui revêt quelques intérêts dans la cadre d’applications Open Data. (Notre collègue David Rousset trouvera cette description certainement bien réductrice… Il y a tant à dire mais rien ne vaut, dans ces conditions, un petit tour sur son blog.)
Si la promesse d'être capable d'écrire avec une telle plateforme une certaine logique applicative pour présenter des visualisations côté client hautement interactives est très séduisante, elle présente néanmoins des inconvénients aux équipes de développement qui sont habitués à miser sur les caractéristiques des langages de niveau supérieur comme C# ou Java pour faire valoir la qualité du produit et pour assurer une facilité de maintenance et d’évolution/amélioration. Le développement du code constitue en effet la problématique majeure à aborder par rapport à un développement traditionnel : absence de phase de compilation, difficultés à écrire du code Orienté Objet avec une syntaxe naturelle, à dissocier la logique « ce qu'il faut rendre » de la logique « comment le rendre », etc.
Comme le développement du code fondé sur le script devient une généralisation avec la vague HTML5, un certain nombre de questions intéressantes émergent : quels sont les outils de développement, que vous et votre équipe, pouvez utiliser de manière productive pour développer et gérer une base de code ? N’est-il pas préférable d’écrire du code dans un modèle optimisé pour le développement et la productivité et de laisser un compilateur faire sa magie et de produire du code optimisé pour le déploiement et l'exécution ? Quelles sont alors les options possibles ?
Dans ce contexte, ScriptSharp (Script#) constitue une réponse pleine de promesses pour compenser ces manques et franchir un cap en termes de productivité. Développée par Nikhil Kothari depuis 2006, Script# est une mini plateforme de développement JavaScript/AJAX (Asynchronous JavaScript and XML) qui permet de coder en C# des bibliothèques JavaScript classiques. Le code est compilé et donc vérifié vis-à-vis des erreurs à l'aide d'un ensemble beaucoup plus strict d'exigences et d’une sémantique de niveau plus élevé (comme le typage fort, l'implémentation d'interface, etc.). La traduction en JavaScript équivalent s'effectue à la compilation. La syntaxe d'origine du langage C# est directement et syntaxiquement traduite dans les déclarations équivalentes de JavaScript. Le JavaScript traduit offre une similitude fiable du code écrit dans le langage C#.
Parmi les atouts clés à retenir de Script#, on peut citer :
- Lors du développement, la puissance et la productivité de C# (avec la capacité de consommer les types génériques), le support de la conception Orienté Objet, la re-factorisation de code, l’intégration avancée avec la technologie ASP.NET MVC (et NuGet), la prise en charge des dernières interfaces programmatiques (API) ASP.NET AJAX, la possibilité d'utiliser du code JavaScript existant à partir de C#, la prise en charge de JQuery dans sa version 1.6.1 ainsi celle de diverses API manquantes, le confort et la robustesse d’une intégration avancée avec l’environnement de développement Microsoft Visual Studio 2010 avec la technologie IntelliSense, le support des tests unitaires (via les projets de test VS2010 ainsi que le Framework de test unitaire QUnit utilisé dans jQuery), la bonne documentation (même si la dernière en date est déjà un peu ancienne (0.5.5.0)) et les nombreux exemples disponibles, etc. ;
- Au niveau des flux de développement dans le contexte d’une usine logicielle, la capacité à s’intégrer dans des builds fondés sur MSBuild ou encore le support des outils .NET existants (FxCop, StyleCop, etc.) ;
- Et au-delà du développement, l’analyse statique et la visualisation de code, le parcours des classes ainsi que la capacité à générer la documentation du code avec SandCastle.
Il convient enfin de mentionner la bonne documentation (même si la dernière en date est déjà un peu ancienne) et les nombreux exemples disponibles.
En synthèse, Script# apporte la puissance de Visual Studio 2010 et des outils .NET pour établir avec le langage C# un modèle de développement productif pour concevoir, tester et gérer des applications à l'aide de HTML5, CSS3 et JavaScript avec des Frameworks populaires tels que jQuery (Core, Back Button and Query, Templating, etc.). (Dans l’environnement Java, le pendant est Google Web Toolkit (GWT).)
Dans la pratique, Script# est aujourd’hui utilisée au sein de Microsoft dans de nombreux projets comme par exemple Bing Cartes, Bing Mobile, Windows Live Mail, Windows Live Messenger, etc. Script# est également utilisé ailleurs. La bibliothèque JavaScript Client Library for Facebook API est, par exemple, développée avec Script#.
L’utilisation de Script# suppose d’installer le fichier .msi correspondant. Vous pouvez télécharger la dernière version 0.7.2.0 de Script# depuis le site du projet Script#. (La version 1.0 est attendue pour la fin de cette année 2011.) Le programme d’installation de Script# installe le compilateur Script#, le runtime core, un ensemble d’assemblages optionnels sous C:\Program Files (x86)\ScriptSharp\v1.0.
Pour démarrer avec Script#, vous pouvez suivre simplement le billet Getting Started with Script# qui vous propose un pas à pas complet. A titre d’illustration rapide dans le cadre de ce billet, le code C# suivant d’une bibliothèque JavaScript BingMapsApp tire parti de l’assemblage Script.Web.dll des APIs Application Web de Script# et de l’assemblage Script.Microsoft.BingMaps.dll de l’API du contrôle AJAX Bing Cartes v7.0, tous deux ajoutés en référence au projet de bibliothèque. (Le projet Google Maps API for Script# sur la forge Codeplex propose l’équivalent pour Google Maps.) :
using System;
using System.Collections;
using System.Html;
using System.Runtime.CompilerServices;
namespace BingMapsApp
{
internal static class BingMapsApplication
{
static BingMapsApplication()
{
Window.AddEventListener("load", delegate(ElementEvent e)
{
BingMapsShell shell = new BingMapsShell();
shell.Run();
}, /* useCapture */ false);
}
}
}
Le code C# de la classe BingMapsShell est le suivant :
using System;
using System.Collections;
using System.Html;
using Microsoft.Maps;
namespace BingMapsApp
{
internal sealed class BingMapsShell
{
private Map _map;
private MapPushpin _pushpin;
private MapInfobox _infobox;
public void Run()
{
Element rootElement = Document.GetElementById("map");
MapOptions mapOptions = new MapOptions();
mapOptions.Credentials = (string) rootElement.GetAttribute(
"data-credentials");
mapOptions.Width = 640;
mapOptions.Height = 480;
mapOptions.ShowCopyright = false;
mapOptions.ShowMapTypeSelector = true;
mapOptions.ShowLogo = false;
mapOptions.ShowScalebar = false;
mapOptions.ShowNavControl = true;
mapOptions.ShowDashboard = true;
mapOptions.Center = new MapLocation(
48.8569246977568, 2.34120972454548);
mapOptions.Zoom = 50;
mapOptions.MapType = MapType.Birdseye;
MapPushpinOptions pushpinOptions = new MapPushpinOptions();
_pushpin = new MapPushpin(mapOptions.Center, pushpinOptions);
MapInfoboxOptions infoboxOptions = new MapInfoboxOptions();
infoboxOptions.Title = "Paris";
infoboxOptions.Visible = false;
infoboxOptions.offset = new MapPoint(0, 20);
infoboxOptions.Height = 48;
infoboxOptions.Width = 80;
infoboxOptions.ShowCloseButton = false;
_infobox = new MapInfobox(mapOptions.Center, infoboxOptions);
_map = new Map(rootElement, mapOptions);
_map.Entities.Push(_pushpin);
_map.Entities.Push(_infobox);
MapEvents.AddHandler(_pushpin, "click", OnPushpinClick);
MapEvents.AddHandler(_map, "viewchange", OnViewChanged);
}
private void OnPushpinClick(EventArgs e)
{
MapInfoboxOptions options = new MapInfoboxOptions();
options.Visible = true;
_infobox.SetOptions(options);
}
private void OnViewChanged(EventArgs e)
{
MapInfoboxOptions options = new MapInfoboxOptions();
options.Visible = false;
_infobox.SetOptions(options);
}
}
}
La page HTML invoquant le code JavaScript de la bibliothèque BingMapsApp.debug.js précédente est le suivant avec, à la clé, simplement une référence de celle-ci :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Bing Cartes</title>
</head>
<body>
<div id="map" style='width: 640px; height: 480px' data-credentials='AvROonkHlY0PHW8zAWDFW5JX8tMeSxzUlkR23_uGzUpeGzrJxf-8tSxAvQmO_5PX'></div>
<script type="text/javascript" src="https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript" src="mscorlib.debug.js"></script>
<script type="text/javascript" src="BingMapsApp.debug.js"></script>
</body>
</html>
Nous venons d’introduire rapidement Script#. Pour aller plus loin, vous pouvez visionner la session MIX11 Script#: Compiling C# to JavaScript using Visual Studio qui propose un aperçu pratique de Script#, avec un partage des expériences d'utilisation dans la vraie vie, et revient sur la feuille de route du projet. La présentation Powerpoint ainsi que les différents exemples de code peuvent être téléchargés ici comme le source de l’application AroundMe utilisant Flickr, Bing Cartes, la géo-localisation et les Canvas Visual Studio pour les applications HTML5.
Nous aurons l’occasion de revenir sur Script#. Dans l’intervalle, vous pouvez en suivre les évolutions sur Twitter ainsi que sur le blog de Nikhil Kothari.
Comments
- Anonymous
February 04, 2014
article très instructif ! merci !