Reglas avanzadas de linting con ESLint

Rate this content
Bookmark

Esta charla explorará formas más avanzadas de escribir reglas de análisis estático en ESLint utilizando las APIs de flujo de control de ESLint. Explicaré rápidamente qué es un grafo de flujo de control y cómo puedes usarlo para encontrar problemas en tu código. Te mostraré cómo detectar cuándo se asigna un valor a una variable de manera inútil y otros problemas lógicos que puedes detectar utilizando esta técnica.

This talk has been presented at TypeScript Congress 2023, check out the latest edition of this JavaScript Conference.

FAQ

Tibor Blanesy trabaja en el análisis estático de JavaScript en Sonar, especializándose en técnicas avanzadas para el linting con ESLint.

SonarQube identifica problemas como el almacenamiento muerto, que ocurre cuando a una variable local se le asigna un valor que no es leído por ninguna instrucción posterior, indicando posibles errores o desperdicio de recursos.

Un ControlFlowGraph es una representación del código que contiene bloques básicos de declaraciones ejecutadas secuencialmente y saltos representados como flechas entre bloques, utilizado para analizar y detectar errores en el código.

ESLint utiliza eventos y objetos como CodePath y ControlPathSegment para monitorizar el flujo de control y detectar problemas en el código, como variables que se asignan pero nunca se utilizan.

El análisis de vivacidad indica qué variables están 'vivas' o necesarias en cualquier punto del programa, ayudando a identificar y optimizar variables innecesarias o redundantes.

La implementación completa del algoritmo de análisis estático se encuentra en el analizador de JavaScript de Sonar, disponible como un proyecto de código abierto en GitHub bajo la regla 18.54.

Tibor Blenessy
Tibor Blenessy
10 min
21 Sep, 2023

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Tibor Blanesy de Sonar presenta técnicas avanzadas para el linting con ESLint, incluyendo el uso de ControlFlowGraph para detectar errores en el código. El algoritmo se basa en el análisis de vivacidad, que identifica las variables vivas en cualquier punto del programa. Además, la charla cubre el cálculo de conjuntos de bloques utilizando la diferencia entre el conjunto de salida y el conjunto de eliminación unido con genset.

1. Técnicas Avanzadas para Linting con ESLint

Short description:

¡Hola! Mi nombre es Tibor Blanesy, trabajo en el análisis estático de JavaScript en Sonar, y en esta charla me gustaría mostrarte algunas técnicas más avanzadas para el linting con ESLint. Echemos un vistazo a una función que devuelve un rango de números entre dos valores pasados como argumento. Si no se proporciona el argumento, asumirá que el rango debe comenzar desde cero. Utilizaremos una representación del código llamada ControlFlowGraph para detectar errores en el código. La base del algoritmo es el análisis de vivacidad, que nos dice qué variables están vivas en cualquier punto del programa.

Mi nombre es Tibor Blanesy, trabajo en el análisis estático de JavaScript en Sonar, y en esta charla me gustaría mostrarte algunas técnicas más avanzadas para el linting con ESLint. Echemos un vistazo a la siguiente función, que encontré en el código base de VS Code. Esta función devuelve un rango de números entre dos valores pasados como argumento.

Si no se proporciona el argumento, asumirá que el rango debe comenzar desde cero. Cuando utilizamos herramientas de análisis estático, como SonarQube, nos mostrará rápidamente que hay un problema con este código. Por alguna razón, el valor asignado a la variable 'from' nunca se utiliza más adelante en el código. La lógica que maneja los argumentos está duplicada.

Este tipo de errores, cuando el valor asignado a la variable no se utiliza, se llama un almacenamiento muerto. SonarQube proporciona la siguiente explicación de por qué esto es un problema. Un almacenamiento muerto ocurre cuando una variable local se le asigna un valor que no es leído por ninguna instrucción posterior. Calcular o recuperar un valor solo para luego sobrescribirlo o desecharlo podría indicar un error grave en el código. Incluso si no es un problema, es como mínimo un desperdicio de recursos. Por lo tanto, se deben utilizar valores sobrecalculados. En los próximos minutos intentaré explicar cómo se pueden detectar este tipo de errores con el análisis estático.

