Calidad del código

La calidad del código es un tema que nació con la programación. ISO 9000 se utiliza para evaluar y controlar la calidad de la gestión empresarial, GOST y el mismo ISO se utilizan para productos, pero no existe un código GOST para la evaluación de calidad. Tampoco hay una definición exacta y estándar para la calidad del código.



Cada desarrollador entiende la calidad a su manera, basada en la experiencia. Las opiniones de los joons y el protagonista son diferentes, y esto lleva al desacuerdo. Cada equipo para proyectos individuales evalúa el código a su manera. El equipo se está actualizando, los desarrolladores se van, los líderes del equipo están cambiando, la definición de calidad está cambiando. Ivan Botanov ( StressoID ) de Tinkoff.ru, Frontend-developer, un tutor en línea en Angular, un orador en reuniones y conferencias, un tutor en YouTube y, a veces, un entrenador de equipo en empresas, intentará ayudar a resolver este problema.

Al descifrar el informe de Ivan sobre Frontend Conf, hablaremos sobre legibilidad, nomenclatura, declarativa, estilo de Código e indirectamente tocaremos las relaciones de June y Lead: errores, rastrillos y "quema" de líderes de equipo.

Descargo de responsabilidad: Prepárese mentalmente, habrá un montón de código incorrecto en el texto , tomado de un sitio "especial" .


Un poco de historia


Todos escribimos de diferentes maneras. Es posible que haya notado esto cuando cambió su lugar de trabajo, proyecto o equipo; cosas inusuales son evidentes de inmediato. Esto también me ha pasado muchas veces, por eso nació este informe. Me concentré en desarrolladores novatos, pero el artículo será útil para aquellos que ya administran más que escriben o personalizan procesos de desarrollo. De qué vamos a hablar:

  • Sobre los problemas del código ilegible.
  • Discutamos el nombramiento.
  • Veamos cuáles son las diferencias entre el estilo declarativo y el imperativo, y cuáles son los problemas.
  • Acerca de la modularización y escritura de códigos.
  • Sobre el estilo del Código y la deuda técnica, sobre los compromisos y el flujo de git.
  • Acerca de las herramientas que puede usar y la corrección de errores en el producto.

Antes de comenzar, haré la pregunta: "¿Cuántos programadores debe despegar el autobús para que el proyecto deje de desarrollarse?" . La respuesta correcta: todos.

¿Qué es un factor de bus?


Condicionalmente, Petya o Vasya están trabajando en el equipo, que sabe todo sobre el proyecto: acuden a él, le preguntan sobre esto y aquello, cómo funciona aquí y cómo funciona allí. Todos dependen de Petya, el número de autobús del proyecto es uno. Cuanto menor es el número, más difícil es desarrollar el proyecto, porque todos distraen a Petya, y él es genial, y debe hacer las tareas y no responder preguntas.

¡Dirás lo genial que es ser Pete! Todos lo aman, lo aprecian, lo necesitan.

Esto no es asi. Por lo general, Petya es un líder de equipo y debe ocuparse de otras tareas: discutir el desarrollo del proyecto, construir arquitectura, administrar el equipo, pero no ir a las dunas y explicar por qué está escrito aquí y no de otra manera.

Si el código es limpio y bueno, entonces es bueno leerlo y hay menos preguntas de Jones. El código limpio aumenta la viabilidad del proyecto y reduce el umbral de entrada . Cuando aparecen nuevas personas en el equipo, harán menos preguntas. En dicho proyecto, es más fácil atraer desarrolladores debido al bajo umbral de entrada.

El código de calidad aumenta los números de los autobuses.

Legibilidad


La legibilidad se ve afectada por la sangría, el nombre torcido y la anidación fuerte; muchos proyectos sufren de esto. Además de la sangría, los operadores ternarios de varias líneas, la falta de un único estilo de Código, una combinación de enfoques de desarrollo y la redefinición no obvia de variables reducen la legibilidad. Todas estas son las causas más comunes de mala legibilidad del código.

Para mí, he identificado el término código lineal : este es un código que se puede leer como un libro.

El código lineal se lee de izquierda a derecha, de arriba a abajo, sin tener que volver al código escrito anteriormente.

Un ejemplo de dicho código:

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); } }) } }) } }) } }) 

Este código es lineal, pero tiene otro problema: está muy anidado. Por lo tanto, también debemos monitorear el anidamiento.

