Skip to main content

Révolutionner le développement de notre micro pipeline frontend

septembre

15, 2020

by jynj2912


Technologie

L’application Web Roblox a été construite comme un monolithe. Comme dans le schéma ci-dessous, elle nécessite que tous les ingénieurs développant sur un même projet procèdent ensemble. Le projet est construit en utilisant un cadre .Net MVC, y compris Web Asp .Net Form, de sorte que l’application de tout changement nécessite MSBuild – même pour les changements JS/CSS/Image.

Développement et déploiement

Du côté des utilisateurs, le chargement des ressources Web se fait selon deux scénarios : le navigateur demande la ressource pour la première fois, et il la retire du CDN après la première demande. Notre organigramme ci-dessous montre comment le téléchargement des actifs vers le CDN est inclus dans l’effort du premier chargement.

Ensuite, après le premier scénario de chargement, le navigateur commencera à extraire une ressource du CDN en tant que telle :

Avec plus de 10 ans de développement continu et une base de code vieillissante, nos pipelines de développement et de sortie n’ont pas l’efficacité que nous attendons du CDN. C’est arrivé pour plusieurs raisons :

  • Même s’il n’y a que des changements de ressources web (tels que Javascript, CSS, HTML, images, etc.), le site web entier doit être construit et déployé.
  • Si des problèmes surviennent à la suite de changements, tous les changements engagés par les différentes équipes doivent attendre que le problème soit résolu avant de pouvoir être publiés.

En outre, les ressources Web sont regroupées et téléchargées vers le CDN par une méthode de classement, ce qui rend les technologies frontend modernes – telles que ES6+ (ECMAScript 6+) ou Typescript – difficiles à adapter pour un développement à long terme. Ainsi, le pipeline actuel de développement et de déploiement crée des obstacles pour tout le monde.

Depuis 2017, Roblox a testé diverses approches pour isoler les processus de développement et de déploiement des ressources web.

  1. La première approche réussie a été de tirer les enseignements de la création de petits sites API et de les appliquer à la création de sites d’applications. Les sites d’application contiennent des ressources Web par composant et se déploient comme leur propre projet. Un site d’application n’est pas un site Web individuel : il fournit plutôt des points terminaux pour regrouper des actifs et renvoie l’URL CDN redirigée.
  2. La deuxième phase consiste à introduire un système de bundle Webpack en remplacement de notre méthode de classement d’assemblages, en conjonction avec un nouveau service de contenu statique. Cela nous permet de télécharger des bundles dans le CDN, ce qui supprime le déploiement du serveur web et ne met à jour que l’URL du CDN pour chaque composant.

Phase I – Application Web (Site)

Comme nous avons déjà développé un cadre JS moderne pour certains des composants de la fonctionnalité, il est naturel de commencer par isoler le projet de restitution côté client du projet principal du site web Roblox. Nous traitons le projet principal comme un squelette, de manière à ce que le projet principal ait seulement besoin de savoir quel site d’application web demander. Ensuite, chaque projet accueille un groupe de composantes de caractéristiques similaires et leurs propres ressources.

Chaque composant du projet aura son propre contrôleur pour fournir un point final permettant de regrouper Javascript, CSS, HTML, et la réponse du point final sera redirigée vers l’URL du CDN. Par exemple, https://chatsite.roblox.com/chat/{version}/get-javascript-bundle comme point final qui retourne https://js.rbxcdn.com/{hashNumber}.js. La réponse de redirection sera le statut 301 Http, et la réponse sera mise en cache dans le navigateur après la première demande.

Afin de notifier le navigateur d’un changement, nous ajoutons un numéro de version dans l’URL du site de l’application à des fins d’extraction du cache. Le numéro de version est un GUID et est ajouté/mis à jour depuis le site d’administration. Pour chaque changement effectué à partir du site de l’application, les développeurs doivent déployer le site de l’application, puis se rendre sur le site de l’administrateur pour mettre à jour le GUID afin de vider le cache.

Nous héritons donc du même système MSBuild pour le groupage, mais chaque projet fera son propre MSBuild, de sorte que le propriétaire de chaque projet a la possibilité de publier ses modifications (comme ci-dessous).

Développement et déploiement

L’avantage de cette approche est que lorsque les ingénieurs déploient un nouveau code, ils n’ont besoin de faire que deux étapes. Tout d’abord, ils publient un site d’application qui comporte les modifications nécessaires. Ensuite, ils mettent à jour la valeur de hachage pour chaque URL de site d’application afin d’avertir les navigateurs qu’il y a des mises à jour et aussi extraire les ressources mises à jour. Pour la première fois, comme ci-dessous, le navigateur demandera la ressource par l’URL mise à jour et téléchargera la ressource à partir de l’URL relative avant que l’URL du CDN ne soit prête.

Après le premier chargement, une fois que l’URL du CDN est prête, le navigateur commence à extraire les ressources du CDN directement. Comme ci-dessous :

Grâce à cette approche, nous sommes désormais en mesure de fournir une ressource de conversion pour chaque composant sans avoir à réaliser une version du site web. La ressource de conversion n’a pas besoin d’être regroupée, et elle a son propre point final pour obtenir la ressource de conversion de LocaleResourceFactory dans le cadre du fichier JS.

Le projet hérite de la même méthode de classification pour regrouper les actifs et les télécharger vers le CDN. Ce mécanisme exige que les chargements d’images à partir de la norme CSS restent sur un chemin prévu. Comme le bundle CSS reste une ferme statique, l’image reste physiquement dans le même serveur. Ainsi, pour la phase I, les images continuent à être téléchargées à partir du site web principal comme auparavant.