Primero, utilizaremos una representación del código llamada ControlFlowGraph. En esta representación, un nodo llamado bloques básicos contiene solo declaraciones que se ejecutan secuencialmente. Los saltos se representan como flechas entre los bloques. Así que aquí tenemos un ControlFlowGraph para la función que mostré anteriormente. Solo mostraremos una parte del grafo, que es relevante para el problema, para mantenerlo pequeño. En la siguiente diapositiva, tengo el mismo ControlFlowGraph anotado en rojo, con eventos que son proporcionados por ESLint cuando escribimos una regla personalizada. La API de ESLint proporciona dos objetos, CodePath, que representa el flujo de control de toda la función, y ControlPathSegment para cada bloque básico. Luego, ESLint dispara eventos para el inicio y fin de CodePath, y para el inicio y fin de cada bloque básico, que es un CodePathSegment.

Entonces, en el código, lo que escribiremos es el siguiente objeto, que contiene un controlador de eventos para los eventos de CodePath. No tenemos tiempo para entrar en detalles de implementación, pero en las siguientes diapositivas, describiré rápidamente los conceptos básicos del algoritmo. La base del algoritmo es el análisis de vivacidad, que nos dice qué variables están vivas en cualquier punto del programa. La variable está viva cuando el valor que contiene podría ser necesario en el futuro. Para cada bloque básico, calcularemos cuatro conjuntos de variables. El conjunto de inicio con las variables que se leen en el bloque básico, el conjunto de eliminación, que contiene las variables que se escriben en el bloque básico, el conjunto de entrada con las variables que están vivas al comienzo del bloque, y el conjunto de salida con las variables que están vivas al final del bloque. Para calcular estos conjuntos, utilizaremos las siguientes dos reglas. El conjunto de salida del bloque actual es la unión de todos los conjuntos de entrada de sus sucesores.

2. Cálculo de Conjuntos de Bloques

Short description:

El conjunto de entrada del bloque actual es la diferencia entre el conjunto de salida y el conjunto de eliminación, unido con genset. Calcularemos los valores de estos conjuntos comenzando desde el fondo del grafo y moviéndonos hacia los predecesores de cada bloque.