Ejemplo de código no lineal :

 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 descartamos todo lo que es superfluo y descubrimos qué rompe la linealidad, entonces veremos algo como esto:

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

Cuando hay más, primero hay que mirar lo que está escrito en un lugar, luego en otro. Si es grande o está muy anidado, entonces la atención está dispersa y el código es difícil de leer.

¿Cómo reducir el anidamiento y lograr un código lineal?


Combinar condiciones . Esto es lo más simple que podemos hacer: anidar si puedo combinar en condición y reducir ligeramente la anidación.

Fue:

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

Se convirtió en:

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

Aplicar un patrón de retorno temprano . Le permite deshacerse por completo de otra cosa. Puedo reemplazar el método o un fragmento de código con if-else con un retorno temprano, y luego se ejecutará un bloque de código u otro. Esto es muy conveniente: no tiene que desplazarse y volver a algunas partes del código.

Fue:

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

Se convirtió en:

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


Aplicar cadena de promesa . Este es un código típico de transportador. Escribí pruebas E2E no hace mucho tiempo, y ese código me dolió los ojos:

 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'); }); }); }) 

Con la cadena de promesa, el código se convierte:

 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 usamos el conocimiento de la función de flecha, podemos hacer esto:

 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')); 

Es legible, declarativo, hermoso: todo es claramente visible.

Orden superior observable. Como soy angular y uso RxJS, me enfrento con el problema de una fuerte anidación del código de espagueti - Observable anidado, es decir, suscripciones anidadas. Hay una secuencia, y dentro de la secuencia necesitas obtener el valor y luego algo que ver con otra secuencia. Algunos escriben así:

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

Y esto realmente afecta los proyectos para adultos. Puedes hacer esto:

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

Aplicando el conocimiento de la API RxJS, nos alejamos de la anidación fuerte, gracias a un orden superior observable , y llegamos a declarativa . Esta cosa, que arroja el valor del flujo interno al externo, es todo. Pero es limpio, lineal, hermoso y no invertido.

Operadores ternarios anidados


En mi opinión, lo peor que se puede encontrar en el código son los operadores ternarios anidados . Vuelva a escribirlos en declaraciones condicionales de bloque, trate de no usarlos en absoluto. No hablaremos sobre condiciones implícitas en absoluto; esto es un fracaso.

Un ejemplo de operadores ternarios anidados y condiciones implícitas:

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

Escribí este simple ternario en 5 minutos. Tiene la longitud de la matriz y algunas operaciones, pero es difícil de leer, porque en algún lugar una pregunta, en otro lugar, no todo está claro. Este código puede reescribirse utilizando operadores ternarios anidados de varias líneas:

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

Tu dirás:

- Ok, bien!
- Visto?
- ¡ Es visible!

Y qué dices a esto:

 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; })(); })() ); 

Alguien escribió y apoyó este ternarnik. Al acceder a dicha sección de código, será difícil determinar dónde comienza el signo de interrogación y dónde termina. Si usa ternaries, no invierta el uno en el otro, esto es malo.

Nombrar


Otro mal código:

 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; } }; 


Podemos decir que este código está ofuscado , pero aun así: vemos que hay una función comprensible, un 'dato' claro, setCookie hace algo, y luego es simplemente una manta y nada está claro: algo está concatenado , en algún lugar espacios. Todo esta muy mal.

Lo que debe considerar al nombrar


Use la notación CamelCase : camelCaseNotation . No hay transliteración, todos los nombres de los métodos están solo en inglés : ssylka, vikup, tovar, yslyga o checkTovaraNaNalichieTseni es un fracaso. Este último, por cierto, lo escribí cuando recién comenzaba a programar.

Sin elemento, datos, el, html, arr , especialmente cuando se itera a través de matrices. Por ejemplo, para una variedad de productos u ofertas, elija nombres descriptivos: product, offer, etc La diferencia entre artículo y producto no es tan grande, pero la legibilidad es mayor. Incluso si tiene una función de una línea que agrega algo, un nombre amigable para los negocios aumentará la legibilidad.

private_property para propiedades privadas : propiedad_privada . Agregué esta regla porque he estado escribiendo TypeScript por segundo año, pero no hay modificadores de acceso en JS, y en la convención de nomenclatura acordamos que el guión bajo define propiedades privadas para otros desarrolladores.

