Niveau Niveau confirmé

Apprendre à développer en équipe

Articledéveloppement

Cet article est issu de mon retour d'expérience sur ces 3 dernières années. Années pendant lesquelles j'ai réfléchi à améliorer le cadre de travail côté front de l'équipe d'une quinzaine de développeurs chez Logic-Immo. Il a pour but de donner des pistes aux équipes de moyenne ou grosse envergure qui souhaitent garder un cadre de travail agréable et performant.

Le travail en équipe est souvent douloureux. Qui n’a jamais fait l’expérience d’arriver dans une boîte et d’y voir une dette technique importante ? Parfois même, il n’y a aucune nomenclature commune, tout et son contraire se côtoient. Bootstrap sur quelques blocs, du css vanilla sur d’autres, certains développeurs/euses codent sur une seule ligne, d’autres écrivent avec des point-virgules, certains non, etc.

En mettant en place des règles pour favoriser un code propre et lisible, donc maintenable, il est bien plus plaisant de travailler sur vos projets au boulot. Comme chaque développeur/euse a sa manière de travailler, il convient de trouver une façon accessible au plus novice (il est fort probable que le directeur technique fasse appel à des contrats pros, stagiaires ou débutants pour dégager du budget pour une ressource plus sénior). Ainsi si la lecture du code est adaptée pour les débutants, elle est accessible pour tout le monde.

Le côté optimisation reste indispensable pour les navigateurs, mais nous verrons en fin qu’avec un certain nombre de tâches automatisées, c’est quelque chose qui se fait implicitement. Pour chaque point, je vais vous parler de l’idée générale, avec parfois plusieurs pistes. À vous de l’adapter à vos projets et de choisir les solutions les plus adéquates, en fonction du niveau de vos développeurs/euses ou des technologies utilisées.

Architecture des fichiers

La manière d'organiser vos fichiers, dans l'arborescence et dans la façon de les inclure est une base saine pour démarrer un projet bien ficelé.

Rangement logique des fichiers

Il suffit d’ouvrir certains projets pour se rendre compte qu’il y a un nombre conséquent de dossiers comprenant les mêmes types de ressources.

Ces ressources sont parfois :

  • placées à des endroits peu logique => Il est difficile de retrouver exactement où faire sa modification ;
  • dupliquées et donc redondantes => risque d’avoir du code inutilisé qui alourdit le site.

Pour pallier cela il faut avoir une arborescence de fichiers logique. Mettez vos fichiers front dans un dossier public/ ou asset/ puis organisez-les avec un découpage cohérent : css/ fonts/ img/ js/ less/ (ou sass/) etc.

Ne multipliez pas les endroits contenant un même type de ressources. Par contre au sein d’un même dossier d’un type de ressources, vous pouvez créer des sous-dossiers pour créer une arborescence logique.

Il n’y a pas forcément d’arborescence type, mais voici un exemple avec un site de petites annonces (semblable donc à une majorité des sites e-commerce).

exemple d'arborescence pour les fichiers SCSS d'un site de petites annonces

Exemple d'arborescence pour les fichiers SCSS d'un site de petites annonces

Inclusions des fichiers (phtml/less/etc)

L’inclusion de fichiers les uns dans les autres est un grand classique des risques d’erreurs. Il permet d’éviter d’avoir un fichier comprenant des centaines voir milliers de lignes de codes. Mais mal utilisé, il devient contre-productif.

Imaginez un exemple concret : si le fichier PHP principal d’une page contient l’appel à un fichier PHP pour le header qui comprend lui-même l’appel à un fichier PHP pour la navigation. Si ce dernier contient un appel à un fichier PHP d’un élément du menu et ainsi de suite. Lorsque vous avez une modification à faire sur la barre de navigation, vous ne savez pas du premier coup d’oeil si vous devez modifier du code dans le fichier de l’élément du menu ou celui de la navigation, voire celui du header.

Pour éviter ce genre de désagrément, ma recommandation est de n’avoir qu’un niveau d’inclusion. C’est exactement ce que l’on a fait plus haut dans l’arborescence de fichiers où seuls les quatre fichiers de bases de pages (detail, home, list, seo) importent d’autres fichiers. Je recommande aussi de mettre en LESS ou Sass les imports dans l’ordre d’apparition des éléments dans la page, rien que pour la lisibilité.

