features · Sep 3, 2014

Quire : créer une grande application avec Dart

✦
Traduit par IA
· Voir en anglais

Application Quire développée avec le langage de programmation Dart

Dernière mise à jour : 28 mai 2026

TL;DR

Quire (53 992 lignes, 1 620 Ko de Dart) a été créé en 2014 avec Dart des deux côtés, client et serveur, en utilisant DQuery et Bootjack plutôt qu’AngularDART ou Polymer.dart pour un contrôle plus fin du DOM. Les choix fondateurs (typage fort sur toute la pile, modèles de données partagés entre client et serveur, boucle d’événements côté serveur et tree shaking pour le JS généré) tiennent toujours la route en 2026.

Quire n’est pas la première application web écrite en Dart, et ne sera pas la dernière, mais c’est peut-être la première à s’appuyer autant sur Dart, côté client comme côté serveur.

Logo du langage de programmation Dart et framework de l’application web Quire

C’est un gestionnaire de tâches amusant, doté d’une structure arborescente jusqu’au cœur. Le projet compte 53 992 lignes, soit 1 620 Ko de code Dart, construit avec quelques bibliothèques open source de la communauté.

Qui a créé Quire ?

Avant de nous lancer dans ce projet, nous étions des passionnés de Dart, connus sous le nom d’équipe Rikulo, et nous avions déjà publié plusieurs bibliothèques Dart : framework d’interface, bibliothèque d’interface, serveur web, serveur de messagerie, client de base de données, etc.

Nous étions enthousiastes quant à l’avenir de Dart dès sa sortie en 2011, et nous avons tout de suite commencé à l’utiliser sur de petites parties de projets. Nous avons fini par construire une application complète, écrite majoritairement en Dart. Nous aimerions partager humblement une partie de notre expérience, dans l’espoir de vous éclairer sur le développement en Dart.

Pourquoi Quire a-t-il choisi Dart plutôt que JavaScript ?

Les raisons de choisir Dart sont nombreuses. Voici les plus importantes pour nous :

  • Le système de typage fort de Dart nous protège d’innombrables petites erreurs. Dart Editor, l’IDE officiel, signale rapidement les erreurs de type, propose l’autocomplétion et facilite le suivi du code.
  • Nous trouvons le modèle d’héritage par classes beaucoup plus intuitif que le modèle prototypal.
  • Dart permet d’utiliser le même langage côté client et côté serveur, avec le même modèle de données et la même base de code.
  • Dart corrige la plupart des pièges de JavaScript. Il n’est pas parfait sur ce point, mais il règle 99 % des mauvaises surprises d’autrefois.
  • Dart propose dès aujourd’hui quelques fonctionnalités populaires de JavaScript Harmony : Future (promesses), fonctions fléchées, etc.
  • Dart s’appuie sur une équipe solide, avec de nombreuses bibliothèques officielles de qualité et des API bien organisées. Dart évolue encore, mais sa spécification est déjà assez stable.
  • Côté serveur, nous préférons le modèle de boucle d’événements au multithreading.
  • Dart effectue du tree shaking lors de la compilation vers JavaScript. (Voir plus bas.)

Choisir Dart a aussi des inconvénients :

  • La communauté Dart est bien plus petite que celle de JavaScript.
  • La communication entre Dart et JavaScript n’est pas triviale.
  • Il est plus difficile de créer des polyfills d’API dans un langage fortement typé.
  • Les performances de Dart Editor ne sont pas encore optimales pour un grand projet.

Grâce au typage fort, écrire en Dart est bien plus fiable qu’en JavaScript. Dart est aussi moins verbeux que Java, et parfois (avec les expressions de fonction, par exemple) même moins que du JavaScript pur. En général, travailler avec Dart est agréable, à quelques exceptions près :

  • Un champ final doit être initialisé dans la liste d’initialisation, avant le corps du constructeur.
  • La spécification des mixins est encore assez immature, et elle ne sera pas corrigée avant la version 2.0.
  • Pas de paramètre de type générique pour les déclarations de fonction, uniquement pour les classes. (Cela alourdirait évidemment le travail du compilateur.)

Comment Dart fonctionne-t-il côté client ?

Tant que la machine virtuelle Dart n’est pas intégrée à Chrome, il faut livrer le produit en le compilant en JavaScript. De nombreux langages se compilent en JavaScript, mais Dart se distingue par quelques avantages supplémentaires.

  • En développement, nous exécutons Dart nativement sur Dartium, un navigateur dérivé de Chromium avec une machine virtuelle Dart intégrée. Aucune compilation n’est nécessaire à cette étape, ce qui nous épargne d’innombrables interruptions.
  • Pour les tests et la production, nous compilons en JavaScript et l’exécutons sur tous les grands navigateurs. Le compilateur Dart vers JavaScript effectue du tree shaking, qui supprime le code inutilisé du résultat. Cela réduit considérablement la taille de notre code JavaScript.

Pourquoi utiliser Dart côté serveur ?

