Vue Conf Toronto 2022

Laëtitia Constantin
abbeal’s tech blog
13 min readFeb 14, 2023

Plusieurs centaines de personnes étaient réunies à Toronto les 2 et 3 Novembre 2022 pour la VueConf ! Nous avons eu la chance d’être sur place pour assister aux dizaines de présentations tenues par des experts du monde entier.

Cet article, nous l’écrivons plusieurs mois après l’événement car il nous a fallu un peu de recul pour trouver avec quel angle l’aborder. En effet, cette conférence ne correspondait pas tout à fait à ce à quoi nous nous attendions. Plus précisément, le niveau technique des conférences du premier jour n’était pas aussi élevé que ce que nous l’espérions. La plupart des présentations n’ont pas dépassé le niveau d’information disponible dans les documentations officielles des outils… Mais cela s’explique certainement pour plusieurs raisons que nous allons expliquer à la suite de cet article. Par ailleurs, bien que d’un niveau assez débutant, il n’y avait rien à redire sur la qualité de ces présentations. Et bien entendu, le jour suivant nous avons tout de même eu droit à de nombreuses présentations d’un niveau technique bien plus avancé et donc à la hauteur de nos attentes !

Depuis que le créateur de Vue, Evan You, a annoncé que Vue 2 serait déprécié en fin d’année 2023, la communauté Vue attendait cet événement avec impatience. C’est au travers d’un écran géant qu’Evan You a débuté cette conférence en direct pour nous rappeler les moments clés de l’évolution de Vue. Nous espérions le voir en personne, mais c’est malheureusement à distance qu’il a retracé l’histoire de Vue depuis ses débuts. C’était somme toute une entrée en matière intéressante pour la culture de tout développeur Vue.

Lors de la sortie de Vue 1 en Décembre 2013, Vue n’était qu’une librairie. Autrement dit, de simples appels d’API, sans structure ni compilateur. Avec l’ajout de Vue Router, vue-cli et Vuex, c’est rapidement devenu un framework, appelé Vue 2, sorti en Octobre 2016. Pour la release de Vue 3, en Septembre 2020, le code source a été complètement réécrit, directement en TypeScript. Avec cette nouvelle version est arrivée la composition API, remplaçant l’option API de Vue 2. Ce changement de syntaxe et de structure, visant à améliorer la maintenabilité et la scalabilité, nécessite une réécriture complète des composants Vue 2 pour les passer en Vue 3. Le fait que cette version inclut d’aussi gros changements est probablement un frein à son adoption. En effet, au moment de la conférence seulement 30% des utilisateurs étaient sur Vue 3, et 25% sur Vue 2.7.

C’est à ce moment là que nous avons saisi l’objectif principal de la conférence : convaincre les développeurs d’utiliser Vue 3 et de migrer les applications qui sont encore en Vue 2, plutôt que de nous soumettre de nouvelles pistes de réflexion sur le développement avec Vue, au sens large.

Pour clôturer sa présentation, Evan You a expliqué les objectifs des futures releases de Vue. Aucun changement de syntaxe n’est prévu, mais plutôt une nouvelle stratégie de compilation pour plus de performances, inspirée de SolidJS. Cette stratégie, sans Virtual DOM, est appelée le “vapor mode”.

Suite à cette présentation, des experts se sont succédés pour présenter différents sujets. Voici ce que nous en avons retenu en 2 focus et 10 astuces.

Focus 1 : Arrêter d’écrire vos routes

Voici le premier conseil d’Eduardo San Martin Morote : pourquoi devrions-nous continuer à écrire des routes lorsque nous développons une application avec Vue.js ?

Comme tous les développeurs, notre objectif est souvent d’automatiser au maximum les tâches que nous sommes amenés à répéter régulièrement. Selon Eduardo San Martin Morote, “plus on écrit souvent quelque chose, plus il devrait être facile et rapide à écrire”. Alors, pourquoi devrions-nous continuer à écrire et à déclarer les routes pour chaque projet ? Ne pourrions-nous pas trouver une autre solution ?