@import "compass/css3",
        "compass/reset",
        "../../../vendor/fontawesome/scss/font-awesome",
        "../../common/fonts/_font-custom",
        "../../common/_color",
        "../../common/_buttons",
        "../../common/_fonts",
        "../../common/_reset",
        "common/_structure",
        "../common/_criteo",
        "../common/_ads-interstitiel.scss",
        "../common/_banner-apps",
        "../common/_header",
        "../common/_navigation",
        "../common/_modal",
        "../common/_volumetry",
        "home/_header",
        "home/_search-engine",
        "home/_friendly-links",
        "home/_ads-sticky";

Découper en modules

Une façon de s'y retrouver plus facilement est de découper votre code en modules et de les rendre indépendants les uns par rapport aux autres. Pour ce qui est des styles par exemple, je vous conseillerais d'utiliser un préprocesseur CSS comme vu au dessus. Cela vous permet de créer un fichier de style pour chacun des blocs de votre page.

Cette façon de faire permet de savoir où faire des modifications rien qu'en visualisant la page HTML.

Nomenclature

Maintenant que nos fichiers sont bien placés et appelés, il nous faut une convention de nommage de ceux-ci et du code.

Nommage des fichiers et variables

Il n’y a rien de plus irritant que d’avoir au sein d'un même projet des fichiers nommés de façon diamétralement opposée et d’avoir des noms de variables aussi bien en majuscule qu’en CamelCase. D’autant plus que certaines notations ont des significations particulières comme les majuscules qui correspondent souvent à des variables globales.

Il n’y a pas de règles précises, l’idée étant vraiment d’avoir une nomenclature suivie par les membres de l’équipe. De notre côté, nous avons opté pour que les fichiers soient nommés nom-du-fichier.(js/scss/css/less/html/etc), donc tout en minuscule avec des tirets séparant les mots, tandis que les variables soient nommées en lowerCamelCase, c’est à dire avec une majuscule séparant les mots suivant du premier.

noms de fichiers noms de variables
search-engine.less searchEngine
home.js blockHomePage
sticky-footer.js stickyFooter
index.html app

L’utilisation des classes et IDs

Sujet parfois épineux. Chez nous, nous avons fait le choix de bannir les ID des styles. Ainsi il n’y a aucun risque d’écraser le style d’un collègue et de créer un effet de bord. Les IDs restent toutefois autorisés pour le JS ou la QA (Quality Assurance).

Il en va de même pour !important qui est uniquement toléré lorsque l’on doit surcharger un plugin JS qui ajoute des styles inline ou avec ID. Mais dans les faits, il n’est quasi jamais utilisé.

Bien évidemment, on ne met pas de styles dans les balises, pour la lisibilité et parce que leur priorité est plus élevée que les ID. De la même manière, il est dangereux de cibler directement une balise. Il vaut mieux cibler uniquement des classes car vous pourriez décider à tout moment de remplacer votre balise ul par une balise ol par exemple. Si vous aviez mis le style sur la classe, alors vous n'avez aucun risque.

Pour rappel, voici une petite astuce pour connaitre la priorité des sélecteurs et qui nous a pousser à adopter la règle d'autoriser uniquement les classes, pseudo-classes et pseudo-éléments (https://www.w3.org/TR/selectors-3/#specificity) :

Pour connaître le sélecteur qui est appliqué entre ces 4 suivants :

#footer ul li a {}
footer.linksSeo ul li a {}
#footer .linksSeo a {}
footer#footer ul a {}

il suffit de compter les occurrences de chaque type de sélecteurs et les ranger dans un tableau comme ceci :

!important Styles dans la balise IDs Classes / Attributs / :pseudo-classes Balises :pseudo-éléments
0 0 1 0 3 0
0 0 0 1 4 0
0 0 1 1 1 0
0 0 1 0 3 0

