J’ai trouvé un moyen de rendre Flutter plus agréable… avec F #
Flutter semble gagner dans les frameworks multiplateformes avec sa facilité d’utilisation, son support communautaire, ses fonctionnalités, etc. Il bat d’autres frameworks, mais je ne l’apprécie toujours pas autant que je pense que je devrais/vouloir.
J’utilise Flutter depuis le premier alpha public en 2017 et je l’utilise encore aujourd’hui. Depuis j’essaie de l’aimer mais en vain. Je n’arrive même pas à l’aimer. J’ai créé des applications qui sont sur les magasins et qui fonctionnent très bien ; J’ai mon propre projet SaaS construit avec, et je crains toujours chaque fois que je dois ajouter une nouvelle fonctionnalité ou corriger un bogue. Pourquoi? Dart (surtout)… Je déteste ce putain de langage. Les seules choses que j’aime c’est async/await
et les fonctions de niveau supérieur. C’est tout.
Il y a environ un an, j’ai commencé à jouer avec F#, et j’ai tout de suite adoré. Sa programmation fonctionnelle, sa syntaxe concise, l’inférence des types, les types en général… quel bonheur. Vous pouvez écrire du code fortement typé qui ressemble à un typage dynamique.
J’aime de plus en plus la saisie dynamique, mais c’est une histoire pour un autre jour (indice : TDD). J’ai sauté sur la première occasion de l’utiliser dans mon projet sur le backend — puis j’ai découvert Fable. Fable est un compilateur F# -> JavaScript, mais qu’est-ce que cela a à voir avec Flutter et Dart ? Eh bien… dans la version 4.0, Fable apporte le support F# -> Dart !
Nous pouvons écrire du code F #, le compiler dans Dart et l’utiliser comme code Dart normal. Au moment d’écrire ces lignes, Fable ne prend pas tout en charge, mais c’est presque terminé. Vous pouvez voir son progression sur ce lien.
Avant d’entrer dans le comment, je vais parler du pourquoi. Pourquoi utiliser un outil tiers pour faire ce que vous pouvez déjà faire immédiatement et sans risques potentiels ?
Je n’aime pas Dart, donc c’est une évidence pour moi, mais je vais vous donner quelques exemples.
Exemples
Peu importe ce que vous essayez et ce que vous faites, il n’existe pas de moyen simple ou élégant d’écrire des classes de données dans Dart. Pourquoi? Parce que vous devez définir votre propre equals
et hashCode
implémentations. Dart compare par référence et non par valeur.
Ce code utilise congeléune bibliothèque qui utilise la génération de code pour vous aider.
Ça n’a pas l’air trop mal ? Faux.
Vous voyez part 'user.freezed.dart';
, @freezed
, with _$User
, UserAuthenticated
, UserAnonymous
? Mais attendez, il y a plus. Vous devez ajouter une dépendance, écrire le code ci-dessus, déclencher la génération de code à partir du terminal, et sans oublier, cela créera un dossier séparé pour vous. Ouais. Parce que le code est trop long, vous pouvez le vérifier par vous-même en utilisant ce lien essentiel.
Si vous voulez la sérialisation/désérialisation JSON, vous obtenez un autre fichier généré… ah, c’est juste un gâchis.
Inutile de dire que c’est moche.
Mais nous n’avons pas besoin d’une bibliothèque pour une classe simple comme celle-ci.
C’est surtout la même chose.
Note: congelé améliore l’expérience de développement lors de la création et de l’utilisation de classes de données, d’unions, de copies, etc.
Vous devez mettre à jour ==
et hashCode
méthodes chaque fois que vous ajoutez un champ/une propriété. Nous pouvons faire mieux. En F#, cela ressemble à ceci :
C’est ça? Oui c’est ça. Lorsque vous exécutez ceci via Fable, vous obtenez ce qui suit :
Plus ou moins la même chose que nous avons écrit plus tôt. Vous obtenez ==
et hashCode
remplace. C’est tout ce que vous voulez/besoin dans Dart mais avec une syntaxe F # beaucoup plus agréable. La meilleure partie est que vous n’aurez jamais à regarder ce code, juste un bon code F#. Je vais vous montrer comment générer Dart à partir de F # en une seconde.
BLOC est une bibliothèque très populaire pour la gestion d’état, et je l’utilise dans mon projet. Pour utiliser BLOC en F #, j’aurais besoin de créer des liaisons, etc., et je ne l’ai pas fait parce que je ne sais pas encore comment, alors j’ai écrit à peu près la même chose sans utiliser de bibliothèques. Redux ancien uni. BLOC est Redux, qui est Elm Architecture, et F # a une implémentation bien meilleure et plus propre.
Ceci est un article informatif. Je simplifierai les choses pour plus de lisibilité afin de transmettre mes idées sans avoir besoin de connaissances techniques. J’entrerai dans les détails et vous montrerai comment écrire une application Flutter uniquement en F # dans mon prochain article.
Pour l’instant, regardons un autre exemple et voyons la différence.
C’est un beau code, non ? Zéro code gras, rien de redondant, et c’est parfaitement lisible. Maintenant, lorsque vous exécutez ceci via Fable, vous obtenez le code suivant. S’il vous plaît cliquez sur ce lien pour voir l’essentiel.
Oui, je sais que c’est du code généré, donc c’est plus moche qu’il ne le serait si je/vous l’écriviez, mais comme indiqué ci-dessus, ce n’est pas si différent. La plupart du temps, la dénomination est différente. Imaginez cela avec congelé — si chaque classe/type était dans un fichier séparé, vous auriez huit fichiers supplémentaires contenant le code généré. Attention, ce code n’inclut pas StateStore/Cubit/Bloc, ce qui représenterait environ 10 lignes en F# et plus en Dart. Il n’y a pas d’injection de dépendance, mais j’en parlerai dans le prochain article.
Peut-être que je vous ai convaincu, peut-être que vous êtes simplement curieux, ou peut-être que vous aimez déjà F# et que vous souhaitez l’utiliser pour le développement mobile. Je ne sais pas, mais voyons comment compiler F # en Dart et exécuter notre application Flutter.
- Vous avez un projet Flutter existant.
- Vous souhaitez construire un tout nouveau projet.
C’est pareil pour les deux approches. Vous avez besoin des éléments suivants :
- IDE pour Flutter -> Android Studio ou VS Code
- IDE pour F# -> Intellij Rider ou Visual Studio
- .NET installé
Ouvrez votre IDE F # et créez un nouveau projet F # dans votre projet Flutter. Appelons-le fsharp
.
Créer un .config
répertoire à l’intérieur du projet, et à l’intérieur de celui-ci, créez un dossier appelé dotnet-tools.json
qui contient les éléments suivants :
{
"version": 1,
"isRoot": true,
"tools": {
"fable": {
"version": "4.0.0-theta-018",
"commands": [
"fable"
]
},
}
}
Vous pouvez utiliser NuGet pour ajouter des packages F#.
Ouvrez votre terminal et exécutez deux commandes l’une après l’autre :
dotnet tool restore
dotnet fable watch YOUR_F#_PROJECT_DIR_NAME -o lib --lang dart
Dans la deuxième commande, lib
est la destination du code compilé, c’est-à-dire votre lib
Répertoire Flutter.
C’est ça. Vous avez maintenant un code Dart que vous pouvez utiliser normalement.
Très bien, cela conclut cette pièce. Je serais heureux de savoir ce que vous pensez de cette approche. Je suis intéressé par ce que pensent les amateurs de Flutter, et bien sûr, si vous êtes un développeur F #, est-ce que cela a l’air plus attrayant que Fabuleux ou alors XamarinName?