Dart côté serveur n’a jamais été un sujet brûlant dans la communauté Dart, mais nous le considérons comme un excellent candidat pour la programmation serveur, parce que :

  • Un service web, de par sa nature asynchrone, s’accorde très bien avec le modèle de boucle d’événements (plutôt que le multithreading).
  • Le code serveur exige bien plus de robustesse et de sécurité que le code client. Un langage fortement typé est ici très précieux.

À lire aussi : Quire obtient la certification ISO pour protéger vos données — la même exigence de robustesse et de sécurité côté serveur se retrouve des années plus tard dans la certification officielle de protection des données de Quire.

Quelles bibliothèques Quire utilise-t-il dans sa pile Dart ?

Quire repose sur une trentaine d’imports de bibliothèques, dont 10 viennent de la communauté, les autres étant publiées par l’équipe Dart. Si vous êtes expert Dart, vous imaginez sans doute y trouver AngularDART et Polymer.dart, mais ils sont tous deux absents.

Nous n’utilisons pas AngularDART, parce que :

  • Nous voulons un contrôle précis du DOM.
  • Nous appliquons des principes d’architecture singuliers pour concevoir la structure du client, et ce paradigme diffère de la logique d’Angular.
  • Lors de notre évaluation d’AngularDART, il générait un important surcoût sur la taille du JavaScript compilé, mais cela s’est beaucoup amélioré depuis.

Nous n’utilisons pas non plus Polymer.dart, parce que :

  • À cause de l’encapsulation et de la redirection des événements, le ShadowDOM ne peut pas coopérer avec un framework orienté sélecteurs, comme Bootstrap.
  • Il est impossible d’injecter du style depuis l’extérieur du ShadowDOM. Si un jeu de composants tiers est fait avec Polymer, il est quasi impossible pour les utilisateurs d’en modifier l’apparence. Mise à jour : depuis décembre 2013, il est possible de modifier le style interne depuis l’extérieur. Voir Shadow DOM 201.

Que sont DQuery et Bootjack ?

Les piliers de notre pile côté client sont DQuery et Bootjack, deux projets open source publiés par l’équipe Rikulo :

  • DQuery est un portage partiel de jQuery vers Dart, centré sur le système de délégation d’événements de jQuery.
  • Bootjack est un portage complet de Bootstrap 3, avec un CSS et des API presque identiques.

Nous avons construit notre pile applicative ainsi pour tirer parti de nos connaissances et compétences du monde JavaScript.

Qu’est-ce que le serveur web Stream ?

Stream est notre serveur web, écrit en Dart pur, avec routage, filtres, MVC côté serveur, etc. Stream fonctionne en douceur avec le modèle de boucle d’événements. Écrire un gestionnaire de requêtes revient simplement à enchaîner une série de routines non bloquantes.

C’est non seulement plus productif, mais aussi plus agréable que le modèle traditionnel de multithreading. Nous assurons aussi la montée en charge de notre service web et gérons le HTTPS avec nginx, qui délègue les requêtes à Stream. Grâce à cette architecture, nous pouvons lancer et arrêter individuellement des machines virtuelles Dart et mettre à jour le serveur sans interrompre l’activité des utilisateurs.

Conclusion

Travailler avec Dart a été une expérience agréable, et nous attendons avec impatience de nouvelles évolutions passionnantes dans la communauté Dart. Enfin, si vous êtes curieux de savoir ce que Dart permet de réaliser, venez essayer notre application, Quire. Elle est gratuite !

En savoir plus sur la façon dont Quire a ensuite été repensé et reconstruit avec Mark II.

Schéma d’architecture de Quire montrant l’implémentation Dart client-serveur

Que retenir de cette réalisation de 2014 en 2026 ?

Le langage Dart et la base de code de Quire ont beaucoup évolué depuis la rédaction de cet article. Dart 2.0 (système de types sound) est arrivé en 2018, Dart 3.0 (null safety, records, patterns) en 2023, et Flutter a bouleversé le paysage des interfaces multiplateformes (l’équipe mobile de Quire l’a d’ailleurs adopté). Mais les choix d’architecture décrits plus haut résistent mieux qu’on pourrait le croire.

Le typage fort sur toute la pile reste rentable. Les erreurs d’exécution qu’un système de types fort détecte à la compilation sont toujours les mêmes. JavaScript s’est rapproché du typage grâce à TypeScript, mais une pile entièrement typée de bout en bout reste rare. Les bugs que Simon citait (d’innombrables petites erreurs) sont toujours ceux qu’une pile non typée livre en production.

Partager les modèles de données entre client et serveur continue de faire gagner du temps. Le problème des modèles dupliqués (l’un en JS, l’autre en Python, qui dérivent en silence) est le même en 2026 qu’en 2014. La solution (un seul langage de bout en bout) aussi. Les équipes TypeScript sur Node construisent des architectures à la Quire pour cette même raison.

La boucle d’événements l’emporte toujours sur le multithreading pour les serveurs web. Node, Deno, Bun et le modèle Stream de Dart s’accordent sur ce point. Le débat est relancé tous les deux ou trois ans et aboutit au même résultat.

