Desde que me uní a Zalando, he tenido la oportunidad de sumergirme en algunos proyectos de código abierto como ESLint , un linter de JavaScript conectable. Esta es mi opinión sobre lo que es ESLint, una breve descripción de la formación de pelusa en general y por qué es tan importante.
En términos generales, el linting es una herramienta para el análisis de código estático y, por lo tanto, parte de las pruebas de caja blanca . El objetivo principal de las pruebas de caja blanca es analizar la estructura interna de los componentes o un sistema. Para que esto tenga sentido, un desarrollador ya tendría conocimiento del código escrito y definirá reglas o expectativas sobre cómo debe comportarse un componente (pruebas unitarias) o cómo debe estructurarse (linting).
En el desarrollo web moderno, esto describe el proceso (y las herramientas) de aplicar reglas contra una base de código y marcar las estructuras de código que violan estas reglas. Las reglas pueden variar desde reglas de estilo de código, por lo que el código parece estar escrito por una sola persona, hasta reglas mucho más complejas (por ejemplo , aquí ). Incluso arreglar estos problemas es parte del linting moderno de JavaScript.
El código Linting ya es una parte establecida de cualquier proyecto de JavaScript (popular) y, en mi opinión, tiene muchos beneficios, tales como:
Como tenemos la posibilidad de definir un conjunto de reglas de estilo, esto aumenta la legibilidad de nuestro código hacia el esfuerzo de hacer que nuestra base de código parezca escrita por " una persona ". Esto es importante, ya que puede suceder que los ingenieros de software pasen de un código base a otro dentro de los proyectos, lo que significa que muchas personas se involucran. Un conjunto común de reglas facilita la comprensión real de lo que está haciendo el código.
Las reglas adicionales de linting ayudan a mejorar las revisiones de código, ya que linting ya actúa como una revisión previa al código, verificando todos los problemas básicos, como errores de sintaxis, nombres incorrectos, el debate entre tabulación y espacios, etc. Aumenta el valor de tener código revisiones, ya que las personas están más dispuestas a verificar la implementación en lugar de quejarse de los errores de sintaxis.
ESLint es una utilidad de linting JavaScript de código abierto creada originalmente por Nicholas C. Zakas. El linting de código es un tipo de análisis estático que se usa con frecuencia para encontrar patrones problemáticos o código que no se adhiere a ciertas pautas de estilo. Hay linters de código para la mayoría de los lenguajes de programación, y los compiladores a veces pueden incorporar linting en el proceso de compilación.
ESLint es una herramienta CLI que se envuelve alrededor de otros dos proyectos de código abierto. Uno es Espree , que crea un árbol de sintaxis abstracta (AST) a partir del código JavaScript. Basado en esto, AST ESLint usa otro proyecto llamado Estraverse que proporciona funciones transversales para un AST. Durante el recorrido, ESLint emite un evento para cada nodo visitado donde el tipo de nodo es el nombre del evento, por ejemplo, FunctionExpression o WithStatement . Las reglas de ESLint son, por lo tanto, solo funciones que se suscriben a los tipos de nodos que desea verificar.
También es importante tener en cuenta que ESLint no admite nuevas funciones de lenguaje hasta que lleguen a la Etapa 4 del proceso de propuesta de TC39 .
Una vista de pájaro básica de cómo funciona ESLint
Para una explicación más detallada, usaré el siguiente script simple que genera un AST para el código JavaScript dado.
Creación sencilla de AST
El AST es una representación abstracta de la estructura de su código. En el mundo de JavaScript, esta representación abstracta está definida por el proyecto ESTree y es el punto de partida si desea comprender los AST de JavaScript o desea construir/ampliar por su cuenta. Recomiendo leer la documentación de gramática de ES5 AST , ya que ayuda a comprender los diferentes tipos de nodos representados en el AST.
Un punto específico de diferencia con el AST es que cada nodo describe una definición de gramática específica en su código, como puede ver a continuación: nuestra línea de código JavaScript ya produce un AST con 5 nodos, y cada nodo en sí contiene información adicional que usted puede ver en la representación JSON a continuación. Esta representación gráfica es solo un ejemplo de cómo se vería una representación de árbol de nuestro código (también interpretaría los valores en ArrayExpression como nodos individuales, pero los desarrolladores son libres de elegirlos).
Visualizando nuestro AST (con http://resources.jointjs.com/demos/javascript-ast )
Como puede ver, el AST de una sola línea de código y una representación de árbol simple contiene mucha información.
Como se mencionó anteriormente, una línea de código JavaScript contiene una gran cantidad de información para un AST. Cada entrada en el AST es un objeto de nodo , que consta de una propiedad de 'tipo' y un objeto SourceLocation .
La propiedad de tipo es una cadena que representa las diferentes variantes de Nodo en el AST. El objeto SourceLocation consiste en una propiedad inicial y final. El tipo, el número de línea inicial y final nos brindan información sobre la estructura de nuestro código. En general, un AST de JavaScript consiste en declaraciones , expresiones y declaraciones (para ES5), que no parece mucho, pero tiene muchas variaciones. Para aquellos interesados en ES2016 y más allá, consulte lo siguiente:
Ahora que hemos generado nuestro AST para nuestro código JavaScript, ¿qué podemos hacer a continuación? ¡atravesando! Tan grande como es el AST, la parte emocionante comienza atravesándolo y analizando la información que tiene. Para atravesar el AST, ESLint se basa en el proyecto Estraverse que atraviesa el AST generado (de Espree).
Estraverse proporciona una funcionalidad transversal que ejecuta una declaración determinada. En esta función transversal podemos suscribirnos a tipos específicos de nodos y completar nuestro análisis. Por ejemplo, si queremos asegurarnos de que todas las definiciones literales en nuestra declaración de matriz sean enteros, podemos verificar eso con el siguiente script de muestra:
Ejemplo de script para atravesar
Además, la funcionalidad transversal de Estraverse utiliza el patrón de diseño Visitor , que nos permite ejecutar funciones para cada nodo visitado del AST en lugar de atravesar todo el AST y realizar operaciones después. Al depurar la función transversal de Estraverse, se ha demostrado que está utilizando el algoritmo de profundidad primero para atravesar un árbol. Esto significa que Estraverse está atravesando hasta el final de un nodo secundario (primero en profundidad) antes de comenzar a retroceder. El patrón Visitor, combinado con una búsqueda en profundidad, permite que ESLint active Eventos cada vez que ingresa a un nodo AST o lo abandona inmediatamente.
La arquitectura de ESLint es conectable, por lo que si desea crear nuevas reglas para problemas, marcos o casos de uso específicos que tenga, se recomienda desarrollar complementos de ESLint en lugar de abrir un problema y solicitar cambios. Esto presenta una oportunidad bastante poderosa para crear un análisis de código mucho más complejo que el que puede proporcionar ESLint. Por lo tanto, los desarrolladores deberían considerar la creación de complementos, ya que son módulos npm.
Gracias a la arquitectura conectable, es fácil usar complementos o reglas ya existentes para diferentes marcos, bibliotecas o empresas, por ejemplo, eslint-plugin-react , eslint-plugin-vue o eslint-contrib-airbnb .
Si bien es posible que todos usemos ESLint y las herramientas de linting en nuestros proyectos de JavaScript, no sabemos mucho acerca de los conocimientos de estos proyectos y los desafíos detrás de ellos, o cómo nos brindan las herramientas para crear código de buena calidad. Recomiendo encarecidamente a todos los desarrolladores de JavaScript que jueguen con estas herramientas, ya que este es un tema en el que solo unos pocos realmente trabajan, pero en realidad se usan en todas partes. Algunos proyectos que realizan un trabajo similar son: https://github.com/jlongster/prettier , https://github.com/babel/babel-eslint , https://github.com/facebook/flow/tree/master/ src/parser ).
Como próximo paso, me gustaría crear un pequeño tutorial del complemento ESLint para que los desarrolladores interesados vean cómo pueden crear su propio conjunto de reglas personalizado para diferentes casos de uso, por ejemplo, colocar reglas en el núcleo de ESLint. Si tiene alguna sugerencia o idea para un complemento de ESLint que le gustaría ver, contácteme en Twitter en @Fokusman .