Communauté
Même si j’expose pas mal de trucs au reste du monde (articles, démo, tutos…) j’ai jamais vraiment « contribué » à la communauté via des projets open source. Jusqu’à peu.
Faut bien commencer 🙂
En vrai, je m’en faisais tout une montagne. Pour moi faire un package nuget était compliqué. J’avais tord. En fait ça n’a rien de compliqué. Ce qui est vraiment chaud, c’est de gérer la maintenance et « animer » la communauté (répondre aux questions, faire un readme, corriger etc.)
Blazor
Je travaille sur un projet avec la techno Blazor depuis quelques mois. Je kiffe.
C’est un projet WASM. Donc qui utilise la WebAssembly. Pour moi c’est le futur. Je pense qu’on va vite se passer de Javascript d’ici 5 ans. Personnellement j’en ai plein le cul de ce language. Par contre respect, il a contribué à rendre nos app web carrément plus sympas.
Et donc on peut pas encore s »en passer vraiment, car l’essentiel des supers libs d’aujourd’hui son écrite en JS. Même si certain éditeur commence à sortir des versions WebAssembly. Mais c’est encore trop rare.
Donc faut encore faire avec. Et Blazor permet de faire un pont entre notre code C# et Javascript.
Ok certain vont me dire, à quoi ça sert, autant tout faire sur du JS. Oui. Mais sans moi, pour les raisons du dessus. Donc moi je veux faire du C#. Alors comment faire ? Faut coder un wrapper qui va nous servir d’intermediaire.
Mon premier package nuget
J’avais besoin d’un lecteur de QR code dans mon appli. J’ai cherché et j’ai rien trouvé sur le gestionnaire de package Nuget. Alors j’ai décidé de faire le mien. Et puis je me suis dit que ce serait sympas de le partager. Et ça donne ça :
Repo Github : https://github.com/YannVasseur35/ReactorBlazorQRCodeScanner
Package Nuget : https://www.nuget.org/packages/ReactorBlazorQRCodeScanner/
Création d'une librairie Blazor
La première chose à faire est de créer un nouveau projet « Bibliothèque de classes Razor »
Si on ouvre le fichier projet, voici ce que j’ai
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.0.11" />
</ItemGroup>
</Project>
Composition d'une lib razor (blazor)
Voici un exemple de projet vide :
Si on analyse une lib razor, voici ce qu’on y trouve :
Component1.razor
C’est votre composant visuel qui sera afficher dans vos pages. Suffira d’appeler <Component1/> dans votre page razor. Il affichera un cadre par défaut. A vous de customiser votre composant pour qu’il affiche ce que vous voulez qu’il affiche.
ExampleJsInterop.cs
Comme son nom l’indique, c’est un exemple de ce que vous pouvez faire à minima avec du code C# qui utilise du javascript. Dans son contructeur :
private readonly Lazy<Task<IJSObjectReference>> moduleTask;
public ExampleJsInterop(IJSRuntime jsRuntime)
{
moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>(
"import", "./_content/RazorClassLibrary1/exampleJsInterop.js").AsTask());
}
On voit que ça charge un fichier js. Notez aussi le chargement « Lazy » qui va permet de ne charger les éléments de notre lib qu’au moment où c’est nécessaire.
Donc quelque part, si vous n’utilisez pas le composant dans vos premières pages, il ne sera pas chargé (téléchargé pour le client). S’en suis dans le code une seule méthode :
public async ValueTask<string> Prompt(string message)
{
var module = await moduleTask.Value;
return await module.InvokeAsync<string>("showPrompt", message);
}
Ici on nous présente un méthode très simple pour afficher un prompt JS. On appelle, via module.InvokeAsync la méthode javascript « showPrompt » et on lui passe un paramètre « message ».
exampleJsInterop.js
export function showPrompt(message) {
return prompt(message, 'Type anything here');
}
Le code JS est super simple. On lance un prompt tout bête avec le message qu’on a en paramètre.
Voilà pour la présentation d’un composant blazor.
Intégration
Maintenant que l’on a un composant blazor on va l’utiliser dans notre app web WASM.
Suffit d’ajouter une référence de projet dans notre projet client.
ensuite dans une page, par exemple index.razor, on ajoute ceci :
@page "/"
@using RazorClassLibrary1
<Component1 />
Visuellement ça donnera ceci :
Ajoutons un peu de code à notre page pour jouer avec un bouton :
@page "/"
@using RazorClassLibrary1
@inject IJSRuntime _jSRuntime
<Component1/>
<button onclick="@Show()">Click me</button>
@code{
private ExampleJsInterop? _exampleJsInterop;
protected override void OnInitialized()
{
_exampleJsInterop = new ExampleJsInterop(_jSRuntime);
}
protected async Task Show()
{
await _exampleJsInterop.Prompt("coucou");
}
}
On vient de lancer du js avec du C#.
Scanner de QR Code.
Pour revenir à mon besoin initiale, je dois pouvoir scanner un QR Code. Ya pas encore de lib nuget mais y’en a quelques une sous javascript, dont jsQR https://github.com/cozmo/jsQR
La lib peut faire plein de chose, moi j’ai besoin de récuperer que la lecture du code QR. Pour cela j’ai ajouté une Action (delegate) à mon composant pour que lorsque le JS trouve un QR code et arrive à le lire, cela déclanche (un Invoke) une méthode dans mon code. Le but n’est pas de décrire comment j’ai fait, le code source est dispo ici :
https://github.com/YannVasseur35/ReactorBlazorQRCodeScanner
J’ai bossé comme avec le précendent projet, en « local » à savoir que mon projet « lib blazor » est ajouté à mon projet blazor client.
Pour que ce soit plus simple, pour moi et pour le reste du monde, il faudrait faire un package nuget et l’importer depuis nuget.org
Le Package
Et c’est la que je me faisait tout une montagne (alors que c’est plus simple que de publier une app Android ou pire Apple). Il suffit de taper une commande :
dotnet pack
Et c’est tout 🙂
Bien entendu il faut aussi donner quelques informations sur le package. Ceci est fait dans le fichier projet de la bibliothèque de classe razor. Voici ce que j’ai mis pour mon package de scan de QR code.
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<PackageId>ReactorBlazorQRCodeScanner</PackageId>
<Version>1.0.5</Version>
<Authors>Yann Vasseur</Authors>
<Company>reactor.fr</Company>
<PackageTags>Blazor;Reactor;QRCode;ScannerQR Code</PackageTags>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.0.4" />
</ItemGroup>
</Project>
Et bim on a un fichier ReactorBlazorQRCodeScanner.1.0.5.nupkg dans votre bin/debug
Push sur nuget.org
Pour publier en ligne, il vous faut un compte sur nuget.org. Ensuite il va vous falloir une clé api. https://www.nuget.org/account/apikeys
Quand c’est fait, il restera une étape, taper cette commande (dans le dossier ou se trouve votre package)
dotnet nuget push ReactorBlazorQRCodeScanner.1.0.5.nupkg –api-key VOTRE-CLE-API –source https://api.nuget.org/v3/index.json
README.MD
Je crois que ce qui a été le plus long, c’est de rédiger un readme en markdown.
Je me suis inspiré d’un modèle de readme, trouvé sur le net.
Ce readme est dans le projet ce qui me permet de le mettre en ligne sous github; Il faut penser à mettre une référence url du raw de ce fichier de github sur nuget.org pour chaque version.
Stats et retour
Honnêtement j’en attendais rien. Mais j’ai eu des retours et des demandes sur mon code. Quelqu’un s’est même proposé d’améliorer qq fonctionnalités. J’ai fait de même ensuite. L’intérêt de l’open source !
Et je suis très étonné de voir que le package est téléchargé,
Comme quoi il y avait un besoin ! Mais du coup ça créer une forme de responsabilité. Ce dont j’étais pas vraiment prêt. Et c’est un peu de boulot en fait tout ça !