El conjunto de entrada del bloque actual es la diferencia entre el conjunto de salida y el conjunto de eliminación, unido con genset. Ahora pasaré por los bloques básicos de la función que mostré anteriormente, y calcularemos los valores de estos conjuntos. Así que comenzaremos desde el fondo del grafo para calcular los conjuntos de este bloque básico. Así que asumiremos que 'from' y 'to' se leen más adelante en la función, por lo que genset se establece en 'from' y 'to', y ignoraremos que hay algo escrito, por lo que el conjunto de eliminación estará vacío. A partir de esto, podemos calcular el conjunto de entrada como 'from' y 'to', y ahora nos moveremos a los predecesores de este bloque. Como el conjunto de entrada del bloque sucesor es 'from' y 'to', podemos decir que el conjunto de salida también es 'from' y 'to', siguiendo la primera regla. En este bloque básico, estamos leyendo el valor de 'arc', por lo que genset es 'arc' y estamos escribiendo los valores de 'from' y 'to', por lo que el conjunto de eliminación es 'from' y 'to'. A partir de esto, podemos calcular el conjunto de entrada como la diferencia entre el conjunto de salida y el conjunto de eliminación. Como estos conjuntos son iguales, la diferencia será vacía. El conjunto de entrada es la unión de vacío con genset, que contiene 'arc'. Por lo tanto, el conjunto de entrada será 'arc'. Ahora nos movemos a otro bloque donde nuevamente el conjunto de salida se establece como el conjunto de entrada del bloque sucesor, por lo que es 'from' y 'to'. Estamos leyendo el valor de 'arc', por lo que genset es 'arc' y estamos escribiendo el valor de 'from'. A partir de esto, podemos calcular que el conjunto de entrada es 'arc' y 'to'. Cuando nos movemos al predecesor de estos dos bloques, podemos establecer el conjunto de salida como la unión del conjunto de entrada de los bloques sucesores, por lo que es 'arc' y 'to'. Estamos leyendo el valor de 'to', por lo que genset es 'to' y no estamos escribiendo ninguna variable, por lo que el conjunto de eliminación está vacío. A partir de esto, podemos calcular el conjunto de entrada como la diferencia entre el conjunto de salida y el conjunto de eliminación, que es 'arc' y 'to', y unirlo con 'to', lo cual no cambia nada. A partir de aquí, nos movemos al predecesor de este bloque, por lo que sabemos que el conjunto de salida es 'arc' y 'to', estamos leyendo el valor de 'arc', por lo que genset es 'arc', estamos escribiendo el valor de 'from', por lo que el conjunto de eliminación contiene 'from', y a partir de esto podemos calcular el conjunto de entrada como 'arc' y 'to'. En el siguiente bloque, la situación es casi idéntica, el conjunto de salida es 'arc' y 'to', estamos escribiendo el valor de 'from', por lo que el conjunto de eliminación es 'from', no estamos leyendo ninguna variable, por lo que genset está vacío. A partir de esto, calculamos el conjunto de entrada como 'arc' y 'to'. Y ahora nos movemos al primer bloque donde el conjunto de salida es 'arc' y 'to', estamos leyendo el valor de 'to', por lo que genset es 'to', no estamos escribiendo ninguna variable, por lo que el conjunto de eliminación está vacío, por lo tanto, podemos calcular el conjunto de entrada como 'arc' y 'to'. Así que ahora hemos calculado los valores de estos bloques básicos. Cada vez que calculamos el conjunto de entrada del bloque, necesitamos recalcular los predecesores de los bloques. Esto es especialmente importante si hay bucles en el grafo, porque necesitaremos continuar hasta que los conjuntos no cambien más. Una vez que esto esté terminado, podemos analizar los valores calculados y detectar los problemas. Generaremos un problema para cada variable que forma parte del conjunto de eliminación, lo que significa que se está escribiendo, pero no forma parte del conjunto de salida del bloque, lo que significa que el valor nunca se necesita en los bloques posteriores. Por lo tanto, en este caso, en nuestra función, 'from()' se escribe al principio, pero no se lee en ningún bloque posterior porque se vuelve a escribir. Por eso generaremos un problema en esta llamada a 'from()'. Si quieres, puedes echar un vistazo a la implementación completa de este algoritmo en nuestro analizador de JavaScript, que es un proyecto de código abierto en GitHub, y el algoritmo se encuentra en la regla 18.54. Este analizador se utiliza en SonarQube, SonarCloud o SonarLink. Espero que hayas encontrado interesante esta charla, y gracias por tu atención. ¡Adiós!

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Depuración Web Moderna
JSNation 2023JSNation 2023
29 min
Depuración Web Moderna
Top Content
This Talk discusses modern web debugging and the latest updates in Chrome DevTools. It highlights new features that help pinpoint issues quicker, improved file visibility and source mapping, and ignoring and configuring files. The Breakpoints panel in DevTools has been redesigned for easier access and management. The Talk also covers the challenges of debugging with source maps and the efforts to standardize the source map format. Lastly, it provides tips for improving productivity with DevTools and emphasizes the importance of reporting bugs and using source maps for debugging production code.
El Futuro de las Herramientas de Rendimiento
JSNation 2022JSNation 2022
21 min
El Futuro de las Herramientas de Rendimiento
Top Content
Today's Talk discusses the future of performance tooling, focusing on user-centric, actionable, and contextual approaches. The introduction highlights Adi Osmani's expertise in performance tools and his passion for DevTools features. The Talk explores the integration of user flows into DevTools and Lighthouse, enabling performance measurement and optimization. It also showcases the import/export feature for user flows and the collaboration potential with Lighthouse. The Talk further delves into the use of flows with other tools like web page test and Cypress, offering cross-browser testing capabilities. The actionable aspect emphasizes the importance of metrics like Interaction to Next Paint and Total Blocking Time, as well as the improvements in Lighthouse and performance debugging tools. Lastly, the Talk emphasizes the iterative nature of performance improvement and the user-centric, actionable, and contextual future of performance tooling.
pnpm: un gestor de paquetes rápido y eficiente para JavaScript
DevOps.js Conf 2022DevOps.js Conf 2022
31 min
pnpm: un gestor de paquetes rápido y eficiente para JavaScript
pnpm is a fast and efficient package manager that gained popularity in 2021 and is used by big tech companies like Microsoft and TikTok. It has a unique isolated node module structure that prevents package conflicts and ensures each project only has access to its own dependencies. pnpm also offers superior monorepo support with its node module structure. It solves the disk space usage issue by using a content addressable storage, reducing disk space consumption. pnpm is incredibly fast due to its installation process and deterministic node module structure. It also allows file linking using hardlinks instead of symlinks.
Repensando las Estrategias de Agrupación
React Day Berlin 2023React Day Berlin 2023
32 min
Repensando las Estrategias de Agrupación
The talk discusses rethinking bundling strategies, focusing on challenges such as long-term caching and improving the state of Next.js and Webpack. It explores handling immutable caching and content hashes, optimizing asset references and page manifests, and addressing issues with client-side navigation and long-term caching. The talk also covers tree shaking and optimization, optimizing module fragments and code placement, and the usage and relationship of TurboPack with Webpack. Additionally, it touches on customizing configuration and hash risks, barrel imports and code splitting, and entry points and chunking heuristics.
Patrones avanzados para la gestión de API en aplicaciones React a gran escala
React Advanced 2021React Advanced 2021
20 min
Patrones avanzados para la gestión de API en aplicaciones React a gran escala
Top Content
This Talk covers advanced patterns for API management in large-scale React applications. It introduces the concept of an API layer to manage API requests in a more organized and maintainable way. The benefits of using an API layer include improved maintainability, scalability, flexibility, and code reusability. The Talk also explores how to handle API states and statuses in React, and provides examples of canceling requests with Axios and React Query. Additionally, it explains how to use the API layer with React Query for simplified API management.
Más allá de las listas virtuales: Cómo renderizar 100K elementos con 100s de actualizaciones/seg en React
React Advanced 2021React Advanced 2021
27 min
Más allá de las listas virtuales: Cómo renderizar 100K elementos con 100s de actualizaciones/seg en React
Top Content
The Talk discusses optimizing rendering of big tables using Flipper, a new version that is ten times faster with improved user interaction and richer data. It explores optimizing rendering with React, virtualization, filtering, sorting, and windowing techniques. The introduction of the Flipper Datasource packet simplifies handling updates, inserts, and removals. The performance of the Flipper data source package is excellent, even in a debug build of React, with minimal CPU usage. The Q&A session covers incremental sorting, dynamic row height, and the potential for two-dimensional virtualization in the future.