Avantages :

  • Les développeurs sont capables de développer et de publier leurs propres ressources Web pour tout changement de FE, comme Javascript, HTML ou CSS.
  • Les développeurs peuvent mettre à jour la chaîne de conversion en ne publiant que le site de l’application grand public au lieu d’une version Web.
  • Comme effet secondaire, seule la page de rendu côté client peut être déployée à partir du pipeline de développement du site de l’application, ce qui encourage les équipes à aller plus vite sur le remaniement du rendu côté client.

Inconvénients :

  • En raison de la réutilisation de l’ancien système, il n’est toujours pas possible de développer et de déployer facilement des images et des JS modernes à partir du site de l’application.
  • Comme les bundles sont générés lorsque le navigateur envoie une requête au site de l’application, il est possible que si la nouvelle URL CDN n’est pas générée avec succès ou est en état de panne, alors le navigateur pourrait être mis en cache avant la prochaine mise à jour.

Phase II – Application Web (dossier)

Après la phase I, une question évidente s’est posée : Pourquoi devons-nous encore rediriger l’URL du CDN à partir du site de l’application ? Pourquoi ne pouvons-nous pas intégrer l’URL du CDN dans le code principal du site web ?

Nous commençons donc la phase II en essayant d’introduire un service de contenu statique pour télécharger des ressources Web vers S3 pendant la période de construction, puis nous renvoyons l’URL CDN dans DB tout en héritant de la structure des composants de la phase I (et en gardant le site web Roblox comme squelette). Chaque ensemble de ressources sera ensuite mis en correspondance avec un nom de chaîne Enum de composant statique. The component name will be embedded into the website skeleton page.

Le site web demandera le service de contenu statique pour le dernier contenu activé par nom de composant et récupérera une URL CDN que le CDN tirera de S3 s’il ne l’a pas mis en cache. Ensuite, avec cet avantage de service de contenu statique, nous finissons de regrouper les actifs pendant le temps de construction. L’URL du CDN est alors prête avant que nous activions la nouvelle version et la validation. Comme nous avons intégré l’URL CDN directement dans le projet de site web Roblox, il n’est pas nécessaire de déployer le serveur Web pour accéder à un site d’application supplémentaire afin d’obtenir l’URL CDN. Cela évite aux développeurs de devoir déployer un serveur Web.

Lorsque les ingénieurs déploient des changements pour la première fois, une seule étape est nécessaire pour mettre à jour l’URL CDN de chaque bundle de composants statiques depuis le site d’administration. L’URL sera directement extraite du CDN puisqu’elle n’est pas encore mise en cache.

Après la première fois, l’URL du CDN sera disponible lorsque les navigateurs feront une demande auprès du service de contenu statique.

La deuxième partie de la phase II consiste à remplacer le système actuel de regroupement par un outil Webpack. Le Webpack a été utilisé pour appliquer un compilateur SCSS, fusionner/modifier des actifs, télécharger des images, compiler l’ES6, la carte des sources, etc. Cet outil webpack découple le projet Web frontend de MSBuild, de sorte que chaque application web est un dossier pour maintenir la ressource. Et grâce au chargeur d’URL, nous pouvons charger une image dans le CDN et intégrer l’URL du CDN dans le fichier du bundle CSS. Comme vous pouvez le voir ci-dessous, le téléchargement de fichiers et la génération d’URL CDN ont lieu pendant la durée de développement du projet. L’URL CDN a été intégrée au site web de Roblox, de sorte que nous n’avons pas besoin d’un déploiement MS pour publier de nouvelles URL CDN.

L’actuel pipeline de développement et de déploiement de WebApp fonctionne donc comme suit :

Avantages :

  • Les développeurs n’ont pas besoin de déployer un serveur Web pour publier une modification. Il leur suffit de se rendre sur le site d’administration et de mettre à jour la dernière URL du CDN avec le nom du composant concerné. C’est une grande amélioration pour notre pipeline de sortie.
  • Les images sont téléchargées et déployées avec chaque composante et servies depuis le CDN.
  • L’introduction de l’outil Webpack met à niveau l’ensemble de l’environnement de développement frontend, libérant les ingénieurs pour qu’ils puissent passer à ES6+, Typescript, etc.

Contre :

  • En contrepartie, nous avons perdu le soutien des ressources de conversion à partir de cette phase, de sorte que toute nouvelle ressource que nous introduisons doit passer par une diffusion sur le web.
  • Comme pour la phase I, toute duplication de code ou dépendance entre les bundles est difficile à identifier.

Et maintenant ?

Bien que nous ayons fait de grands progrès, nous aimerions continuer à étudier le Webpack et d’autres outils possibles pour traiter la question des dépendances entre les bundles. De plus, notre service de recherche de ressources de conversion doit être capable d’effectuer une recherche dynamique afin de permettre un déploiement isolé pour l’introduction de tout nouvel espace de noms de ressources. Nous avons parcouru un long chemin, mais nous sommes toujours à la recherche de nouvelles opportunités pour rendre notre pipeline de développement plus rapide et plus facile à développer.


Ni Roblox Corporation ni ce blog ne cautionnent ni ne soutiennent aucune entreprise ou service. En outre, aucune garantie ou promesse n’est faite quant à l’exactitude, la fiabilité ou l’exhaustivité des informations contenues dans ce blog.

Cet article de blog a été publié à l’origine sur Roblox Tech Blog.