Qualité du code

La qualité du code est un thème né de la programmation. ISO 9000 est utilisé pour évaluer et contrôler la qualité de la gestion d'entreprise, GOST et la même ISO sont utilisés pour les produits, mais il n'y a pas de code GOST pour l'évaluation de la qualité. Il n'y a pas non plus de définition exacte ni de norme pour la qualité du code.



Chaque développeur comprend la qualité à sa manière, basée sur l'expérience. Les vues des joons et du plomb sont différentes, ce qui conduit à des désaccords. Chaque équipe pour des projets individuels évalue le code à sa manière. L'équipe est mise à jour, les développeurs partent, les chefs d'équipe changent - la définition de la qualité change. Ivan Botanov ( StressoID ) de Tinkoff.ru, développeur frontend, un tuteur en ligne sur Angular, un conférencier lors de réunions et de conférences, un tuteur sur YouTube et parfois un coach d'équipe dans les entreprises, tentera d'aider à résoudre ce problème.

En décodant le rapport d'Ivan sur Frontend Conf, nous parlerons de lisibilité, de dénomination, de caractère déclaratif, de style de code, et aborderons indirectement les relations de juin et de Lead: erreurs, ratisser et «brûler» des chefs d'équipe.

Avertissement: Préparez-vous mentalement, il y aura beaucoup de mauvais code dans le texte , provenant d'un site "spécial" .


Un peu d'histoire


Nous écrivons tous de différentes manières. Vous l'avez peut-être remarqué lorsque vous avez changé de lieu de travail, de projet ou d'équipe - des choses inhabituelles sont immédiatement évidentes. Cela m'est également arrivé plusieurs fois, c'est pourquoi ce rapport est né. Je me suis concentré sur les développeurs novices, mais l'article sera utile à ceux qui gèrent déjà plus que d'écrire ou de personnaliser les processus de développement. De quoi allons-nous parler:

  • Ă€ propos des problèmes de code illisible.
  • Discutons du nommage.
  • Voyons quelles sont les diffĂ©rences entre le style dĂ©claratif et impĂ©ratif, et quels sont les problèmes.
  • Ă€ propos de la modularisation et de la frappe du code.
  • Ă€ propos du style de code et de la dette technique, des commits et du flux git.
  • Ă€ propos des outils que vous pouvez utiliser et de la correction des erreurs dans le prod.

Avant de commencer, je pose la question: "Combien de programmeurs le bus doit-il décoller pour que le projet cesse de se développer?" . La bonne réponse: tout le monde.

Qu'est-ce qu'un facteur de bus?


Conditionnellement, Petya ou Vasya travaille en équipe, qui sait tout sur le projet: ils vont le voir, lui demandent ceci et cela, comment ça marche ici, et comment ça marche là-bas. Tout le monde dépend de Petya, le numéro de bus du projet est un. Plus le nombre est petit, plus il est difficile de développer le projet, car tout le monde distrait Petya, et il est cool, et doit faire les tâches, et ne pas répondre aux questions.

Vous direz à quel point c'est cool d'être Pete! Tout le monde l'aime, l'apprécie, a besoin de lui.

Ce n'est pas le cas. Habituellement, Petya est un chef d'équipe, et il doit faire face à d'autres tâches: discuter du développement du projet, construire l'architecture, gérer l'équipe, mais n'allez pas dans les dunes et expliquez pourquoi il est écrit ici et pas autrement.

Si le code est propre et bon, alors c'est bien de le lire et il y a moins de questions des jones. Un code propre augmente la viabilité du projet et abaisse le seuil d'entrée . Lorsque de nouvelles personnes apparaissent dans l'équipe, elles poseront moins de questions. Dans un tel projet, il est plus facile d'attirer les développeurs en raison du seuil d'entrée bas.

Le code de qualité augmente les numéros de bus.

Lisibilité


La lisibilité est affectée par l'indentation, la dénomination tordue et l'imbrication forte - de nombreux projets en souffrent. Outre l'indentation, les opérateurs ternaires multilignes, l'absence d'un style de code unique, une combinaison d'approches de développement et une redéfinition non évidente des variables réduisent la lisibilité. Tous ces facteurs sont les causes les plus courantes de mauvaise lisibilité du code.