Nuxt propose déjà une solution en générant automatiquement les routes en fonction de l’architecture des fichiers. De plus, un des points forts de Vue est que chaque composant est défini dans un seul fichier, avec son template, son script et son style. Pourquoi les routes devraient-elles être écrites ailleurs ?

C’est là qu’intervient unplugin-vue-router, un plugin qui permet de générer les routes de façon typée. Ce projet est encore expérimental, mais vous pouvez le retrouver ici. Compatible avec Vite, Rollup, webpack, Vue CLI et esbuild, il vous suffit d’ajouter une configuration dans votre fichier pour utiliser ce plugin. Il va créer le router sans avoir besoin d’écrire explicitement les routes, et vous avez toujours la possibilité d’étendre la configuration et d’ajouter des routes directement dans vos composants.

On vient le déclarer comme ci-joint dans le fichier de config :

// vite.config.ts
import VueRouter from ‘unplugin-vue-router/auto’

export default defineConfig({
plugins: [
VueRouter(),
// other plugins
]
})

Puis on va créer le router sans explicitement créer les routes.

// router.ts
import { createRouter, createWebHistory } from 'vue-router/auto'

createRouter({
history: createWebHistory(),
// You don't need to pass the routes anymore,
// the plugin writes it for you

// You can extend the routes
extendsRoutes(routes) {
routes.push({
path: '/adding-sth',
component: AddingSomethingPage
})
}
})

Tout l’intérêt vient aussi résider dans la possibilité d’ajouter une route directement, de façon explicite dans un fichier .vue !

<script setup>

definePage({
name: 'my-own-name',
path: '/absolute-with-param',
alias: ['/a/:param'],
meta: {
custom: 'data'
}
})

</script>

Focus 2 : Combiner Cypress et Vitest pour vos tests

Cypress et Vitest sont deux outils complémentaires permettant de faire des tests. Le premier est utilisé pour faire des tests end-to-end, tandis que le second est utilisé pour faire du Component Testing (tests unitaires). Cependant, un même test peut facilement être écrit soit avec Cypress, soit avec Vitest. Par exemple pour tester l’ajout d’un item dans une liste :

// Avec Cypress :
it(`should be possible to add a new item`, () => {
cy.visit('/');
cy.findByLabelText(`Title`).type(`Foo bar`);
cy.findByRole(`button`, { name: `Add item` }).click();
cy.findByText('Foo bar').should('exist');
});

// Avec Vitest :
it(`should be possible to add a new item`, async () => {
let user = userEvent.setup();
render(ShoppingListApp);
user.type(await screen.findByLabelText(`Title`), `Foo bar`);
user.click(await screen.findByRole(`button`, { name: `Add item` }));

expect(screen.queryByText(`Foo bar`)).toBeInTheDocument();
});

Néanmoins, ces deux outils ont chacun leurs avantages et leurs inconvénients. Les tests end-to-end avec Cypress peuvent devenir très lents lorsqu’il y en a beaucoup. En effet, ils s’exécutent dans le navigateur, tandis que les tests Vitest s’exécutent dans un environnement Node.js, ce qui est plus rapide. Lors de la démo présentée par Markus Oberlehner, 1400 tests écrits avec Cypress mettaient environ 40 minutes à s’exécuter, tandis que les mêmes tests écrits avec Vitest mettaient seulement 20 secondes ! En contrepartie, les tests écrits avec Vitest apportent une confiance moins élevée en la stabilité de l’application, car certains bugs ne peuvent pas être détectés lorsque l’on teste en isolation. De plus, ils peuvent parfois remonter des faux négatifs liés à des problèmes qui ne pourraient jamais arriver en testant manuellement, tels que les race conditions (accès concurrents lorsque des actions sont effectuées trop rapidement).

Ainsi, combiner Cypress et Vitest et utiliser l’un ou l’autre à bon escient est le meilleur moyen d’avoir les avantages des deux : un feedback rapide et une confiance élevée en la stabilité de l’application.

Pour faciliter cela, Markus Oberlehner conseille de créer un “type alias” représentant un driver de test générique. Par exemple :

type TestDriver = {
findByLabelText: FindByLabelText,
findByRole: FindByRole,
findByText: FindByText,
goTo: GoTo,
};