Puis de comparer les valeurs obtenues. La plus élevée est 1110 donc le sélection #footer .linksSeo a est prioritaire sur les autres. C’est aussi simple que cela. À égalité, c’est leur placement dans la feuille de style qui les départages, les plus bas écrasant toujours ceux du dessus. Ainsi en n’utilisant que des classes, on peut facilement surcharger un style sans se demander si notre sélecteur doit comporter un ID ou un !important. Voici un lien pour tester la priorité des sélecteurs pour les flemmards (caractéristique propre aux bons développeurs/euses ;-)) : https://specificity.keegan.st/

Ordre des propriétés/valeurs

Dans un soucis de rapidité de lecture, nous avons décidé d’ordonner les couples de propriétés/valeur de styles.

Ce qui demande un petit peu de gymnastique au début devient très vite un réflexe dont vous aurez du mal à vous passer.

L’idée est que lorsqu’une propriété, par exemple le background, est toujours positionnée plus bas que la propriété width, alors il est plus facile de la repérer rapidement. Voici un exemple que nous utilisons où nous avons regroupé les propriétés par logique. Il en existe d'autres comme le rangement par ordre alphabétique.

.selector {
   display
   position
   top
   right
   bottom
   left
   z-index
   overflow
   clear
   width
   height
   line-height
   padding
   margin
   font-family
   font-size
   font-weight
   font-style
   text-decoration
   text-align
   justify-align
   align-content
   color
   background
   border
   text-shadow
   ...
   :hover
   :focus
   ...
   ::afer
   ::before 
}

Disposition des sélecteurs communs

Cela peut paraître bête, mais lorsque vous avez plusieurs sélecteurs auxquels vous attribuez des propriétés/valeurs, écrivez les les uns en-dessous des autres pour gagner en lisibilité.

/* peu conseillé par illisible selon le nombre de sélecteurs */
.firstSelector, .secondSelector, .thirdSelector {
   margin: 20px;
}

/* conseillé car plus lisible */
.firstSelector,
.secondSelector,
.thirdSelector {
    margin: 20px;
}

Trouver le bon cadre

La question du choix de la technologie à utiliser se pose à chaque début de projet. L'un des sujets qui revient encore aujourd'hui est l'utilisation de JQuery. Est-ce bien nécessaire ? L'important est de privilégier des techniques ou technologies qui donnent un cadre, sans forcément passer par un framework.

Lorsque l’on bosse à plusieurs, il vaut mieux prendre une techno maîtrisée par l’ensemble de l’équipe qui est amenée à bosser sur le projet. Il peut être parfois intéressant de pousser une techno qui a le vent en poupe, notamment pour attirer de nouveaux développeurs/euses. Mais chaque technologie a sa période de gloire. De plus, elle n’est pas forcément maîtrisée par tous les futurs candidats prêts à rejoindre le projet. Là je vous conseillerais au maximum de rester framework agnostic. Faire le maximum de vanilla permet d’alléger le projet mais également de garder un code compris par tous, malgré que cela puisse augmenter les temps de développement car il y a plus à faire. Bien évidemment, cela n'empêche pas (et il est même conseillé) de mettre des règles et une architecture basée sur des controllers, dispatchers, components pour gagner en lisibilité.

Enfin définissez des conventions de codage. Afin d'avoir des règles pour le point virgule à la fin des lignes, un nombre d'espaces qui définissent une tabulation, etc.

Bienveillance

Le cadre de travail est tout aussi important. Avec du respect et de la bienveillance, vos collègues et vous serez plus à même de donner le meilleur de vous-même

Être responsable

La première attitude à adopter dans une équipe est d'être responsable. Quand un/e développeur/euse coince sur un sujet, technique ou autre, il vaut mieux en faire part rapidement à l'équipe. Chose évidente lorsque l'on travail en agile où les daily sont des moments privilégiés pour alerter ses camarades.

L'idée est de ne jamais se retrouver au pied du mur à la fin d'un projet. Si chacun prend le temps d'aider les autres, le niveau global s'améliore et personne ne reste coincé et donc non productif. N'hésitez pas à demander à votre manager ou directeur technique un temps de votre charge de travail dédié à l'entraide, la veille technique et les réunions improvisées. Cela évite d'avoir des retards dus aux imprévus et de générer du stress inutilement.

La notion clé du travail en équipe est donc la transparence vis-à-vis de l'équipe.

L’importance de la recette technique