Constantes en mayúsculas : const BLOCK_WIDTH = 300; y nombres de clase en mayúsculas: class SomeClass . Escribo en TypeScript y todo está claro allí, todo está claro en ES6 , pero también hay proyectos heredados en los que todas las clases de funciones con el new operador escriben en mayúsculas.

No hay variables de una letra : u = user . Esta es una referencia a i - no. Escriba claramente, es decir, negocios funcionalmente. No es necesario hacer el método Check, que verifica algo, pero lo que no está claro. Escriba los nombres de addProductToCard(); sendFeedback() de los métodos : addProductToCard(); sendFeedback() addProductToCard(); sendFeedback() .

Imperatividad


Una pequeña digresión. La impedancia apareció simultáneamente con la programación. En ese momento, codificaron en Assembler y escribieron imperativamente: cada comando, cada paso se describió en detalle y se asignó una celda de memoria al valor. Vivimos en 2019 y ya no escribimos en JS.



Este es un código simple pero imperativo que tiene un bucle for, variables. No está claro por qué se agregan aquí.

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

Problemas de código imperativo : muchas variables, muchas construcciones de mantenimiento de estas variables y muchos comentarios, porque estas variables deben describirse de alguna manera: no puede crear una variable y olvidarse de ella. Todo esto afecta la legibilidad del código.

Declaratividad


El estilo declarativo ha reemplazado. Escribimos en JavaScript y está disponible para nosotros. El estilo declarativo se ve así:

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

Esto es lo mismo que en el imperativo, pero mucho más simple y más comprensible.

Beneficios de un código declarativo


Dicho código es más fácil de leer, mantener y probar, y las construcciones de código complejas pueden ocultarse detrás de métodos y abstracciones. Puedes entender las diferencias entre el estilo imperativo y declarativo con el ejemplo de freír huevos. Para freír huevos fritos en un estilo imperativo, tomamos una sartén, la ponemos al fuego, vertimos aceite, tomamos un huevo, lo rompemos, lo derramamos. En un estilo declarativo, decimos: "Huevos fritos", y el proceso estará oculto detrás de las abstracciones. Queremos freír huevos revueltos, no descubrir cómo funciona.

Los problemas comienzan cuando desarrolladores poco experimentados provienen de la universidad donde estudiaron a Pascal y escriben así:

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


Esta es una combinación de estilos declarativos e imperativos. No hay legibilidad, no hay imperativo completo, algunas variables y if . Esto if persona agregó porque simplemente no sabía sobre el filtro. Si eres un cliente potencial y ves ese código, sube, haz un enlace con un palo y lleva el código a declarativo.

Crear variables


No cree variables por el bien de las variables, esta es una mala idea. Cuando descubrí por los desarrolladores por qué están haciendo esto, escuché:

- Bueno, ¡aumenta la legibilidad!

¿Qué aumenta la legibilidad aquí: const username = user.name ? Si desea crear una variable, asigne importancia al nombre. Por ejemplo, tenemos una expresión regular:

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

Aquí crearía una variable para que una persona no pierda tiempo en los procedimientos, pero lea que esto revisa regularmente el teléfono y va más allá. Si tiene operaciones matemáticas, también escriba en una variable, porque, con seguridad, la operación matemática tiene una entidad comercial, un hito comercial determinado, por ejemplo, para calcular la canasta o hacer un descuento. En este caso, puede crear una variable.

Crear una variable para crear variables no vale la pena.

Redefinición clara de variables


Supongamos que creamos una variable de element , cuyo nombre no está claro de qué se trata. Escribimos un element DOM, escribimos su anulación en una matriz por alguna razón, y nos fuimos:

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

Todo está bien, desaparecido, olvidado. Siguiendo a Petya, que trabaja en nuestro equipo, entró y agregó el bloque if . Que es Simplemente redefiní la variable nuevamente, y me fui. Y el alcance ya es diferente. Cuando el próximo desarrollador intente entender este código, especialmente si el método es grande, esperará someId o someItem , y allí no lo será en absoluto. Este es un lugar donde puede perder mucho tiempo buscando cuál es el problema. Vamos a escribir un debugger , poner un brake point , ver qué hay allí, en general, no escribir así.

División en métodos


Consideramos brevemente la división en métodos y avanzamos suavemente hacia las abstracciones.