Pour ma part, j'ai identifié le terme code linéaire - c'est un code qui peut être lu comme un livre.

Le code linéaire se lit de gauche à droite, de haut en bas, sans avoir à revenir au code précédemment écrit.

Un exemple d'un tel code:

list.forEach((element1) => { if (element1.parent_id == null) { output.push(element1); list.forEach((element2) => { if (element2.parent_id == element1.id) { output.push(element2); list.forEach((element3) => { if (element3.parent_id == element2.id) { output.push(element3); list.forEach((element4) => { if (element4.parent_id == element3.id) { output.push(element4); } }) } }) } }) } }) 

Ce code est linéaire, mais il a un autre problème - il est fortement imbriqué. Par conséquent, nous devons également surveiller la nidification.

Exemple de code non linéaire :

 if(!brk && html.childNodes[0].value && html.childNodes[0].max) { if(clear) html.childNodes[0].value = 1; else if(html.childNodes[0].value <= html.childNodes[0].max) { ++ html.childNodes[0].value; if(brk) { for(id = 1; id < html.childNodes.length; ++ id) findActive(html.childNodes[id], true); html.parentNode.className = ""; } return null; } else { html.parentNode.className = "Ready"; html.className = ""; return html; } } 

Si nous rejetons tout ce qui est superflu et découvrons ce qui rompt la linéarité, alors nous verrons quelque chose comme ceci:

 if (condition) { return; } else { return; } 

Lorsqu'il y a autre chose, vous devez d'abord regarder ce qui est écrit à un endroit, puis à un autre. S'il s'agit d'un si grand ou fortement imbriqué, alors l'attention est dispersée et le code est difficile à lire.

Comment réduire l'imbrication et obtenir un code linéaire?


Combinez les conditions . C'est la chose la plus simple que nous puissions faire - imbriquée si je peux combiner en condition et réduire légèrement l'imbrication.

C'Ă©tait:

 if (isUser()) { if (isAdmin()) { console.log('admin'); } } 

C'est devenu:

 if(isUser() && isAdmin()) { console.log('admin'); } 

Appliquer un modèle de retour précoce . Il vous permet de vous débarrasser complètement des autres. Je peux remplacer la méthode ou un morceau de code par if-else avec un retour anticipé, puis un bloc de code ou un autre sera exécuté. C'est très pratique - vous n'avez pas à faire défiler et revenir à certaines parties du code.

C'Ă©tait:

 if (isAdmin()) { return admin; } else { return user; } 

C'est devenu:

 if (isAdmin()) { return admin; } return user; 


Appliquer la chaîne de promesse . Il s'agit d'un code Protractor typique. J'ai écrit des tests E2E il n'y a pas si longtemps, et un tel code m'a fait mal aux yeux:

 ptor.findElement(protractor.By.id('q01_D')).click().then(() => { ptor.findElement(protractor.By.id('q02_C')).click().then(() => { ptor.findElement(protractor.By.id('q03_D')).click().then(() => { console.log('done'); }); }); }) 

Avec la chaîne de promesses, le code se transforme:

 ptor.findElement(protractor.By.id('q01_D')).click() .then(() => { return ptor.findElement(protractor.By.id('q02_C')).click(); }) .then(() => { return ptor.findElement(protractor.By.id('q03_D')).click(); }) .then(() => { console.log('done'); }); 


Si nous utilisons la connaissance de la fonction flèche, nous pouvons le faire:

 ptor.findElement(protractor.By.id('q01_D')).click() .then(() => ptor.findElement(protractor.By.id('q02_C')).click()) .then(() => ptor.findElement(protractor.By.id('q03_D')).click()) .then(() => console.log('done')); 

Il est lisible, déclaratif, beau - tout est clairement visible.

Ordre supérieur observable. Étant donné que je suis un angulaire et que j'utilise RxJS, je suis confronté au problème de l'imbrication forte du code spaghetti - imbriqué observable , c'est-à-dire des abonnements imbriqués. Il y a un flux, et à l'intérieur du flux, vous devez obtenir la valeur, puis quelque chose à faire avec un autre flux. Certains écrivent comme ceci:

 Observable.of(1,2,3) .subscribe(item => { item += 2; Observable.of(item) .subscribe(element => { element += 1; }) }) 

