Je cherche à comprendre comment charger le navigateur embarqué de Java FX dans un client lourd. Je ne sais pas si ce projet fonctionne mais ce sera un premier pas vers l'obtention d'un PoC qui marche.
Je suis tombée sur cet autre repo qui a deux avantages :
Parfait pour installer des applications du PlayStore dans une sandbox quand on s'est dégooglisé. Je pense à Teams, Microchiotte Authenticator et Plantes vs Zombies (faut bien que la grande joue 😁)
— Liens directs
Merci à Kalvn pour le lien.
Avant ces vacances de Noël, on m'a confié la tâche de déterminer quelle techno utiliser pour coder plusieurs fronts.
J'avais regardé les frameworks SPA via Aurelia et Vue et les pages générées côté serveur via Twig que j'ai toujours adoré 😍.
Ce tuto de Kalvn tombe à point nommé puisqu'il complète très bien l'usage de la balise <template>
.
— Liens directs
Comment créer et utiliser des sprites SVG (c'est-à-dire fusionner plusieurs SVG en un seul fichier). Pour résumer...
1) Créer un fichier SVG vide
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none;">
...
</svg>
2) Dans une balise <symbol>
y migrer le contenu du SVG à intégrer au sprite sans oublier d'y reporter la viewBox en attribut de la balise <symbol>
.
Par exemple le SVG suivant :
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 95 95">
<defs>
<style>.cls-1{fill:#00dd7e;}</style>
</defs>
<title>8 Point Star</title>
<path class="cls-1" d="M83.59,63.91,97.5,50,83.59,36.09V16.41H63.91L50,2.5,36.09,16.41H16.41V36.09L2.5,50,16.41,63.91V83.59H36.09L50,97.5,63.91,83.59H83.59Z" transform="translate(-2.5 -2.5)"/>
</svg>
Sera intégré comme ceci :
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="icon-star" viewBox="0 0 95 95">
<path class="cls-1" d="M83.59,63.91,97.5,50,83.59,36.09V16.41H63.91L50,2.5,36.09,16.41H16.41V36.09L2.5,50,16.41,63.91V83.59H36.09L50,97.5,63.91,83.59H83.59Z" transform="translate(-2.5 -2.5)"/>
</symbol>
</svg>
3) Dans le même fichier, ajouter autant de balises <symbol>
qu'il y a de SVG à intégrer au sprite **en leur donnant des ID différents
4) Pour utiliser le SVG il suffit d'écrire ceci dans votre page HTML
<svg class="icon icon--red">
<use xlink:href="/path/to/sprite.svg#icon-star"></use>
</svg>
Le top du top c'est que le SVG sera mis en cache pas le navigateur, ce qui est une solution idéale pour un set d'icônes à la résolution accroissable (nouveau mot).
]]>Apprendre à se laver les mains.
— Liens directs
Je me mets sous le coude ce tuto coiffure pour quand ma petite dernière aura les cheveux suffisamment longs.
]]>Aujourd'hui j'ai relu un cours de @Kysofer qu'il prépare sur la bonne utilisation des monades en programmation fonctionnelle et ça m'a donné envie de le résumer en un cas d'école clair et simple.
Pour la petite histoire et depuis Java 8, je vois apparaître des Optionals
partout mais 99% des développeurs n'ont pas compris comment s'en servir (c'est pour cette raison que je dis souvent que la programmation fonctionnelle est un cancer métastasé, car une fois ces mauvaises pratiques installées, le code devient alors incurable). #Sadness
Bref, c'est partie pour une explication claire et courte... Notre cas d'école sera le suivant :
Une
Personne
possède uneDate de Naissance
, cette date contient elle-même uneAnnée de Naissance
qui contient à son tour une valeur (logée dans un Integer).L'objectif est d'imprimer l'année de naissance si elle existe sans jamais écrire le moindre 'if' pour l'exécution ci-après déclarée dans la méthode
main()
.
La méthode main()
:
class Main {
public static void main(String[] args) {
optionalPrintln(Optional.ofNullable(new Person(new BirthDay(new YearOfBirth(2000)))));
optionalPrintln(Optional.ofNullable(new Person(new BirthDay(null))));
optionalPrintln(Optional.ofNullable(new Person(null)));
}
}
La sortie attendue dans la console doit être celle-ci
2000
class Person {
private final BirthDay birthDay;
public Person(BirthDay birthDay) {
this.birthDay = birthDay;
}
public Optional<BirthDay> getBirthDay() {
return Optional.ofNullable(birthDay);
}
}
class BirthDay {
private final YearOfBirth year;
public BirthDay(YearOfBirth year) {
this.year = year;
}
public Optional<YearOfBirth> getYearOfBirth() {
return Optional.ofNullable(year);
}
}
class YearOfBirth {
private final int year;
public YearOfBirth(int year) {
this.year = year;
}
public Optional<Integer> getValue() {
return Optional.of(year);
}
}
Les 9-10ième des développeurs Java que je côtoie écriront ce genre de code pour la optionalPrintln(Optional<Person> option)
:
class Main {
// ...
public static void optionalPrintln(Optional<Person> option) {
if (option.isPresent()) {
Person person = option.get();
Optional<BirthDay> birthDay = person.getBirthDay();
if (birthDay.isPresent()) {
Optional<YearOfBirth> yearOfBirth = birthDay.get().getYearOfBirth();
if (yearOfBirth.isPresent()) {
Optional<Integer> year = yearOfBirth.get().getValue();
if (year.isPresent()) {
System.out.println(year.get());
}
}
}
}
}
}
C'est très moche, c'est très compliqué et ça n'est pas fonctionnel du tout ! Pire encore, certains développeurs écriront ceci :
year.ifPresent(it -> System.out.println(it));
à la place de ce dernier 'if' :
if (year.isPresent()) {
System.out.println(year.get());
}
tout en croyant coder en fonctionnel, or ça n'est pas le cas du tout non plus ! Croire que l'on fait bien alors que l'on fait mal, c'est en ce sens que la chose est pire AMHA.
La programmation fonctionnelle ne cherche pas à représenter des instructions, c'est-à-dire une succession d'actions techniques qui s'enchaînent mais a contrario, elle cherche à représenter un flux de conversion, c'est-à-dire le fait de passer d'un type A à un type B.
L'API permettant une telle prouesse réside dans le map
de la stream API, or cette fonctionnalité n'est pas applicable à un objet composé comme c'est le cas du Optional
puisqu'il s'agit d'un arbre à deux niveaux sur une seule branche.
Dans ce cas, il faut utiliser la méthode flatMap()
de la même API pour supprimer le niveau superflue de l'arbre et accéder directement à la donnée si elle n'est pas null
.
Ce qui donne le code suivant :
public static void optionalPrintln(Optional<Person> option) {
option.flatMap(it -> it.getBirthDay())
.flatMap(it -> it.getYearOfBirth())
.flatMap(it -> it.getValue())
.ifPresent(it -> System.out.println(it));
}
A chaque invocation de flatMap()
, cette méthode va jouer pour nous un optional.ifPresent(it -> ...)
afin de nous en décharger. Si rien n'est présent, alors l'évaluation du flatMap()
lui succédant ne se fera tout simplement pas car le flux d'instances à convertir d'un type à un autre type sera dépourvu de toute instance à convertir. #Malin
Et c'est comme cela que l'on code en fonctionnel avec les Optionals ! Le véritable but étant de ne jamais s'en servir explicitement.
Remarque :
La programmation fonctionnelle est extrêmement difficile car elle oblige les développeurs à passer du stade "je dis à la machine comment faire" au stade "je décris à la machine quoi transformer et vers quoi d'autre".
Depuis ces 20 dernières années, j'ai toujours constaté que moins de 5% des développeurs étaient capables de penser dans ce paradigme et parmi ce petit pourcentage, à peine la moitié s'en servira dans sa vie professionnelle.
]]>Je découvre le mot-clef expect
de Kotlin. Son objectif est de dire que pour une même classe, il va y avoir différentes implémentations en fonction de la plateforme.
Par exemple pour la classe (vide) :
expect class KMPDate(formatString: String) {
fun asString(): String
}
Nous aurons cette première implémentation pour Android :
actual class KMPDate actual constructor(formatString: String) { // 1
private val dateFormat = SimpleDateFormat(formatString) // 2
actual fun asString(): String {
return dateFormat.format(Date()) // 3
}
}
et cette seconde pour iOS :
actual class KMPDate actual constructor(formatString: String) { // 1
private val dateFormatter = NSDateFormatter().apply { // 2
this.dateFormat = formatString
}
actual fun asString(): String {
return formatter.stringFromDate(NSDate()) // 3
}
}
KPMDate n'est pas une interface mais bien une classe concrète avec plusieurs implémentions dites "platform-dependent" dans le même fichier.
Mieux encore, c'est compatible avec GraalVM et Kotlin native pour produire des binaires natifs (AMD64 et ARM64 principalement) compilés et linkés statiquement (+ compilation AOT + tree shaking pour les optims) sans avoir besoin d'une JRE d'installée sur l'environnement cible, donc parfait dans des conteneurs très légers par exemple :D
]]>Mais cet article est excellent !
Merci à @Sebsauvage pour sa doc et @Shikiryu pour le lien.
— Liens directs
@Guigui : super je me le note. Merci !
— Liens directs
J'avais déjà expliqué mon désamour pour Kafka ici mais comme toujours, le client est roi et des architectes poussent cet outil même si leurs besoins en terme de charge et de volume ne sont pas suffisamment élevés pour justifier Kafka.
Ici, un bon article expliquant les stratégies de partitionnement des topics Kafka. Merci à son auteur, ça m'aide.
P.S : au regard de ma critique vive de Kafka, cet outil possède un avantage qui est extrêmement intéressant : le découplage temporel, c'est-à-dire qu'en forçant l'asynchronisme des messages, Kafka retire du SI les problèmes d'indisponibilités des services appelés, et ça c'est une très bonne chose (que l'on peut toujours compenser par un cluster de micro-services + Kubernetes mais bon).
— Liens directs
A lire pour plus tard.
— Liens directs
Pour @Lenny et @Kysofer qui doivent se servir de Netty.
EDIT 5: un cinquière tuto ici.
EDIT 4 : un quatrième tuto ici.
EDIT 3 : un troisième tuto ici.
EDIT 2 : un deuxième tuto ici.
EDIT : je viens de tomber sur ce tuto et quand je lis ce genre de code :
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
public class WebSocketHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof WebSocketFrame) {
System.out.println("This is a WebSocket frame");
System.out.println("Client Channel : " + ctx.channel());
if (msg instanceof BinaryWebSocketFrame) {
System.out.println("BinaryWebSocketFrame Received : ");
System.out.println(((BinaryWebSocketFrame) msg).content());
} else if (msg instanceof TextWebSocketFrame) {
System.out.println("TextWebSocketFrame Received : ");
ctx.channel().writeAndFlush(
new TextWebSocketFrame("Message recieved : " + ((TextWebSocketFrame) msg).text()));
System.out.println(((TextWebSocketFrame) msg).text());
} else if (msg instanceof PingWebSocketFrame) {
System.out.println("PingWebSocketFrame Received : ");
System.out.println(((PingWebSocketFrame) msg).content());
} else if (msg instanceof PongWebSocketFrame) {
System.out.println("PongWebSocketFrame Received : ");
System.out.println(((PongWebSocketFrame) msg).content());
} else if (msg instanceof CloseWebSocketFrame) {
System.out.println("CloseWebSocketFrame Received : ");
System.out.println("ReasonText :" + ((CloseWebSocketFrame) msg).reasonText());
System.out.println("StatusCode : " + ((CloseWebSocketFrame) msg).statusCode());
} else {
System.out.println("Unsupported WebSocketFrame");
}
}
}
}
J'ai juste envie de pleurer (et je vais vous expliquer pourquoi). La programmation orientée objets reposent sur trois principes :
Le polymorphisme, c'est le fait qu'une classe fille puisse se faire passer pour sa classe mère. L'idée étant que l'on doit organiser notre code de telle sorte que nous puissions TOUJOURS utiliser les super-types (classe mère abstraite ou interface). Or dès que l'on doit ajouter des conditions du type truc instanceof Class
c'est que l'on passe à côté du principale intérêt du polymorphisme : ne jamais avoir besoin de dépendre des implémentations.
Soyons clair, dans un code orienté objet je n'ai jamais eu besoin d'écrire des instanceof
et de toute ma vie, ce n'a dû m'arriver qu'une ou deux fois et parce que je dépendais d'un code aussi vieux que Java lui-même !
Bref, si vous codez en Java et que vous avez besoin des implémentations, pis encore des instanceof
et des casts, alors c'est que vous pensez en procédural et non en objet. Et pour tout ceux qui souhaitent apprendre à penser en objet, je les renvoie aux formations de Kysofer (car il m'a promis une com' si vous y aller de ma part :D) et il y a la pré-collection automne de Sezane qui me fait grave de l’œil si vous voulez...
Article mis sous le coude pour tout à l'heure.
— Liens directs
J'avais entendu le nom il y a quelques années mais n'ayant pas plus creusé le concept je l'avais oublié. Le hasard du destin me fait retomber dessus aujourd'hui. Bref il s'agit de 9 règles de programmation à appliquer.
En résumé :
Globalement, je le fais sans m'en rendre compte, mes classes sont minuscules (20 lignes en moyennes). Éventuellement le ELSE m'est encore utile mais c'est vrai que programmant en fail-first je lui préfère un throw direct et donc qu'il n'apparaît vraiment pas souvent.
]]>Note personnelle : je n'aime vraiment pas du tout la syntaxe de Rust, mais vraiment :(. À chaque fois que j'en fais je meurs un petit peu. Après je maintiens qu'il s'agit d'un des meilleurs langages du marché à cette heure et une tendance de fond qui me pousse à prendre la vague.
Bon je vais reprendre le début du kata @Kysofer (qui va me faire intervenir dans ses formations) pour montrer comment il programme en OOP "pure" avec Rust en mettant en place une encapsulation stricte (à la Yegor Bugayenko). Le poste se fera en plusieurs parties, cette première étape consistant à montrer comment fonctionnent les trait
, les struct
et la notion de value borrowed
pour les débutants.
Objectifs du kata :
value borrowed
.Code :
#![allow(non_snake_case)] // Oui je viens du monde Java/Kotlin
// Structures
struct Couple {
opA: i32,
opB: i32,
}
struct Triplet {
opA: Couple,
opB: i32,
}
// Interface
trait Addition {
fn add(&self) -> i32;
}
// Implementations
impl Addition for Couple {
fn add(&self) -> i32 {
return self.opA + self.opB;
}
}
impl Addition for Triplet {
fn add(&self) -> i32 {
return self.opA.add() + self.opB;
}
}
Exécution :
Pour instancier et exécuter le code il faut écrire ceci. Tout marche, aucun problème.
fn main() {
let additionA = Couple { opA: 1, opB: 2 };
println!("Couple add : [{}]", additionA.add()); // Print 3
let additionB = Triplet {
opA: additionA,
opB: 3,
};
println!("Triplet add : [{}]", additionB.add()); // Print 6
}
La petite difficulté (el famoso "value borrowed") arrive dès que l'on initialise les deux structures l'une derrière l'autre :
fn main() {
let additionA = Couple { opA: 1, opB: 2 };
let additionB = Triplet {
opA: additionA,
opB: 3,
};
println!("Couple add : [{}]", additionA.add()); // NE COMPILE PAS
println!("Triplet add : [{}]", additionB.add());
}
En réalité, au moment du premier println!()
, la variable additionA
n'est plus dans l'espace courant mais a été empruntée par Triplet
, elle se retrouve donc utilisable mais uniquement par lui. Alors soit on réordonnance le code (ce que j'ai fait dans la première exécution qui fonctionne) soit on indique que Triplet
restitue la variable qu'il a emprunté (je montrerai plus tard comment faire).
Bref, jusque là rien de transcendant nous remarquerons quand même que Triplet
contient un Couple
(c'est-à-dire une structure) et non une Addition
(c'est-à-dire une interface) ce qui matérialise un couplage fort entre les types et donc l'impossibilité de programmer par contrat (c'est-à-dire en masquant les implémentations et en protégeant l'encapsulation des données contenues dans la structure Couple
).
C'est là qu'arrivera la second difficulté dont je parlerai aussi plus tard : comment calculer dynamiquement les tailles des implémentations des traits pour les utiliser en tant qu'attribut d'une structure.
Avis personnel : depuis quelques mois que je m'amuse avec Rust je peux dire que globalement j'aime ce langage mais cela ne m'empêche pas de le trouver pauvre sur pas mal de ses aspects (au sens paradigme de programmation).
Dans ce qui me déplaît, je mettrais la forte emprunte qu'il retire C et du C++, notamment leur style procédurale omniprésent (on ne code plus comme en Pascal en 2020, damned), l'encapsulation découragée totalement (en ce sens Rust n'est pas objet pour un sous, et la programmation en structure-first est un anti-concept, encore une fois cf. Elegant Objects de Yegor Bugayenko) et pour ma plus grande tragédie, une syntaxe que je trouve lourdingue car s'appuyant sur beaucoup de symboles ou trop peux expressive (je suis navrée pour ceux qui pensent que i32 et u32 sont de bonnes façons d'écrire des entiers signés ou non en 2020).
Encore une fois, la syntaxe de Kotlin (sauf le sucre syntaxique du préfixe get/set et les equals methods), l'API immutable de Kotlin, la gestion des Threads/KoRoutines de Kotlin, le null-check de Kotlin, le tout mêlé au Owernship de Rust, à la performance du binaire produit par son compilateur, à sa capacité à gérer du bas niveau, tout ceci en ferait sûrement l'un des langages les plus efficaces et fiable du siècle.
Je prie pour que Kotlin Native soit un "game changer" notamment pour qu'il parvienne à s'élever au niveau de Rust en terme de performances et de protection contre les race-conditions.
]]>Je me le note, merci à JcFrog pour le lien.
— Liens directs
Alors ce tutoriel est très bien pour ceux qui souhaitent apprendre la syntaxe du langage par contre en aucun cas il ne correspond au titre de l'e-book dont il est un chapitre : "Introduction au langage Kotlin, découvrir les notions avancées de la programmation orientée objet".
En rien l'article ne parle d'OOP et de ses concepts avancés, bien au contraire il met en avant les aspects du langage qui poussent à la programmation procédurale réalisée à partir de structures de données façon C/VB/PL-SQL et je m'explique.
Lorsque vous créez une classe avec des getters et des setters, vous ne faites ni plus ni moins que de créer une structure avec des attributs public déguisés en attributs privés. Fondamentalement, même si c'est au travers d'une méthode, vous permettez à n'importe quelle autre classe de violer l'aspect le plus fondamental de l'OOP : l'encapsulation (je vous invite à suivre les tutos de @Kysofer sur le sujet, c'est un grand gourou du domaine).
D'ailleurs, et pour reprendre l'un de ses cours, l'encapsulation c'est deux composantes :
Avec un exemple simple, si j'ai cette horreur (du point de vue de l'OOP) :
val name:String = person.getName()`
person.setName("my-name")`
Alors cela revient exactement au même que d'écrire :
val name:String = person.name`
person.name = "my-name"
Cela est tellement la même chose que Kotlin l'assume et génère à la compilation, à partir des getters/setters, le code du second exemple pour permettre l'accès en public aux attributs.
Mais là n'est pas le problème, en effet le vrai problème est que si je venais à changer le type interne de name
pour le passer d'une String
à un nouveau type, par exemple appelé Name
, alors il faudra que je modifie TOUS LES APPELS EFFECTUÉS à getName() car les codes appelant s'attendent à une String, rien n'est encapsulé, rien n'est masqué, a contrario toute la représentation interne fuite à travers les getters/setters et les gens appellent cela innocemment de l'OOP alors que ça n'en est pas du tout : ce sont des struct
déguisées en objets.
La solution consiste à n'utiliser que des interfaces car par essence, une interface ne peut pas avoir d'attributs. Alors certes les dérives depuis Java 8 et certains anti-patterns de la programmation fonctionnelle (du point de vue de l'OOP toujours) ont eu tendance à modifier le langage mais dans la pratique, c'est vraiment une très mauvaise idée de mettre des attributs/constantes dans une interface.
Je sais que @Kysofer et @Lenny réfléchissaient à faire des tutos sur l'OOP sur Youtube/PeerTube, j'espère que ce post va les motiver à passer à l'acte. D'ailleurs je partagerai toutes vos vidéos mes chéris :) #Waiting
]]>Il y a plusieurs façons de faire, mais lorsqu'il s'agit de remplir un placeholder d'un input text, cette méthode marche plutôt bien :
<input type="text" i18n="[placeholder]my-i18n-key" />
L'attribut qui se fera injecter le i18n doit être mis entre crochet [ ]
et s'il y en a plusieurs, alors ils doivent être séparés par des virgules s'ils possèdent la même valeur ; ou par des points-virgules s'ils possèdent chacun une valeur différente.
Par exemple :
<!-- Les deux attributs posséderont la même valeur i18n -->
<input type="text" i18n="[placeholder,aria-placeholder]my-i18n-key" />
<!-- Chaque attribut possédera sa propre valeur i18n -->
<input type="text" i18n="[placeholder]my-i18n-key;[aria-placeholder]my-other-i18n-key" />
Aurelia est un framework à la fois simple et élégant.
— Liens directs
Un tuto interactif sympa sur les flexbox que m'a filé @Kim aujourd'hui.
— Liens directs
Problème :
Solution :
Il vous suffit d'utiliser la commande suivante :
OUTPUT_FILE="./mon_fichier"
URL="https://monhost/my-download.file"
wget --continue --tries=inf -O "${OUTPUT_FILE}" "${URL}"
Explication :
--continue
indique à wget de reprendre là où il s'est arrêté.--tries=inf
indique à wget de réessayer autant de fois qu'il le faudra (la limite étant à 20 essais par défaut).-O
indique à wget où écrire le fichier à télécharger.Pour @Chlouchloutte, un tuto simple montrant comment mocker l'objet Context
des routes de JavaLin avec MockK. Mais normalement Mockito en direct devrait aussi faire le café.
Aurelia est un framework orienté SPA plus rapide que React ou Angular sur quasiment tous les modes de rafraîchissement du DOM. Ici Jeremy Danyow tient un podcast où il explique les bases des mécanismes de binding du framework.
@Chlouchloutte si tu recherches des snippets de code je te recommande d'aller sur le GitHub d'Aurelia dédié aux benchmarks des différents mécanismes de mise à jour du DOM mais j'ai l'impression que le podcast est la meilleure façon de tout comprendre (1h par contre, désolée).
]]>Un tuto expliquant comment fonctionne la balise vidéo de HTML5. Attention, le tuto n'est pas parfait, je recommande de le compléter par celui-ci de l'agence AlsaCréations qui explique les "vrais" attributs qu'il faut mettre dans la balise <video>
(vrai au sens W3C du terme) et éventuellement celui-ci du site OpenClassRooms.
Et un lien intéressant portant sur les connexions P2P en WebRTC avec HTML5.
— Liens directs
Comment dessiner des yeux de filles façon manga ? Marrant, je vais essayer.
Un autre tuto ici.
— Liens directs
Un bon article expliquant les bases de Vert.x afin de créer une API RESTful.
— Liens directs
Le blog d'Human coders qui parle de tout avec plein de tutos
— Liens directs
Un bon tuto sur le fonctionnement d'un perceptron. Pour tous ceux qui souhaitent se mettre à l'IA.
— Liens directs
Je découvre l'outil grâce à Kalvn (qui tient toujours sa place parmi mes 3 shaarlistes préférés <3).
Et voici un tuto que propose Kalvn sur Artillery.
— Liens directs
Pour @Chlouchloutte et surtout ton ami qui découvre Prolog.
Les mots clefs important en Prolog :
Je dois accompagner des équipes dont les projets vont tourner sur Bootstrap 3 et à terme Bootstrap 4. Je me mets de côté cette documentation (car je suis team Bulma).
Encore une fois, merci à Kalvn qui a toujours le bon lien au bon moment (à croire que nous travaillons au même endroit sans le savoir).
— Liens directs
Les layouts en CSS pour @Animal
— Liens directs
GraphQL est une alternative très sérieuse à RESTful. Ce qui me pose encore problème pour l'adopter définitivement c'est la carence en frameworks afin de parser/lexer les requêtes reçues via HTTP et d'en assurer le mapping côté base de données.
Ici GraphQL Java apporte une première pierre à cet édifice avec un exemple d'implémentation simple mais concret.
— Liens directs
Les liens de Kalvn sont décidément bien trouvés ! Ici des tutos animés sur les Flexbox des CSS.
@Chlouchloutte @Animal il est temps de vous y mettre !
Source du lien.
— Liens directs
Toute une documentation très bien faite sur les coroutines en Kotlin et les mécanismes de synchronisation que le langage fourni. Vraiment très bien pour apprendre à tirer partie des CPU multi-coeurs.
— Liens directs
Eviter les problèmes de débutants en Rust
— Liens directs
Un très bon tuto bricolage. Je dois faire des travaux à la maison ur ur ur.
— Liens directs
Un tuto sur le fonctionnement de WebRTC.
— Liens directs
Merci !
Un autre lien : https://github.com/RomuloOliveira/commit-messages-guide/blob/master/README.md
]]>Super tuto à base d'exemple et de cas concrets au sujet des FlexBox et des principaux problèmes / layouts "résolus".
Pour @Animal & @Chlouchloutte
— Liens directs
Un tuto simple sur Angular 7 et son MessageService
qui agit comme un bus applicatif permettant la transition des messages entre les composants.
@Chlouchloutte toi qui est une grosse-biloute Angular. Qu'en penses-tu par rapport aux EventEmitter
?
Edit : j'ai trouvé un début de réponse sur cette StackOverflow expliquant que les EventEmiter constituent une API interne d'Angular qui peut être dépréciée à tout instant. Il est clairement recommandé d'utiliser l'API de RxJs à la place. => Ok
— Liens directs
Un tuto en français sur les modules de Java 9.
— Liens directs
Je retiens cette structure :
// Tout ce qui va concerner les tests end to end
|- e2e/
|----- app.e2e-spec.ts
|----- app.po.ts
|----- tsconfig.e2e.json
// les dépendances avec npm
|- node_modules/
// l'endroit où les fichiers de build seront mis
|- dist/
// Le dossier où vous allez modifier vos fichiers de code
//Là où va se trouver vos composants, services, etc..
|- src/
|----- app/
|----- app.component.css|html|spec.ts|ts
|----- app.module.ts
|----- assets/
|----- environments/
|----- environment.prod.ts|ts
|----- favicon.ico
|----- index.html
|----- main.ts
|----- polyfills.ts
|----- styles.css
|----- test.ts
|----- tsconfig.app.json
|----- tsconfig.spec.json
|----- typings.d.ts
// la configuration globale de votre application
|- .angular-cli.json // the main configuration file
|- .editorconfig // editorconfig which is used in some VS Code setups
|- .gitignore
|- karma.conf.js
|- package.json
|- protractor.conf.js
|- README.md
|- tsconfig.json
|- tslint.json
]]>This tutorial walks us through the process of creating a simple REST controller with Spring Boot
Parce que je vais refaire du Spring Boot et du Hibernate 😥. Encore que Spring Boot ça va encore, c'est juste que ça rame au startup. D'ailleurs, nous devrions l'appeler Spring SlowBoot, ce serait plus parlant à mon avis.
— Liens directs
Merci à Liandri qui a posté ce tuto sur Hugo (excellent CMS générant des fichiers statiques pour ceux qui ne le connaîtraient pas).
— Liens directs
Comment construire la palette de couleur de son site web.
— Liens directs
Parce que cela nous est arrivé la semaine dernière au bureau avec la vis de la porte d'entrée.
— Liens directs
Meilleur site web que je n'ai jamais utilisé pour apprendre Git. Clairement, c'est une perle !
— Liens directs
Un tuto expliquant HBase et le concept de bases orientées colonnes (et non lignes / n-uplets).
— Liens directs
Excellent article sur la commande ansible-inventory
.
@Animal : je te recommande sa lecture.
— Liens directs