Los métodos deben tener funcionalidad atómica : un método, una acción . Si tiene una acción de una línea, no la mezcle todavía, simplemente porque el método es muy pequeño. El método no debe tener más de 10 líneas. Esta declaración provoca un holivar y ahora también "dispara", así que escríbeme o en los comentarios, y explicaré por qué escribí esta regla.

Modularidad de código


La modularidad mejora la legibilidad del código al dividirse en abstracciones, ayuda a "ocultar" el código difícil de leer, es más fácil de probar y es más fácil corregir errores . Explicaré con más detalle.

Escondiéndose detrás de abstracciones


Por ejemplo, hay un código que crea un botón, le asigna una identificación, una clase y hace clic en él; todo es simple.

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

Puede agregar una función al código del botón, ajustarlo y usar la función createButton al crear el botón:

 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; } 

Por el nombre "parlante" queda claro qué hace la función y se pasa esa identificación. Si queremos hacer un botón y no entender cómo se crea y por qué, escribimos código usando esta función.

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

A continuación, escribimos helper , que luego utilizan otros desarrolladores. Si quieren entender cómo se fríen los huevos revueltos o si quieren cambiar la receta: agregar o quitar sal, pasarán por allí y venerarán.

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

Escribiendo


No hablaré sobre escribir durante mucho tiempo, hay un montón de informes. Escribo en TypeScript, me gusta, pero todavía hay flujo y otras herramientas. Si no tiene escrito en su proyecto, entonces es hora de implementarlo. Esto ayuda a depurar un montón de errores.

Olores de código


Los olores de código están muy entrelazados con mi tema, porque escribir código de baja calidad genera los mismos olores. Mira el genial informe de Alexei Okhrimenko , toca este tema en detalle.

Estilo de código


Este es el conjunto de reglas de equipo, proyecto o empresa a las que se adhieren los desarrolladores. Un buen estilo de código contiene ejemplos de código bueno y malo. Se puede escribir en cualquier herramienta y lugar conveniente. Tenemos este Wiki, y para una pequeña empresa, un archivo en Word es suficiente. También puede tomar el estilo de Código ya preparado, que ya utilizan otras compañías: JQuery , Google o Airbnb , el estilo de Código más popular.

Si usa una tecnología o marco específico, generalmente también tienen su propio estilo de Código, que vale la pena ver. Por ejemplo, en Angular, esta es la Guía de estilo angular , o la Guía de estilo React / JSX de Airbnb.

Este es un ejemplo de nuestro estilo de código.



Aquí hay una sección para crear variables, y describe cómo no hacer y cómo hacerlo.

Deuda técnica


Este es un tipo de pago por el hecho de que alguna vez cortamos el césped. A menudo, una deuda técnica nace cuando no tenemos tiempo para completar una tarea y escribir un recordatorio para volver a ella más tarde. De los casos que no están relacionados con las funcionalidades del negocio, esto es, por ejemplo, actualizar el marco.

La deuda tecnológica genera muletas y un código de baja calidad.

Debido a la deuda técnica, escribo mal código y muletas. El próximo desarrollador verá esto, eso es todo, verá las jambas y agregará otra muleta: "Si todavía hay algo de soporte, no hay nada malo". La deuda tecnológica genera muletas, se pierde calidad, lo que nuevamente genera muletas, y aumentan aún más la deuda tecnológica.

Existe una teoría de "ventanas rotas" . Si aparece una ventana rota en el edificio y no se cambia, luego de un tiempo aparecerá una segunda ventana rota, una tercera, graffiti. La gente ve que nadie está siguiendo el edificio y el castigo por ventanas rotas no debería serlo. Así es el código. A menudo, en proyectos heredados, el código está rodeado de muletas, porque Petit y Vasya condicional ven muletas y piensan: "Está bien, seré el primero". Por lo tanto, en las empresas normales, a la deuda técnica se le da suficiente tiempo: o toman una cuota o un sprint técnico que resolverá el problema. Si usted es un líder, o influye de alguna manera en los procesos de construcción de sprints y la lista de tareas que se toman en el trabajo, preste atención a la deuda técnica, esto es importante.

Repositorio


Analicemos los mensajes de confirmación. La imagen muestra ejemplos de mensajes reales que vi en diferentes proyectos. ¿Cuáles de ellos crees que son informativos?



