Bridge.NET : Générer du JavaScript avec C# ?

Imaginez écrire 10 lignes de code pour générer 500 lignes de JavaScript, le rêve non ? Ne cherchez plus, c’est possible grâce à la transpilation (ou transcompilation).

Alors qu’est-ce que c’est au juste ? Et bien le principe est très simple, il s’agit de la compilation d’un langage en un autre, en général de plus bas niveau. Quand vous utilisez un langage comme C# ou Java, au moment de la compilation, ceux-ci vont générer du bytecode, qui est un langage très proche du langage de la machine et qui lui permet de le comprendre et de l’exécuter. Et bien pour d’autres langages, c’est la même chose sauf qu’ils vont compiler en JavaScript afin de pouvoir être utilisé par des navigateurs.

https://devopedia.org/transpiler

Ça permet non seulement de réduire la charge de travail, car on fait plus de choses en codant moins, mais aussi de rendre le code plus maintenable. Parce qu'en ce qui concerne le JavaScript, il est très facile de transformer un projet en un gros plat de spaghettis s’il n’est pas développé très soigneusement. Et en prime, ça permet de générer du code rigoureux, sécurisé, et souvent minifié pour limiter la taille des fichiers, que demander de plus !

// Programation orientée objets
// Encapsulation des données
class User 
{
    // Typage fort
    // Visibilité des variables
    constructor(public username : string, public email : string) 
    {
        if(!Validator.isEmailValid(email))
        {
            // Classes par defaut
            throw new Error("Email invalide");
        }
    }
}

// Encapsulation des données
class Validator
{
    // Méthodes statiques
    public static isEmailValid(email : string) 
    {
        return email.includes("@") && email.includes('.');
    }
}

Et bien sûr, la cerise sur le gâteau, c’est qu’ils permettent de ne plus être limité au JavaScript pour faire de la programmation Web front end, ce qui ouvre un éventail de nouvelles opportunités.

Si on jette un coup d’œil aux solutions existantes, on se rend compte que le choix ne manque pas : TypeScript, CoffeeScript, Dart pour ne citer que les plus connus. Mais il y a quand même un truc qui me chiffonne, c’est que bien qu’il y ait beaucoup de choix, quasiment tous ces langages se ressemblent et sont tous plus ou moins des dérivés du JavaScript.

En soit, la raison est assez logique. Déjà parce que c’est plus simple de transpiler un langage proche du JavaScript en celui-ci : c’est moins lourd, plus flexible, et ça permet d’avoir un langage qui implémente le meilleur de JavaScript en se séparant du pire.

Mais c’est aussi parce que le public cible de ce genre de langage est principalement composé de développeurs front end, donc essentiellement des personnes qui connaissent et qui travaillent déjà avec JavaScript.

Du coup, en temps que développeur C#, on se sent un peu mis de côté. Bien sûr, ce n’est pas la mort d’apprendre JavaScript (et c’est même plus que recommandé !), mais c’est dommage de se restreindre quand on sait que n’importe quel langage pourrait faire l’affaire et apporter des fonctionnalités intéressantes que les dérivés de JavaScript n’ont pas.

Et bien une équipe de développeur s’est faite la même remarque, ils ont donc créé un framework/compilateur qui permet de transformer du C# en JavaScript : Bridge.NET.

Je dois vous avouer que quand j’ai vu ça, je n’y ai pas cru. Ça me semblait trop beau pour être vrai. Mais j’ai testé, et ça marche, ça marche même très bien !

Rien qu’avec le site officiel, on sent que ça ne rigole pas

Je vais vous montrer comment ça marche dans un instant, mais avant, il faut que je réponde à une question importante : pourquoi utiliser C# pour faire des applications web ?

Il est vrai que JavaScript est un langage parfaitement adapté pour ça, grâce à son interaction avec le DOM très simple et son système d’événements aux petits oignions, c’est pourquoi j’incite tous les développeurs web sans exception de s’y intéresser un minimum.

Néanmoins, il y a tout de même des points sur lesquels C# cartonne là où JavaScript est assez faible. Par exemple, la programmation orientée objets, le typage fort, la richesse de son framework (.NET étant immensément plus riche que le framework de base de JavaScript)… Ce sont ces fonctionnalités qui rendent C# intéressant, et elles s’appliquent aussi très bien à la programmation web. Donc oui, il est pertinent de l’utiliser pour faire du front end.

Bien sûr, ce n’est pas le seul langage transpilable en JS contenant des objets, un typage fort et une grande librairie, c’est déjà le cas pour TypeScript qui est un juste-milieu entre C# et JavaScript, et qui est un bon concurrent à Bridge.NET (et inversement). Mais c’est un autre sujet pour une autre fois.