Celui-ci est à implémenter à la fois avec Cypress et Vitest. Par exemple :

let cypressDriver: TestDriver = {
findByLabelText: (label) => cy.findByLabelText(label),
findByRole: (role, options) => cy.findByRole(role, options),
findByText: (text) => cy.findByText(text),
goTo: (path) => cy.visit(path),
};

let vitestDriver: TestDriver = {
findByLabelText: (label) => screen.findByLabelText(label),
findByRole: (role, options) => screen.findByRole(role, options),
findByText: (text) => screen.findByText(text),
goTo: (path) => {
router.push(path);
render(App);
},
};

Puis il suffit de l’utiliser dans ses tests en le passant en paramètre, de façon à utiliser facilement l’implémentation voulue :

it(`should be possible to add a new item`, ({ driver }) => [
driver.goTo(`/`),
driver.findByLabelText(`Title`).type(`Foo bar`),
driver.findByRole(`button`, { name: `Add item` }).click(),
driver.findByText(`Foo bar`).shouldBeVisible(),
]);

Un test Cypress peut alors rapidement être changé en test Vitest, et inversement !

Tips 1 : Utiliser vue-query

Lors de sa présentation sur le state management, Nataliia Teplukhina nous a conseillé l’utilisation de vue-query pour la gestion du cache. Cet outil, basé sur react-query, permet de gérer facilement la mise en cache des données serveur côté client lorsqu’on travaille avec une API REST. C’est l’équivalent pour REST d’Apollo, qui lui ne fonctionne qu’avec GraphQL. Avec vue-query, il est très facile de configurer après combien de temps et dans quels cas la donnée doit être rafraîchie. Cet outil permet également de définir facilement la stratégie à utiliser en cas de réponse d’erreur de la part du serveur, afin par exemple de réessayer 3 fois avant de montrer une erreur.

Tips 2 : Utiliser VueUse

Si vous débutez avec Vue 3, VueUse est un outil qui va vous simplifier la vie ! En tout cas, c’est ce qu’assure Jessica Sachs. C’est une collection d’utilitaires de composition Vue qui regroupent de nombreuses fonctions pratiques pour développer des applications. Si vous avez besoin de créer un composant, il se peut que VueUse l’ait déjà fait pour vous. On apprécie particulièrement les fonctions autour des browsers et sensors qui permettent d’accéder facilement à de nombreux éléments du navigateur ou caractéristiques du PC. Jetez un coup d’œil sur la liste des fonctions disponibles sur le site, il y en a plus d’une centaine !

Tips 3 : Utiliser UnJS

Sur les conseils de Daniel Roe, nous vous invitons à aller consulter UnJS, une collection de librairies et outils JavaScript indépendants. Elle contient notamment Nitro, le serveur d’application démarré automatiquement par Nuxt. Parmi les outils qui nous paraissent les plus incontournables de cette collection, nous souhaitons citer :

  • unimport : pour auto-importer les composables là où on en a besoin
  • unplugin : pour écrire des plugins dans le style de Vite et Rollup
  • unenv : pour permettre la portabilité du code vers d’autres runtime que Node.js (Workers, navigateur, etc.) grâce à des presets

Tips 4 : Lire le code source des frameworks et librairies

Il est important de ne pas hésiter à lire le code source des frameworks et des librairies pour s’améliorer en tant que développeur, nous conseille Daniel Kelly. Souvent relu par de nombreuses personnes, ce genre de code est une excellente source d’inspiration et d’apprentissage. N’ayez pas peur de vous y plonger et de vous inspirer des meilleurs ! Cela vous permettra de comprendre comment ces outils fonctionnent et de mieux les utiliser dans vos propres projets.

Par exemple, le code source de Pinia donne de très bons exemples d’utilisation de fonctionnalités avancées de Vue, telles que markRaw et effectScope.

Tips 5 : VueDX