Respuesta correcta
Los mensajes informativos están en bloques, pero "se agregó una función", "se solucionó un error", no son informativos.

Confirmar mensajes


Escribo en WebStorm y me encanta. En él, puede configurar el resaltado de los números de tareas, la transición cuando hace clic en el Rastreador de tareas es genial. Si alguien no usa WebStorm, entonces es hora, porque con él, los mensajes de confirmación se obtienen en alta calidad. ¿Qué es un mensaje de compromiso de calidad? Esta es una confirmación, en la que hay un número de tarea y una declaración breve pero sucinta de la esencia de los cambios : "hizo un nuevo módulo", "agregó un botón", "agregó una función donde se crea el componente", y no una "característica agregada" sin rostro. Al ver las confirmaciones, quedará claro dónde se agregó el componente y dónde se solucionó el error. Incluso en los mensajes de confirmación, es necesario indicar el tipo de cambios : función, corrección de errores, para que quede claro en qué se produjeron los cambios.

Gitflow


Hablaré brevemente sobre Gitflow. Descripción detallada en la traducción del artículo de Vincent Driessen . Gitflow es uno de los modelos de gestión de repositorios más populares y exitosos, que tiene las ramas principales : desarrollo, maestro, preprod, prod y ramas temporales : característica, error, lanzamiento. Cuando comenzamos la tarea, desviamos la rama de características de la rama de desarrollo. Después de pasar la revisión del código en la rama de características, la volvemos a desarrollar. Al final, recopilamos lanzamientos de desarrollo y lanzamiento en master.



Las herramientas


El primero es el ciudadano . Esta es una utilidad de software que aprendí no hace mucho tiempo: me parecía, sentía, me gustaba. Le permite estandarizar confirmaciones de mensajes, tiene una interfaz de consola agradable en la que puede seleccionar funciones. Si se ha comprometido con el espíritu de "corregir una función" o "corregir un error", entonces es hora de mostrar a los muchachos Commitizen para que puedan usarlo al menos para empezar, y luego puede escribirlo desde la cabeza.

Linters es una herramienta imprescindible en todos los proyectos. Hay muchas configuraciones listas para usar en linters, pero puede escribir sus propias reglas . Si tiene sus propias reglas, entonces el linter debería indicar estas reglas; deberá escribir las reglas para su estilo de Código.
Enlaces útiles en linter:


Un párrafo separado asignado sonarJS . Esta es una herramienta que le permite integrar la validación de código en CI. Por ejemplo, hacemos una solicitud de extracción, y luego sonarJS escribe para solicitar la extracción de nuestras escuelas, y molesta o no. Esto es genial, me gustó. Incluso si el condicional Vasya piensa que nadie notará su canto, él notará sonarJS.

La herramienta se integra fácilmente en Jenkins. Nuestros muchachos construyeron lo suficientemente rápido. Lo más probable es que se integre en otros sistemas, pero no lo hemos probado. SonarJS sigue comprobando el código para detectar olores de código. Para ser honesto, no sé si Linter ordinario hace esto.

Formateadores o estilistas es una herramienta que formatea el código de acuerdo con una configuración, por ejemplo, Prettier . Puede configurarlo para el gancho previo a la inserción y obtener un estilo de código uniforme en el repositorio. Petya de nuestro equipo puede poner 500 espacios, o no escribir un punto y coma, todo estará limpio y hermoso en el repositorio.

El formateador le permite mantener el código en un solo estilo.

Quería contar una historia que nos pasó. Implementamos Prettier en un proyecto que escribió muchas tareas y decidimos no ejecutar todo el proyecto a través de él, sino solo piezas de código con características. Nos pareció que gradualmente saldríamos y no estropearíamos la historia de los compromisos: en la anotación veremos quién es el último en gobernar. Esa fue una mala decisión. Cuando realizamos la tarea y la solicitud de extracción, y cambiamos un par de líneas, Prettier formateó todo el archivo, y cuando vimos la solicitud de extracción, ¡solo había dos líneas! Esto tomó una tonelada de tiempo de revisión de código. Por lo tanto, si desea implementar Prettier, ejecute todo el proyecto .

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

Sentry, . Por qué , Sentry. .


.


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

Sentry StackTrace — , .


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

-


- , .

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

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

: Twitter Facebook .

Frontend Conf . ? Frontend Conf ++ : , , .

— FrontendConf ++. — , . , 27

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


All Articles