Workshops on related topic

Masterclass de Depuración de Rendimiento de React
React Summit 2023React Summit 2023
170 min
Masterclass de Depuración de Rendimiento de React
Top Content
Featured WorkshopFree
Ivan Akulov
Ivan Akulov
Los primeros intentos de Ivan en la depuración de rendimiento fueron caóticos. Vería una interacción lenta, intentaría una optimización aleatoria, vería que no ayudaba, y seguiría intentando otras optimizaciones hasta que encontraba la correcta (o se rendía).
En aquel entonces, Ivan no sabía cómo usar bien las herramientas de rendimiento. Haría una grabación en Chrome DevTools o React Profiler, la examinaría, intentaría hacer clic en cosas aleatorias, y luego la cerraría frustrado unos minutos después. Ahora, Ivan sabe exactamente dónde y qué buscar. Y en esta masterclass, Ivan te enseñará eso también.
Así es como va a funcionar. Tomaremos una aplicación lenta → la depuraremos (usando herramientas como Chrome DevTools, React Profiler, y why-did-you-render) → identificaremos el cuello de botella → y luego repetiremos, varias veces más. No hablaremos de las soluciones (en el 90% de los casos, es simplemente el viejo y regular useMemo() o memo()). Pero hablaremos de todo lo que viene antes - y aprenderemos a analizar cualquier problema de rendimiento de React, paso a paso.
(Nota: Esta masterclass es más adecuada para ingenieros que ya están familiarizados con cómo funcionan useMemo() y memo() - pero quieren mejorar en el uso de las herramientas de rendimiento alrededor de React. Además, estaremos cubriendo el rendimiento de la interacción, no la velocidad de carga, por lo que no escucharás una palabra sobre Lighthouse 🤐)
React, TypeScript y TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript y TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS es extremadamente popular y, por lo tanto, ampliamente soportado. TypeScript está ganando popularidad y, por lo tanto, cada vez más soportado.