Pour vous aider à améliorer votre workflow et à faciliter le développement des applications Vue 3, il est fortement recommandé d’ajouter l’extension Volar à votre VS Code. Si vous êtes curieux, vous pouvez également télécharger VueDX (Vue Development eXperience) de Rahul Kadyan, qui promet d’offrir également une très bonne intégration avec le framework. Elle propose des fonctionnalités comme la coloration syntaxique, la complétion de code et la navigation de code pour les fichiers Vue.js. Elle permet également de générer automatiquement du code Vue.js à partir de modèles prédéfinis, ce qui peut être très utile pour démarrer rapidement un nouveau projet.

Tips 6 : Migrer de JavaScript vers TypeScript

Si vous êtes un développeur JavaScript, vous avez peut-être entendu parler de TypeScript, un sur-ensemble de JavaScript qui permet une meilleure gestion du type de données. La migration vers TypeScript peut sembler intimidante, mais les avantages en valent la peine.

TypeScript permet de structurer le code de manière plus rigoureuse, ce qui peut réduire les erreurs et faciliter la maintenance. Il aide également à la scalabilité en permettant une meilleure gestion des dépendances et en fournissant une documentation en temps réel. TypeScript permet de “doter de pouvoir” les développeurs en offrant une meilleure gestion des erreurs et une documentation plus claire. Cela peut également encourager les contributions de nouveaux développeurs, car ils auront une meilleure compréhension du code.

Pour commencer, vous pouvez ajouter un fichier tsconfig.json à votre projet en définissant “strict: false”, ce qui désactivera les vérifications de type en un premier temps. Vous pouvez ensuite commencer à convertir vos fichiers .js en .ts. Il est important de définir le langage “ts” dans votre script pour que les fichiers .ts soient correctement interprétés. Enfin, n’oubliez pas de remettre “strict: true” une fois la migration terminée.

En utilisant un outil comme ts-loader avec webpack, vous pouvez facilement compiler vos fichiers TypeScript en JavaScript utilisable dans les navigateurs. Vous pouvez également utiliser // @ts-check pour vérifier seulement certaines parties de votre code et bénéficier ainsi d’une vérification plus rapide.

Tips 7 : Améliorer la vitesse de chargement de vos pages

Le chargement rapide d’une page est crucial pour l’expérience utilisateur. Si la page met du temps à charger, il y a de fortes chances que les utilisateurs abandonnent et cherchent une alternative. Pour améliorer le temps de chargement de votre page, voici 10 astuces que nous a partagé Kara Erickson et Henri Helvetica :

  • Événement LCP (Largest Contentful Paint) : L’événement LCP mesure le temps qu’il faut pour afficher la partie la plus importante de votre page. Il est donc important de s’assurer que cette partie se charge rapidement, idéalement en moins de 2.5s.
  • Balise <img loading=lazy /> : Cette balise indique au navigateur qu’il peut différer le chargement de l’image jusqu’à ce qu’elle soit nécessaire à l’affichage sur l’écran. Cela peut considérablement accélérer le temps de chargement initial de la page. Il faut l’utiliser sur toutes les images excepté le LCP.
  • Balise fetchpriority=high : Cette balise indique au navigateur que vous souhaitez que l’image soit téléchargée aussi rapidement que possible.
  • Éviter les images lourdes : Il est important de ne pas télécharger des images trop lourdes surtout si elles ne sont destinées qu’à être affichées petites. Idéalement, la taille des images ne doit jamais dépasser 144 Ko.
  • srcset/sizes : La balise srcset/sizes vous permet de spécifier différentes tailles d’images pour différentes tailles d’écran. Par exemple, <img sizes=”sm:100vw md:100vw lg:1200vw”/>.
  • Choisir une police légère : Il est important de bien charger la police dès le début et de choisir une police légère pour ne pas ralentir le temps de chargement. Vous pouvez utiliser @nuxtjs/google-fonts pour charger des polices Google rapidement.
  • Utiliser des SVGs pour les icônes : Les SVGs sont plus légers que les autres formats d’images et sont donc plus rapides à charger.
  • Charger le style en premier : Il est important d’installer le style dès le début pour éviter d’avoir à le charger plus tard, ce qui peut ralentir le temps de chargement. Écrivez le de manière explicite pour ne pas avoir à le chercher après le début du chargement.
  • Utiliser le format WebP pour les images plus larges telles que les photos. C’est un format particulièrement léger, conçu pour le Web.
  • Préférer le mot-clé defer à async pour le chargement des scripts.