Et cela affecte vraiment les projets pour adultes. Vous pouvez le faire:

 Observable.of(1,2,3) .mergeMap(item => Observable.of(item + 2)) .mergeMap(element => Observable.of(element + 1)) .subscribe() 

En appliquant les connaissances de l'API RxJS, nous nous sommes éloignés de l'imbrication forte, grâce à un ordre supérieur observable , et sommes arrivés à la déclaration . Cette chose, qui jette la valeur du flux interne vers l'extérieur, c'est tout. Mais c'est propre, linéaire, beau et pas investi.

Opérateurs ternaires imbriqués


À mon avis, le pire que l'on puisse trouver dans le code est les opérateurs ternaires imbriqués . Réécrivez-les sur les instructions conditionnelles de bloc, essayez de ne pas les utiliser du tout. Nous ne parlerons pas du tout de conditions implicites - c'est un échec.

Un exemple d'opérateurs ternaires imbriqués et de conditions implicites:

 arr.length > 0 ? arr[1] == 1 ? arr[1] = 2 : arr[1] = 1 : console.log('empty arr'); !a && b && func() 

J'ai écrit ce simple ternaire en 5 minutes. Il a la longueur du tableau et certaines opérations, mais il est difficile à lire, car quelque part une question, quelque part ailleurs - tout n'est pas clair. Ce code peut être réécrit à l'aide d'opérateurs ternaires imbriqués sur plusieurs lignes:

 arr.length > 0 ? arr[1] === 1 ? arr[1] = 2 : arr[1] = 1 : console.log('empty arr'); 

Vous direz:

- D' accord, d'accord!
- Vu?
- C'est visible!