Juste une dernière note avant de passer à l’explication, il faut d’abord que vous sachiez que Bridge n’est plus en développement actif par son équipe, et ils ne se contentent plus que de faire des patchs de sécurité et de la correction de bugs. C’est triste, mais c’est la dure vie des projets Open Source. Malgré ça, il reste tout de même très stable, très fonctionnel et toujours pertinent à utiliser !

Voilà, maintenant, on peut enfin commencer.

Installation et configuration

Note avant de commencer : Bridge fonctionne sous .NET Framework uniquement, à la déception des fans de .NET Core (comme moi), donc Visual Studio est quasiment obligatoire pour pouvoir l’utiliser.

La manière la plus simple de créer un projet Bridge.NET est de télécharger une extension pour Visual Studio qui permet de créer des projets de type Bridge.

Ça va générer un projet qui va contenir un fichier App.cs avec à l’intérieur une fonction Main(). Tout comme un programme en console classique, la fonction Main() va contenir l’intégralité du programme, et sera le point central de notre application.

Pour générer le JavaScript, il suffit de recompiler le projet, ce qui va générer l’output dans le répertoire /bin/Debug/bridge. Cet output contiendra au minimum :

  • bridge.js : le framework qui va implémenter les fonctionnalités de .NET en JavaScript.
  • projet.js : l’output JavaScript de votre programme.
  • index.html : le HTML de la page web.

En plus de ça, peuvent se rajouter un fichier implémentant les fonctionnalités de Newtonsoft.Json, les métadonnées des différents fichiers qui vous permettent de faire de la réflexion, des bibliothèques supplémentaires… Mais ils sont totalement dispensables.

Avant de commencer à programmer, il est nécessaire d’apporter quelques points de configuration. Tout d’abord, téléchargez le package Nuget Bridge.Html5 qui va permettre de pouvoir interagir avec le DOM directement en C# (ce qui est quand même l’intérêt de la programmation front end).

Ensuite, on va aller configurer notre projet dans le fichier build.json pour lui dire de ne pas recompiler le HTML, sinon, Bridge va venir remettre à blanc notre index.html à chaque recompilation. Pour être honnête, je ne comprends vraiment pas l’intérêt de cette fonctionnalité, mais passons.

"html": {
    "disabled": false
},

Cette fois, on est tout bon.

Votre premier programme

Pour l’exemple, j’ai programmé un clicker game que j’ai appelé Tacos King, le but est d’obtenir le plus de tacos possibles… Je sais, c’est stupide, mais c’est un exemple ludique qui me permet d’avoir de l’interaction avec le DOM.

Pour commencer, je vais commencer par mettre un bouton dans mon HTML.

<img id="tacos" src="images/taco.png" alt="Tacos" />
c’est une image, mais elle se comportera comme un bouton.

Avec ce bouton, j’aimerais bien augmenter mon nombre total de tacos, et c’est là que le C# entre en scène. Dans le fichier App.js, je vais venir récupérer mon bouton grâce un QuerySelector (qui fonctionne comme en CSS/jQuery) en utilisant l’ID “tacos”, et le mettre dans un objet. Et avec cet objet, je vais pouvoir créer un événement qui va venir incrémenter mon nombre de tacos.

class App 
{
    int tacos = 0;
    var tacosButton = Document.QuerySelector<HTMLButtonElement>("#tacos");

    tacosButton.OnClick = (e) =>
    {
        tacos++;
    };
}

Cool, mais maintenant, j’aimerais bien pouvoir voir mon nombre de tacos sur l’interface. Pour ça, je vais créer une span dans mon HTML, puis la récupérer en C# pour y stocker mon nombre de tacos à chaque fois qu’on clique sur le bouton.

<span id="tacos-number"></span> tacos
class App 
{
    int tacos = 0;
    var tacosButton = Document.QuerySelector<HTMLButtonElement>("#tacos");
    var tacosSpan = Document.QuerySelector<htmlSpanElement>("#tacos-number");

    tacosButton.OnClick = (e) =>
    {
        tacos++;
        tacosSpan.TextContent = tacos.ToString();
    };
}

On recompile, et Bridge va nous créer un beau fichier JS. Il reste plus qu’à l’inclure dans le HTML, et voilà le travail. Le résultat est aussi souple et fluide que du JavaScript traditionnel.

Il y a un peu de CSS en plus, mais le code essentiellement est le même.

Bon, pour l’instant, c’est un peu léger pour un clicker game, je suis d’accord. Mais j’ai été beaucoup plus loin que ça, en incluant des restaurants à acheter et des tacos par seconde, le tout avec Bridge. Si vous voulez voir ce que ça donne, je vous renvoie vers le bonus de cet article.

Le jeu complet !

Dans quel contexte utiliser Bridge ?

Faire joujou avec des tacos, c’est marrant, mais on peut légitimement se demander dans quelles circonstances il est intéressant d’utiliser Bridge.NET.