Il est capital de faire valider son code par ses collègues. De une parce que ceux-ci peuvent vous aider à vous évitez de faire passer une coquille. Qui n’a jamais laissé par mégarde un console.log dans son code ? Mais aussi parce qu’ils peuvent vous aider à vous améliorer sur une partie du code où ils auraient fait autrement.

Les pull request doivent être bienveillantes. Il n’y a aucune raison d’être agressif et encore moins de se sentir dévalorisé lors de retours. Il y en a constamment, même pour les meilleurs, car il n’y a pas qu’une manière de coder et certains algo demandent parfois à être débattus. Les pull request peuvent contenir :

  • des améliorations à effectuer (avec explications précises) ;
  • des questions sur la compréhension d'un bout de code ;
  • des encouragements ou félicitations lorsque quelque chose d'intelligent a été fait.

exemples de messages de pull request

Exemples de messages de pull request

Chez nous, une pull request doit être validée par au moins deux développeurs/euses pour que le code puissent continuer son parcours par la QA, recette client puis finir en production.

Une responsabilité partagée

Travailler en équipe demande de se pousser vers le haut. C’est le niveau global de l’équipe qui permet d’avoir un code propre et performant.

L’avantage de la recette technique est que tout le monde est garant du code qui passe en production. Si une coquille ou un bug y arrive c’est que vous n’avez pas bien vérifié le code d’un de vos collègues. Vous êtes donc autant responsable que lui. Il faut donc penser au niveau de l'équipe et non de façon individuelle.

Le versioning

À une époque, il fallait faire attention aux fichiers que vous modifiez pour ne pas écraser le travail de vos collègues. En général, chacun modifiait une page différente pour éviter de se marcher sur les pieds. Mais depuis un bout de temps il existe des solutions pour éviter cela. La gestion de versions permet non seulement de modifier le même fichier sans risque d’effet de bord mais également de garder des sauvegardes de votre code à un instant donné. Ainsi nul besoin de laisser du code commenté pour plus tard. On pourra le récupérer ultérieurement dans l’historique de nos modifications si besoin.

Il existe des systèmes de gestion de versions centralisée comme SVN et décentralisée comme GIT. De nos jours GIT est la solution la plus utilisée donc je vous la conseille pour être à l’aise lors de vos premiers pas dans une nouvelle équipe.

Google Trends GIT/SVN

Partages de connaissances

Dès la conception d'une fonctionnalité ou d'un bloc, vos meilleurs amis sont la feuille et le crayon. Il est toujours plus facile de prendre la bonne direction si on la visualise en amont. Je préconise donc de faire le maximum de schémas et de prendre des notes. Toutes ces informations sont un support pour expliquer à vos collègues votre démarche, un concept ou une problématique à résoudre avec eux. N'oubliez pas qu'une documentation est indispensable pour les nouveaux arrivants ou vous y retrouver quand vous reviendrez sur le projet quelques mois plus tard.

Dans le même état d'esprit, instaurez des Tech Lunch. Le concept est de faire des présentations sur des points techniques aux autres membres de votre équipe. Ils permettent de vous améliorer en faisant des recherches plus pointues sur les sujets qui vous plaisent mais ils permettent surtout d'améliorer le niveau de vos collègues, qui produiront un meilleur code. Nous les faisons à raison d'une fois par mois entre midi et deux.

Automatisation des tâches

Finalement tout ça nous permet d'être plus efficace et de nous relire plus facilement. Mais prendre ces libertés ne permet pas de rendre votre code le plus performant possible. Automatisez au maximum certaines tâches car moins les process sont complexes et moins il y a de risques d'erreurs

Minification

La minification du code est sûrement la plus évidente, elle permet de gagner pas mal d'octets pour gagner en performance sur le site en production. Pour ceci et pour toutes les tâches de cette section, il est intéressant d'utiliser un gestionnaire de tâche. Même chose que pour les technologies JS, il s'agit de voir en fonction des compétences de chacun lequel vous souhaitez utiliser. Si Grunt est ancien, il existe Gulp ou webpack de plus récents, mais vous pouvez choisir d'autres gestionnaires également.