Et que répondez-vous à ceci:

 return query instanceof RegExp ? (function () { fn.each(function (id) { if (id.match(query)) { seatSet.push(id, this); } }); return seatSet; })() : (query.length == 1 ? (function (character) { //user searches just for a particual character fn.each(function () { if (this.char() == character) { seatSet.push(this.settings.id, this); } }); return seatSet; })(query) : (function () { //user runs a more sophisticated query, so let's see if there's a dot return query.indexOf('.') > -1 ? (function () { //there's a dot which separates character and the status var parts = query.split('.'); fn.each(function (seatId) { if (this.char() == parts[0] && this.status() == parts[1]) { seatSet.push(this.settings.id, this); } }); return seatSet; })() : (function () { fn.each(function () { if (this.status() == query) { seatSet.push(this.settings.id, this); } }); return seatSet; })(); })() ); 

Quelqu'un a écrit et soutenu ce ternarnik. En accédant à une telle section de code, il sera difficile de comprendre où le point d'interrogation commence et où il se termine. Si vous utilisez des ternaires, veuillez ne pas investir les uns dans les autres - c'est mauvais.

Nommer


Un autre mauvais code:

 var _0x30119c = function() { var _0x3af68e = { 'data': { 'key': 'cookie', 'value': 'timeout' }, 'setCookie': function(_0x3543f3, _0x13e5c1, _0x586dac, _0x1c9d63) { _0x1c9d63 = _0x1c9d63 || {}; var _0x47b83f = _0x13e5c1 + '=' + _0x586dac; var _0xae3be = 0x0; for (var _0xae3be = 0x0, _0x5d2845 = _0x3543f3['length']; _0xae3be < _0x5d2845; _0xae3be++) { var _0x440369 = _0x3543f3[_0xae3be]; _0x47b83f += ';\x20' + _0x440369; var _0x411875 = _0x3543f3[_0x440369]; _0x3543f3['push'](_0x411875); _0x5d2845 = _0x3543f3['length']; if (_0x411875 !== !![]) { _0x47b83f += '=' + _0x411875; } } _0x1c9d63['cookie'] = _0x47b83f; } }; 


Nous pouvons dire que ce code est obscurci , mais même ainsi: nous voyons qu'il y a une fonction compréhensible, des `` données '' claires, setCookie fait quelque chose, puis c'est juste une couverture et rien n'est clair - quelque chose est concaténé , quelque part des espaces. Tout va très mal.

Ce que vous devez considérer lors de la dénomination


Utilisez la notation camelCaseNotation : camelCaseNotation . Il n'y a pas de translittération, tous les noms des méthodes sont uniquement en anglais : ssylka, vikup, tovar, yslyga ou checkTovaraNaNalichieTseni est un échec. Ce dernier, d'ailleurs, j'ai écrit quand je commençais à peine à programmer.

Aucun élément, données, el, html, arr , en particulier lors de l'itération à travers des tableaux. Par exemple, pour une gamme de produits ou d'offres, choisissez des noms conviviaux: product, offer, etc La différence entre l'article et le produit n'est pas si grande, mais la lisibilité est plus élevée. Même si vous avez une fonction d'une ligne qui ajoute quelque chose, un nom convivial augmentera la lisibilité.

private_property pour les propriétés privées : private_property . J'ai ajouté cette règle parce que j'écris TypeScript depuis la deuxième année, mais il n'y a pas de modificateurs d'accès dans JS, et dans la convention de dénomination, nous avons convenu que le trait de soulignement définit des propriétés privées pour les autres développeurs.

Constantes en majuscules : const BLOCK_WIDTH = 300; et les noms de classe en majuscule: class SomeClass . J'écris en TypeScript et tout est clair là-bas, tout est clair dans ES6 , mais il y a aussi des projets hérités dans lesquels toutes les classes de fonctions avec le new opérateur écrivent en majuscules.

Aucune variable d'une lettre : u = user . Il s'agit d'une référence à i - ne pas. Écrivez clairement, c'est-à-dire commercialement. Il n'est pas nécessaire de faire la méthode Check, qui vérifie quelque chose, mais ce qui n'est pas clair. Écrivez l' addProductToCard(); sendFeedback() des méthodes : addProductToCard(); sendFeedback() addProductToCard(); sendFeedback() .

Impérativité


Une petite digression. L'impérativité est apparue simultanément avec la programmation. A cette époque, ils codaient dans Assembler, et écrivaient impérativement: chaque commande, chaque étape était décrite en détail, et une cellule mémoire était affectée à la valeur. Nous vivons en 2019 et n'écrivons donc plus sur JS.



C'est un code simple mais impératif qui a une boucle for, des variables. On ne sait pas pourquoi ils sont ajoutés ici.

 for (let i = 0; i >= 10; i++) { const someItem = conferences[i]; const prefixString = 'Hello '; if (someItem === 'Frontend Conf') { console.log(prefixString + someItem); } } 

Problèmes de code impératifs : beaucoup de variables, beaucoup de constructions de maintenance de ces variables et beaucoup de commentaires, car ces variables doivent être décrites d'une manière ou d'une autre - vous ne pouvez pas créer une variable et l'oublier. Tout cela affecte la lisibilité du code.

DĂ©claration


Le style déclaratif a remplacé. Nous écrivons en JavaScript et il est disponible pour nous. Le style déclaratif ressemble à ceci:

 conferences .filter(someItem => someItem === 'Frontend Conf') .forEach(someItem => console.log('Hello' + someItem)); 

C'est la même chose que dans l'impératif, mais beaucoup plus simple et plus compréhensible.

Avantages d'un code déclaratif


Un tel code est plus facile à lire, à maintenir et à tester, et des constructions de code complexes peuvent être cachées derrière des méthodes et des abstractions. Vous pouvez comprendre les différences entre le style impératif et déclaratif par l'exemple de la friture des œufs. Pour faire frire des œufs frits de façon impérative, nous prenons une poêle, la mettons au feu, versons de l'huile, prenons un œuf, le cassons, le versons. Dans un style déclaratif, nous disons: «Oeufs frits», et le processus sera caché derrière les abstractions. Nous voulons faire frire des œufs brouillés, pas pour comprendre comment cela fonctionne.

Les problèmes commencent lorsque des développeurs peu expérimentés viennent de l'université où ils ont étudié Pascal et écrivent comme ceci:

 const prefix = 'Hello '; conferences .forEach(someItem => { if (someItem === 'Frontend Conf') { const result = prefix + someItem; console.log(result) } }); 


Il s'agit d'une combinaison de styles déclaratifs et impératifs. Il n'y a aucune lisibilité, aucun impératif complet, certaines variables et if . Ceci if personne a ajouté parce qu'il ne savait tout simplement pas sur le filtre. Si vous êtes un lead et voyez un tel code, montez, piquez un lien avec un bâton et amenez le code à déclaratif.

Création de variables


Ne créez pas de variables pour le plaisir de variables - c'est une mauvaise idée. Lorsque j'ai découvert pourquoi les développeurs font cela, j'ai entendu:

- Eh bien, cela augmente la lisibilité!

Qu'est-ce qui augmente la lisibilité ici - const username = user.name ? Si vous souhaitez créer une variable, donnez une signification au nom. Par exemple, nous avons une expression régulière:

 const somePattern = /[0-9]+/; str.split(somePattern); const someResult = a + b - c; 

Ici, je créerais une variable pour qu'une personne ne perde pas de temps sur les procédures, mais lirais que cette vérification régulière du téléphone, et va plus loin. Si vous avez des opérations mathématiques, écrivez également dans une variable, car, bien sûr, l'opération mathématique a une entité commerciale, un certain point de repère commercial, par exemple, pour calculer le panier ou faire une remise. Dans ce cas, vous pouvez créer une variable.

Créer une variable pour créer des variables n'en vaut pas la peine.

Redéfinition peu évidente des variables


Supposons que nous avons créé une variable d' element , à partir du nom de laquelle il n'est pas clair de quoi il s'agit. Nous avons écrit un element DOM, écrit son remplacement dans un tableau pour une raison quelconque, et laissé:

 let element = document.getElementById('someId'); arr.forEach(item => { // ... //      // ... element = document.getElementById('someItem') if (typeof item === 'string') { let element = document.getElementById('some' + item); element.appendChild(); } }); 

Tout va bien, disparu, oublié. Après Petya, qui travaille dans notre équipe, est venu et a ajouté le bloc if . Qu'est ce que c'est? Juste redéfini la variable à nouveau, et à gauche. Et la portée est déjà différente. Lorsque le développeur suivant essaie de comprendre ce code, surtout si la méthode est volumineuse, il attendra someId ou someItem , et là ce n'est pas du tout. C'est un endroit où vous pouvez perdre beaucoup de temps à chercher quel est le problème. Nous allons écrire un debugger , mettre un brake point , voir ce qui est là - en général, ne pas écrire comme ça.

Division en méthodes


Nous considérons brièvement la division en méthodes et passons en douceur aux abstractions.

Les méthodes devraient porter la fonctionnalité atomique : une méthode - une action . Si vous avez une action sur une seule ligne, ne la mélangez pas encore, tout simplement parce que la méthode est si petite. La méthode ne doit pas dépasser 10 lignes. Cette déclaration provoque un holivar et maintenant aussi des "shoots", alors écrivez-moi ou dans les commentaires, et je vous expliquerai pourquoi j'ai écrit cette règle.

Modularité du code


La modularité améliore la lisibilité du code en se divisant en abstractions, aide à «masquer» le code difficile à lire, il est plus facile à tester et il est plus facile de corriger les erreurs . Je vais vous expliquer plus en détail.

Se cacher derrière des abstractions


Par exemple, il existe du code qui crée un bouton, lui attribue un identifiant, une classe et clique dessus - tout est simple.

 const element = document.createElement('button'); element.id = 'id_button'; element.classList = 'red'; document.body.appendChild(element); element.click(); 

Vous pouvez ajouter une fonction au code du bouton, l' createButton et utiliser la fonction createButton lors de la création du bouton:

 const.button = createButton('id_button'); button.click(); function createButton((id') { element = document.createElement('button'); element.id = id; element.classList = 'red'; document.body.appendChild(element); return element; } 

Par le nom "parlant", il est clair ce que fait la fonction et cet identifiant est transmis. Si nous voulons créer un bouton et ne pas comprendre comment il est créé et pourquoi, nous écrivons du code en utilisant cette fonction.

 button.component.js let button = createButton('id_button'); button.click(); 

Ensuite, nous écrivons helper , qui sera ensuite utilisé par d'autres développeurs. S'ils veulent comprendre comment les œufs brouillés sont frits ou veulent changer la recette - ajoutez ou retirez du sel, ils passeront et vénéreront.

 button.helpers.js function createButton(id) { let button = document.createElement('button'); button.id = id; button.classList = 'red'; document.body.appendChild(element); return button; } 

Dactylographie


Je ne parlerai pas de taper pendant longtemps - il y a un tas de rapports. J'écris en TypeScript, j'aime bien, mais il y a encore du flux et d'autres outils. Si vous n'avez pas de saisie dans votre projet, il est temps de l'implémenter. Cela aide à déboguer un tas d'erreurs.

Le code sent


Les odeurs de code sont très étroitement liées à mon thème, car l'écriture de code de mauvaise qualité génère les mêmes odeurs. Regardez le rapport cool d'Alexei Okhrimenko , il aborde ce sujet en détail.

Style de code


Il s'agit de l'ensemble de règles d'équipe, de projet ou d'entreprise auxquelles les développeurs adhèrent. Un bon style de code contient des exemples de bon et de mauvais code. Il peut être écrit dans n'importe quel outil et endroit pratique. Nous avons ce Wiki, et pour une petite entreprise, un fichier Word suffit. Vous pouvez également prendre le style Code prêt à l'emploi, qui est déjà utilisé par d'autres sociétés: JQuery , Google ou Airbnb - le style Code le plus populaire.

Si vous utilisez une technologie ou un framework spécifique, ils ont généralement leur propre style de code, qui vaut le coup d'œil. Par exemple, dans Angular, il s'agit du Angular Style Guide ou du React / JSX Style Guide d'Airbnb.

Ceci est un exemple de notre style de code.



Voici une section pour créer des variables et décrit comment ne pas faire et comment.

Dette technique


C'est une sorte de paiement pour le fait que nous avons fauché quelque part. Souvent, une dette technique naît lorsque nous n'avons pas le temps de terminer une tâche et d'écrire un rappel pour y revenir plus tard. Parmi les cas qui ne sont pas liés aux fonctionnalités métier, il s'agit par exemple de la mise à jour du framework.

La dette technologique engendre des béquilles et un code de mauvaise qualité.

À cause de la dette technique, j'écris du mauvais code et des béquilles. Le prochain développeur va regarder ça, c'est tout, voir les montants et ajouter une autre béquille: "S'il y a encore du support, il n'y a rien de mal." La dette technologique engendre des béquilles, la qualité est perdue, ce qui engendre à nouveau des béquilles, et elles augmentent encore plus la dette technologique.

Il existe une théorie des «fenêtres cassées» . Si une fenêtre cassée apparaît dans le bâtiment et qu'elle n'est pas modifiée, après un certain temps, une deuxième fenêtre cassée apparaîtra, une troisième, des graffitis. Les gens voient que personne ne suit le bâtiment et la punition pour les fenêtres cassées ne devrait pas l'être. Le code aussi. Souvent dans les projets hérités, le code est entouré de béquilles, car les conditionnels Petit et Vasya voient des béquilles et pensent: "Ça va, je serai le premier." Par conséquent, dans les entreprises normales, la dette technique dispose de suffisamment de temps - elles prennent un quota ou un sprint technique qui résoudra le problème. Si vous êtes un leader, ou si vous influencez en quelque sorte les processus de construction de sprints et la liste des tâches qui sont mises en œuvre, faites attention à la dette technique - c'est important.

DĂ©pĂ´t


Discutons des messages de validation. L'image montre des exemples de messages réels que j'ai vus dans différents projets. Selon vous, lesquels sont informatifs?



Bonne réponse
Les messages informatifs sont en blocs, mais «ajout d'une fonctionnalité», «correction d'un bug» - ne sont pas informatifs.

Valider les messages


J'écris dans WebStorm et j'adore ça. Dans celui-ci, vous pouvez configurer la mise en surbrillance des numéros de tâche, la transition lorsque vous cliquez dans Task Tracker est cool. Si quelqu'un n'utilise pas WebStorm, il est temps, car avec lui, les messages de validation sont obtenus en haute qualité. Qu'est-ce qu'un message de validation de qualité? Il s'agit d'un commit, dans lequel il y a un numéro de tâche et une déclaration courte mais succincte de l' essence des changements : "a fait un nouveau module", "a ajouté un bouton", "a ajouté une fonctionnalité où le composant est créé", et pas une "fonctionnalité ajoutée" sans visage. Lors de la visualisation des validations, il sera clair où le composant a été ajouté et où le bogue a été corrigé. Même dans les messages de validation, il est nécessaire d'indiquer le type de modifications : fonctionnalité, correction de bogue, afin qu'il soit clair dans lequel les modifications se sont produites.

Gitflow


Je vais parler brièvement de Gitflow. Description détaillée dans la traduction de l'article de Vincent Driessen . Gitflow est l'un des modèles de gestion de référentiel les plus populaires et les plus réussis, qui a les branches principales - développer, master, préprod, prod et branches temporaires : fonctionnalité, bogue, version. Lorsque nous démarrons la tâche, nous détournons la branche de fonctionnalité de la branche de développement. Après avoir passé en revue le code sur la branche de fonctionnalité, nous le réinjectons dans develop. Au final, nous collectons les versions de develop et les versions en master.



Les outils


Le premier est Commitizen . Il s'agit d'un utilitaire logiciel que j'ai appris il n'y a pas si longtemps - j'ai regardé, ressenti, aimé. Il vous permet de normaliser les validations de messages, possède une belle interface de console dans laquelle vous pouvez sélectionner des fonctionnalités. Si vous avez commis dans l'esprit de «corriger une fonctionnalité» ou de «corriger un bogue», il est temps de montrer Commitizen à vos gars afin qu'ils puissent l'utiliser au moins pour commencer, puis vous pouvez l'écrire de la tête.

Linters est un outil indispensable dans chaque projet. Il existe de nombreuses configurations prédéfinies dans les linters, mais vous pouvez écrire vos propres règles . Si vous avez vos propres règles, le linter devrait peloter ces règles - vous devrez écrire les règles de votre style de code.
Liens utiles sur linter:


Un paragraphe séparé a attribué sonarJS . Il s'agit d'un outil qui vous permet d'intégrer la validation de code dans CI. Par exemple, nous faisons une demande d'extraction, puis sonarJS écrit pour extraire la demande de nos écoles, et bouleverse ou non. C'est cool - j'ai bien aimé. Même si le Vasya conditionnel pense que personne ne remarquera son inclinaison - il remarquera sonarJS.

L'outil s'intègre facilement dans Jenkins. Nos gars ont intégré assez rapidement. Très probablement, il s'intègre dans d'autres systèmes, mais nous ne l'avons pas essayé. SonarJS vérifie toujours le code pour les odeurs de code. Pour être honnête, je ne sais pas si un linter ordinaire fait ça.

Les formateurs ou les stylistes sont un outil qui formate le code selon une configuration, par exemple, Prettier . Vous pouvez le configurer pour le pré-push hook et obtenir un style de code uniforme dans le référentiel. Petya de notre équipe peut mettre 500 espaces, ou pas du tout écrire un point-virgule - tout sera propre et beau dans le référentiel.

Le formateur vous permet de conserver le code dans un seul style.

Je voulais raconter une histoire qui nous est arrivée. Nous avons implémenté Prettier dans un projet qui a écrit beaucoup de tâches et avons décidé de ne pas exécuter tout le projet, mais uniquement des morceaux de code avec des fonctionnalités. Il nous a semblé que peu à peu nous sortirions et ne gâcherions pas l'histoire des commits: dans l'annotation nous verrons qui dure. C'était une mauvaise décision. Quand nous avons fait la tâche et la demande de tirage, et changé quelques lignes, Prettier a formaté tout le fichier, et quand nous avons regardé la demande de tirage - seulement deux lignes! Cela a pris une tonne de temps de révision de code. Par conséquent, si vous souhaitez implémenter Prettier, exécutez l'intégralité du projet .

— error tracking runtime. , , . - — . Error tracking DOM-, , . Sentry , TrackJS , .

Sentry, . Pourquoi? , Sentry. .


.


, , : «, iOS, , , Android — , iOS».

Sentry StackTrace — , .


Sentry. , — : . , , : « , ?». — . , . , — «» .

-


- , .

  • .
  • — .
  • .
  • . , frontend-developer Tinkoff.ru.
  • Code style, . — .
  • — . , , .
  • Git Flow — , . — .
  • — , . , .

. « » , — , . . , , , . , , .

: Twitter Facebook .

— Frontend Conf . Ça vous a plu? Frontend Conf ++ : , , .

— FrontendConf ++. — , . , 27

Source: https://habr.com/ru/post/fr433326/


All Articles