Et n’oubliez pas que l’on ne peut pas améliorer ce qu’on ne mesure pas ! Le LCP, déjà cité plus haut, est l’une des métriques les plus importantes à mesurer. Elle fait partie des Core Web Vitals, avec le FID (First Input Delay) et le CLS (Cumulative Layout Shift). Mais il faut également prêter attention au TTFB (Time To First Byte) et au SI (Speed Index). Le TTFB correspond au temps entre le moment où le navigateur envoie la requête et le moment où il reçoit le premier octet de la réponse. Le SI correspond au temps au bout duquel les parties visibles de la page sont affichées. Pour mesurer tout cela, différents outils existent tels que Google Lighthouse et WebPageTest.

Tips 8 : Créer vos propres modules Nuxt avec Nuxt Kit

Développer un module Nuxt peut vous aider à mieux comprendre le fonctionnement de Nuxt, et est un bon moyen de contribuer à l’open-source. Lucie Haberer nous a parlé de Nuxt Kit qui est un utilitaire permettant de développer ses propres modules Nuxt très facilement grâce à defineNuxtModule. Il vient avec un bundler et des options de configuration par défaut.
Mais attention à ne pas réinventer la roue ! La liste des modules Nuxt existants est disponible ici : https://nuxt.com/modules

Tips 9 : Construire un design system cohérent et consistant

Un design system est un ensemble de standards pour des composants réutilisables. Les conseils de Shivam Mishra pour construire un design system cohérent et consistant sont les suivants :

  • Utiliser le Base Variant Pattern : créer un composant de base qui ne sera jamais directement affiché (par exemple un bouton avec seulement les fonctionnalités de base), puis créer toutes les variantes requises (un bouton warning, un bouton disabled, etc.)
  • Utiliser la syntaxe de nommage suivante pour les design tokens :
–{élément}-{intention}-{propriété}-{interaction}

Par exemple :
–button-danger-background-default
  • Ne pas négliger l’importance de la culture pour l’adoption du design system : plus d’utilisateurs signifie plus de contributeurs, donc plus d’évangélistes et donc plus d’utilisateurs… C’est un cercle vertueux.

Tips 10 : Migrer de Vue 2 à Vue 3

Puisque tout l’objectif de cette conférence semblait de nous convaincre de migrer vers Vue 3, nous vous suggérons d’utiliser vue-codemod pour le faire en toute sérénité.

Le support pour Vue 2 s’arrêtera le 31 décembre 2023. Si cela ne suffit pas à vous convaincre de sauter le pas, nous vous rappelons ces quelques fonctionnalités de Vue 3 qui pourraient vous donner envie de le faire :

  • Teleport, qui permet de téléporter du HTML à un autre endroit du DOM
  • Fragment, qui permet de faire composants avec plusieurs noeuds racine
  • Suspense, encore expérimental, qui permet de faire du lazy loading des composants pour afficher un fallback le temps qu’ils soient chargés
  • Script setup, qui permet de déclarer les composants d’une façon un peu moins verbeuse (également disponible avec Vue 2.7)

De plus, pour une meilleure expérience avec Vue 3, nous vous encourageons également à migrer de Webpack à Vite et de Jest à Vitest !

Conclusion

Pour terminer cet article, voici les prochains évènements :

  • VueJS Live (En ligne + Londres) du 12 au 15 Mai
  • VueConf US (New Orleans), du 24 au 26 Mai

On vous recommande également de souscrire gratuitement à la newsletter de Michael Thiessen qui propose des contenus intéressants sur Vue et Nuxt.

Merci de nous avoir lu ! Article co-écrit avec Justine Ventalon

--

--

abbeal’s tech blog
abbeal’s tech blog

Published in abbeal’s tech blog

abbeal, c’est une société de conseil à taille humaine animée par la veille, le partage et l’expertise technique.

Laëtitia Constantin
Laëtitia Constantin