Déjà, un point que j’aimerais aborder, c’est que Bridge n’est pas juste un prototype ou une démo technique, c’est un vrai transpiler qui a déjà fait ses preuves en production d’après beaucoup d’utilisateurs sur le net, et je pense que c’est un outil qui peut vraiment mener à des développements de qualité, à condition qu’il soit utilisé dans le bon contexte.

Tout d’abord, je ne recommande pas Bridge pour les pages qui nécessitent peu de JavaScript, il ne faut pas oublier que Bridge (comme TypeScript), c’est vraiment une artillerie lourde. Il faut créer un projet Bridge, écrire le code, le transpiler, et inclure la librairie de 50k lignes qui vient avec dans votre page. Est ce que ça vaut vraiment le coup de faire tout ça au lieu d’écrire 50 lignes de JS ? Clairement pas. Je serais plus enclin à utiliser Bridge si je sens que ma page va demander beaucoup de code, et que les concepts de POO risquent de manquer.

Deuxièmement, je déconseillerais l’utilisation de Bridge pour les sites/applications en plusieurs pages interconnectées. Étant donné que le but est de générer un gros fichier JS, le système m’a l’air plus approprié pour faire des applications en une page (SPA). Et actuellement, aucun framework n’implémente Bridge pour faire des applications en plusieurs pages, comme Angular pour TypeScript.

Ce genre d’application.

Ensuite, si vous utilisez déjà du C# pour votre back end, Bridge peut être une très bonne solution puisqu’elle vous permet de partager vos bibliothèques entre front end et back end, ce qui est impossible avec une autre alternative (hormis Blazor). Vous gagnez en temps et en effort tout en recyclant vos bibliothèques.

C’est-ce que j’appelle du code écolo, tout se recycle.

Enfin, note importante, il ne faut pas oublier que les transpileurs, en plus d’ajouter des gros fichiers dans votre page (comme bridge.js), ne vont pas améliorer ses performances, bien au contraire. Ils amélioreront la qualité et la sécurité du code, oui, mais souvent au détriment de la rapidité. Si les performances sont vraiment un point critique de votre application, privilégiez du pur JavaScript bien organisé et optimisé.

Donc, pour résumé, Bridge est intéressant pour créer des SPA demandant beaucoup de lignes de code, et qui peuvent se permettre de manger un peu de performances. Et en plus de ça, je le recommande tout particulièrement si votre back end est déjà en C#, et si vous (et votre équipe) aimez .NET de manière générale.

Dans tous les cas, ce qui est sûr, c’est qu’aucune alternative à JavaScript ne justifie que vous n’appreniez pas ce langage. C’est le standard du Web (qu’on le veuille ou non) et il pourra toujours vous sauver la mise si jamais vous rencontrez des limitations avec d’autres technologies. Il vous permet en plus de vraiment comprendre l’output que vous produisez avec un transpiler. Passer à Bridge ou TypeScript sans connaître le JavaScript, c’est comme essayer de cuisiner un bœuf bourguignon sans savoir faire une omelette.


Et voilà, j’ai fait le tour concernant Bridge.NET, une technologies un peu obscure, mais que je trouve assez intéressante. Si vous êtes de cet avis, retrouvez le clicker game que j’ai fabriqué avec Bridge de A à Z ici accompagné de toutes les explications.

Et si ce n’est pas le cas, bon déjà vous devez vraiment avoir aimé mon article pour l’avoir lu jusqu’au bout (merci beaucoup !), mais surtout, je vous renvoie vers des technologies similaires à Bridge que je trouve tout aussi intéressantes :

  • TypeScript : un dérivé de JavaScript orienté objet et fortement typé, transpilant en JS.
  • Blazor Server : un framework ASP.NET vous permettant de créer du code front end en C# et de l’exécuter directement depuis le serveur.
  • Blazor WebAssembly : similaire à Blazor Server, vous permettant de créer du code front end en C# et de l’exécuter directement chez le client grâce à la technologie WebAssembly.

J’ai fait une vidéo de présentation sur Blazor (en particulier Blazor Server), allez la voir si le sujet vous intéresse.

Si vous voulez découvrir des nouvelles technologies comme Bridge ou celles citées juste au-dessus, allez jeter un coup d’œil à mon blog. Vous y retrouverez tout un tas d’outils et de conseils qui pourraient bien révolutionner votre carrière de développeur !

Et si vous avez besoin d’aide avec Bridge, ou que vous avez des choses à ajouter, des remarques ou des suggestions, utilisez l’espace commentaire juste en dessous. N’oubliez pas de partager l’article à vos amis et collègues qui continuent encore à écrire du JavaScript façon chef italien, sans savoir qu’il existe des solutions parfaites pour eux !


Accéder au bonus : Un clicker game avec Bridge.NET.