¿Los dos juntos? No tanto. Dado que ambos cambian rápidamente, es difícil encontrar materiales de aprendizaje precisos.

¿React+TypeScript, con los IDEs de JetBrains? Esa combinación de tres partes es el tema de esta serie. Mostraremos un poco sobre mucho. Es decir, los pasos clave para ser productivo, en el IDE, para proyectos de React utilizando TypeScript. En el camino, mostraremos el desarrollo guiado por pruebas y enfatizaremos consejos y trucos en el IDE.
Dominando conceptos avanzados en TypeScript
React Summit US 2023React Summit US 2023
132 min
Dominando conceptos avanzados en TypeScript
Top Content
Featured WorkshopFree
Jiri Lojda
Jiri Lojda
TypeScript no es solo tipos e interfaces. Únete a esta masterclass para dominar características más avanzadas de TypeScript que harán tu código a prueba de balas. Cubriremos tipos condicionales y notación de inferencia, cadenas de plantillas y cómo mapear sobre tipos de unión y propiedades de objetos/arrays. Cada tema se demostrará en una aplicación de muestra que se escribió con tipos básicos o sin tipos en absoluto y juntos mejoraremos el código para que te familiarices más con cada característica y puedas llevar este nuevo conocimiento directamente a tus proyectos.
Aprenderás:- - ¿Qué son los tipos condicionales y la notación de inferencia?- ¿Qué son las cadenas de plantillas?- Cómo mapear sobre tipos de unión y propiedades de objetos/arrays.
Masterclass: Integrando LangChain con JavaScript para Desarrolladores Web
React Summit 2024React Summit 2024
92 min
Masterclass: Integrando LangChain con JavaScript para Desarrolladores Web
Featured Workshop
Vivek Nayyar
Vivek Nayyar
Sumérgete en el mundo de la IA con nuestro masterclass interactivo diseñado específicamente para desarrolladores web. "Masterclass: Integrando LangChain con JavaScript para Desarrolladores Web" ofrece una oportunidad única para cerrar la brecha entre la IA y el desarrollo web. A pesar de la prominencia de Python en el desarrollo de IA, el vasto potencial de JavaScript sigue siendo en gran medida inexplorado. Este masterclass tiene como objetivo cambiar eso.A lo largo de esta sesión práctica, los participantes aprenderán cómo aprovechar LangChain, una herramienta diseñada para hacer que los modelos de lenguaje grandes sean más accesibles y útiles, para construir agentes de IA dinámicos directamente dentro de entornos JavaScript. Este enfoque abre nuevas posibilidades para mejorar las aplicaciones web con funciones inteligentes, desde el soporte al cliente automatizado hasta la generación de contenido y más.Comenzaremos con los conceptos básicos de LangChain y los modelos de IA, asegurando una base sólida incluso para aquellos nuevos en IA. A partir de ahí, nos sumergiremos en ejercicios prácticos que demuestran cómo integrar estas tecnologías en proyectos reales de JavaScript. Los participantes trabajarán en ejemplos, enfrentando y superando los desafíos de hacer que la IA funcione sin problemas en la web.Este masterclass es más que una experiencia de aprendizaje; es una oportunidad de estar a la vanguardia de un campo emergente. Al final, los asistentes no solo habrán adquirido habilidades valiosas, sino que también habrán creado funciones mejoradas con IA que podrán llevar a sus proyectos o lugares de trabajo.Ya seas un desarrollador web experimentado curioso acerca de la IA o estés buscando expandir tus habilidades en áreas nuevas y emocionantes, "Masterclass: Integrando LangChain con JavaScript para Desarrolladores Web" es tu puerta de entrada al futuro del desarrollo web. Únete a nosotros para desbloquear el potencial de la IA en tus proyectos web, haciéndolos más inteligentes, interactivos y atractivos para los usuarios.
De Todo App a B2B SaaS con Next.js y Clerk
React Summit US 2023React Summit US 2023
153 min
De Todo App a B2B SaaS con Next.js y Clerk
WorkshopFree
Dev Agrawal
Dev Agrawal
Si eres como yo, probablemente tengas un millón de ideas para proyectos secundarios, algunas de las cuales incluso podrían hacerte ganar dinero como un micro SaaS, o podrían resultar ser la próxima startup de mil millones de dólares. Pero, ¿cómo sabes cuáles? ¿Cómo pasas de una idea a un producto funcional que puede ser puesto en manos de clientes que pagan sin renunciar a tu trabajo e invirtiendo todo tu tiempo y dinero en ello? ¿Cómo pueden competir tus proyectos secundarios en solitario con las aplicaciones construidas por enormes equipos y grandes empresas?
Construir productos SaaS ricos viene con desafíos técnicos como infraestructura, escalabilidad, disponibilidad, seguridad y subsistemas complicados como autenticación y pagos. Por eso, a menudo son los gigantes tecnológicos ya establecidos quienes pueden construir y operar productos de este tipo de manera razonable. Sin embargo, una nueva generación de devtools está permitiendo a los desarrolladores construir fácilmente soluciones completas que aprovechan la mejor infraestructura en la nube disponible, y ofrecen una experiencia que te permite iterar rápidamente en tus ideas por un bajo costo de $0. Se llevan todos los desafíos técnicos de construir y operar productos de software para que solo tengas que pasar tu tiempo construyendo las características que tus usuarios quieren, dándote una oportunidad razonable de competir contra el mercado al mantenerte increíblemente ágil y receptivo a las necesidades de los usuarios.
En esta masterclass de 3 horas comenzarás con una simple aplicación de gestión de tareas construida con React y Next.js y la convertirás en un producto SaaS completamente funcional y escalable integrando una base de datos escalable (PlanetScale), autenticación multi-tenant (Clerk), y pagos basados en suscripción (Stripe). También aprenderás cómo los principios del desarrollo de software ágil y el diseño impulsado por el dominio pueden ayudarte a construir productos rápidamente y de manera rentable, y competir con las soluciones existentes.
Construyendo Pinia desde cero
Vue.js Live 2024Vue.js Live 2024
70 min
Construyendo Pinia desde cero
Workshop
Eduardo San Martin Morote
Eduardo San Martin Morote
Sumergámonos en cómo funciona Pinia bajo el capó construyendo nuestro propio `defineStore()`. Durante este masterclass cubriremos algunos conceptos avanzados de Vue como la inyección de dependencias y los scopes de efectos. Esto te dará una mejor comprensión de la API de Composición de Vue.js y Pinia. Requisitos: experiencia en la construcción de aplicaciones con Vue y su API de Composición.