Le tree shaking compte davantage, pas moins. En 2014, le compilateur de Dart avec tree shaking était un atout distinctif. En 2026, c’est le minimum attendu de toute chaîne de build ciblant JS. Webpack, Rollup, esbuild et Vite le font tous. La leçon reste valable ; l’outillage a rattrapé son retard.

Les craintes de 2014 sur le ShadowDOM sont en grande partie dissipées. Polymer.dart a été abandonné. Les Web Components ont gagné en maturité. Les raisons données par Simon pour éviter Polymer (injection de styles, coopération avec les frameworks) ont fini par être réglées par la plateforme. Le principe général (éviter les frameworks de pointe pour le cœur d’une application en production) vaut toujours en 2026 pour le framework « à la mode » du moment.

À lire aussi : Dans les coulisses : une Chronologie mobile basée sur Flutter — un regard sur la manière dont l’équipe mobile de Quire a mis Flutter au service d’un affichage en frise chronologique.

Quelles sont les erreurs les plus courantes dans le choix d’un langage pour une grande application web ?

Choisir la pile technique d’une application destinée à durer des années est l’une des rares décisions d’ingénierie coûteuses à inverser. Quatre travers reviennent quand les équipes se trompent.

1. Choisir par défaut le langage à la plus grande communauté. JavaScript a la plus grande communauté, mais « la plus grande » ne veut pas dire « la mieux adaptée à votre problème ». Un langage au typage fort, bien outillé et à la communauté plus modeste peut surpasser un écosystème foisonnant aux garanties faibles. La taille de la communauté compte, mais pas à elle seule.

2. Adopter une pile qui sépare les langages client et serveur. Chaque modèle de données dupliqué est un bug en puissance. Les équipes qui livrent du Ruby côté serveur et du JS côté client paient ce coût indéfiniment. Celles qui partagent un seul langage sur les deux fronts (Dart, TypeScript, Kotlin) évitent toute une catégorie de bugs.

3. Adopter la technologie de pointe avant qu’elle ne se stabilise. En 2014, l’équipe de Quire a évité AngularDART et Polymer.dart parce que tous deux soulevaient des questions d’architecture ouvertes.

AngularDART a opéré un virage radical et Polymer a été abandonné. La règle générale (laisser un framework faire ses preuves en production à grande échelle avant de lui confier le cœur de son application) vaut toujours en 2026 pour le framework « à la mode » du moment.

4. Négliger le système de types pour gagner du temps à court terme. Les langages non typés semblent plus rapides la première semaine. Au sixième mois, le temps gagné est largement perdu en débogage. Les équipes qui ont connu à grande échelle des piles non typées puis typées reviennent presque jamais en arrière de leur plein gré.

Le pari de l’équipe Quire sur Dart en 2014 semble raisonnable avec le recul, non parce que Dart est devenu dominant (ce n’est pas le cas), mais parce que les critères sous-jacents (typage, partage client-serveur, boucle d’événements, tree shaking) sont devenus un consensus de l’industrie au cours de la décennie suivante.

Ce qui a bien vieilli, ce sont les principes d’ingénierie, pas les choix d’outils. Cela vaut en général pour tout choix de langage fait dans l’incertitude : choisissez selon des principes que vous pourrez défendre dans dix ans, pas selon une popularité que vous pouvez mesurer aujourd’hui.

Rejoignez plus de 100 000 équipes qui utilisent le logiciel de gestion de projet Quire — inscription gratuite

Foire aux questions

Avec quel langage Quire est-il développé ?

Dart, côté client et côté serveur. L’application représente environ 54 000 lignes de code Dart, avec une trentaine d’imports de bibliothèques.

Pourquoi Quire a-t-il choisi Dart plutôt que JavaScript ou TypeScript ?

Typage fort, modèle d’héritage par classes et un seul langage pour le client et le serveur. Dart proposait aussi quelques fonctionnalités modernes avant leur prise en charge généralisée dans JavaScript.

Pourquoi Quire n’a-t-il pas utilisé AngularDART ou Polymer.dart ?

L’équipe voulait un contrôle du DOM plus fin que celui permis par la liaison d’AngularDART, et les schémas d’architecture de Quire ne correspondaient pas à la logique d’Angular. Polymer.dart a été écarté parce que le ShadowDOM entrait alors en conflit avec les sélecteurs de type Bootstrap. Polymer a ensuite été abandonné, ce qui a validé ce choix.

Que sont DQuery et Bootjack ?

Des bibliothèques open source de l’équipe Rikulo (l’équipe d’ingénierie de Quire). DQuery est un portage partiel de jQuery vers Dart, centré sur la délégation d’événements. Bootjack est un portage complet de Bootstrap 3, avec un CSS et des API presque identiques.

Qu’est-ce que Stream dans la pile technique de Quire ?

Le serveur web de Quire, écrit en Dart pur, fondé sur le modèle de boucle d’événements. Le routage, les filtres et le MVC côté serveur sont intégrés. Quire exécute Stream derrière nginx, qui gère la montée en charge et le HTTPS.

Simon Pai
Co-Founder at Bookshow