Cette tâche automatisée est très importante puisqu'elle vous permet d'écrire votre code de la façon la plus lisible possible. Vous pouvez privilégier toutes les écritures lisibles même si elles sont plus longues puisque cette tâche optimisera en partie votre code.

Concaténation

La concaténation est le fait de mettre le code de vos fichiers les uns à la suite des autres dans un seul et même fichier. Généralement on regroupe les fichiers JavaScript entre eux et ceux de styles entre eux. L'idée est de n'avoir qu'une seule requête HTTP à faire plutôt qu'une pour chaque fichier.

Autres

exemple de l'intérêt de la compression d'une image

La compression des images est un point clé puisqu'il s'agit très souvent des ressources les plus lourdes. Il est possible de mettre en place des tâches ou de passer par un compresseur d'images en ligne. TinyPNG par exemple : TinyPNG

Conclusion

Vous avez maintenant de nombreuses pistes pour améliorer votre façon de travailler en équipe. Certains éléments de nommage ou façon de faire peuvent être débattus et adaptés à votre équipe, en tenant compte des compétences de vos collègues. Mais gardez en tête que le temps de les mettre en place est un investissement à moyen et long terme. Plus qu'un gain de temps évident par la suite pour développer les futures évolutions, c'est aussi la motivation de l'équipe qui s'en trouvera améliorée.

Commentaires

Très bon article ! J'ai cependant quelques remarques/suggestions d'amélioration ????

Concernant l'organisation des fichiers, je ne prétendrait pas qu'il s'agit d'une vérité pour tout type de projet mais on a tendance à conseiller de plus en plus une organisation par bloc fonctionnel plutôt que par type de fichier. Tout simplement pour éviter de devoir ouvrir 4 répertoires pour modifier les fichiers d'un même élément d'une page. C'est particulièrement utile dans des projets basés sur les web components.

Et pour compléter ton propos très pertinent sur les bonnes pratiques Sass/Less, j'aurais simplement fait mention de l'utilisation d'un linter pour permettre de s'assurer du respect des règles décidées dans l'équipe, et également l'association avec un pre-commit hook afin que personne ne puisse commit de code en désaccord avec les règles de l'équipe. Ça fait gagner du temps à tout le monde, et les pull requests seront d'autant plus simples à valider !

Les 4 ? à la fin de ma première phrase étaient censés être un smiley :), je préfère préciser pour que ça ne déforme pas mon propos !

@BisonFoutu : Effectivement ! Remarque pertinente. Il est possible également de regrouper l'ensemble des fichiers d'une feature. Personnellement ça dépend des technos JS utilisés. Sur du ReactJS par exemple c'est ce qu'on fera. Par contre avec du JS vanilla, je préfère avoir les ressources séparées par type. Parce que je retrouve facilement mes mixins et fichiers communs qui peuvent être liés à ma feature. Mais là c'est un choix à prendre entre les membres de l'équipe.

Un linter permet d'être plus rigide. Après j'ai plus tendance à penser que les retours de la Pull Request peut permettre aux développeurs d'enregistrer plus facilement leurs erreurs ou coquilles. Du coup j'aurai tendance à ne pas surcharger le nombre de restrictions d'un linter. Mais ça peut être une bonne idée :)

Bon article avec des exemples concrets pour une fois car généralement avec ce genre d'article on en ressort moins informés qu'avant de l'avoir lu.

J'ai trouvé le passage sur jQuery totalement gratuit par contre car basé uniquement sur une opinion. Donc pas très intéressant sur ce point là.

@Depassage : Merci pour tes retours.

Pour Jquery, je ne suis pas contre et je l'utilise de temps à autre. Mais son gros problème pour moi est qu'il est utilisé à outrance par des développeurs qui du coup ne comprennent pas toujours le javascript (forcément vu que JQuery est assez magique, on ne pourrait que l'utiliser). JQuery est aussi lourd à charger, plus lent a exécuter, etc. Mais j'avoue que sans plus de précision, ça pouvait donner une impression de gratuité.

Commenter

Vous devez être inscrit et identifié pour utiliser cette fonction.

Connectez-vous (déjà inscrit)

Oubli de mot de passe ? Pas de panique, on va le retrouver

Pas encore inscrit ? C'est très simple et gratuit.