Refactorización de código potenciada mediante Árboles de Sintaxis Abstracta

Rate this content
Bookmark

Cuando se refactorizan bases de código grandes, Encontrar y Reemplazar, incluso con expresiones regulares, solo puede llevarte hasta cierto punto. Cuando eso falla, no recurras a actualizaciones manuales dolorosas, en su lugar, utiliza Árboles de Sintaxis Abstracta (AST).

En esta sesión presentamos los AST y mostramos cómo se pueden utilizar para razonar / generar código. Saldrás con una mayor comprensión de cómo puedes actualizar automáticamente el código y nuevos conocimientos sobre cómo funcionan los linters de código en el fondo.

Stephen Cooper
Stephen Cooper
29 min
02 Jun, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Esta charla explora el poder de los Árboles de Sintaxis Abstracta (AST) en el desarrollo de software. Cubre el uso de AST en el mantenimiento de ejemplos de React, la automatización de la identificación de dependencias y la introducción de tipos genéricos. La charla también discute el uso de AST para razonar y generar código, así como su aplicación en la construcción de complementos de ESLint y modificaciones de código. Además, destaca recursos para explorar AST, probar scripts de AST y construir complementos de Babel.

Available in English

1. Introducción a los AST

Short description:

Voy a hablarles sobre los AST y el poder que brindan. Comencemos.

Debería tener una introducción así todo el tiempo. Eso sería realmente bueno. Entonces, sí, como han escuchado, voy a hablarles sobre los AST, porque este es un tema que, antes de unirme a AG Grid, siempre me daba un poco de miedo, siempre un poco como, oh, no sé si sé cómo usarlos. Pero una vez que me adentré en ello, metí las manos en el asunto, me ensucié las manos, me di cuenta de que hay mucho poder al usarlos. Y eso es lo que quiero transmitirles hoy y tal vez ayudarles a comenzar su viaje con los AST. Así que comencemos.

2. Misión y tareas clave de AG Grid

Short description:

La misión para nosotros en AG Grid es construir la mejor cuadrícula de datos en JavaScript. Tenemos dos tareas clave: mantener ejemplos de React e introducir tipado genérico. Queremos proporcionar código que se ajuste a sus necesidades y garantizar una integración perfecta con TypeScript.

Entonces, la misión para nosotros en AG Grid es construir la mejor cuadrícula de datos en JavaScript. Y hay varias tareas que debemos realizar para lograrlo. Cuando me uní a la empresa hace dos años, había estas dos tareas clave que debían realizarse.

Necesitábamos mantener miles de ejemplos de React para que cuando consulte nuestra documentación, pueda ver, Quiero esta función, la quiero en React. Todavía estoy usando clases porque mi empresa aún no ha actualizado. O estoy usando hooks o estoy usando hooks con TypeScript. Queremos brindarle el código exactamente de la manera que desea consumirlo.

Y luego, el segundo es que nos encanta TypeScript. Queremos introducir el tipado genérico en todo nuestro producto. Entonces, si nos proporciona una interfaz para los datos de su fila, queremos que eso se refleje en todas nuestras interfaces para que obtenga una autocompletación y verificación de tipos excelentes. Entonces, la pregunta es, ¿cómo voy a hacer esto? Esto es lo que vemos.

3. Introducción a los AST y ejemplos de React

Short description:

En nuestra documentación, encontrarás numerosos ejemplos y diferentes formas de importar AgGrid. Estamos agregando tipado genérico en las interfaces, evitando el enfoque lento y propenso a errores de fuerza bruta. Los AST proporcionan una herramienta poderosa para completar tareas de manera eficiente. Comencemos por mantener miles de ejemplos de React y comprender los árboles de sintaxis abstracta.

Entonces, en nuestra documentación, verás muchos de estos ejemplos. Como dije, tenemos tres versiones para clases, hooks, hooks con TypeScript. Y luego hay dos formas diferentes de importar AgGrid en 500 ejemplos de características diferentes. Y puedes ver que tenemos hasta 3000 demos. Así que espero que pienses, No voy a hacer eso manualmente. Porque si lo haces manualmente, tendrás que contratar a mucha gente, cometerás errores, tu documentación tendrá errores y nadie ganará. Así que no hay un enfoque de fuerza bruta real para eso.

Y luego, si miramos la segunda tarea, que intentaremos resolver, es agregar este tipado genérico en cientos de interfaces. Entonces puedes pasar esta interfaz a nuestro componente React de AgGrid, y luego necesitamos que se propague a todas partes donde puedas tener un callback o manejadores. Para esto, podrías usar el enfoque de fuerza bruta. Podrías encontrar dónde usas los datos de la fila, ir allí, cambiar el tipo, reconstruir. Sabes, ese tipo es entonces, necesitas bajar un poco más en la jerarquía, encontrar esas interfaces, agregarlas, y ves que es solo este ciclo que es un poco lento y tedioso y propenso a errores también. Así que realmente no queremos hacer eso. Podrías hacerlo, pero probablemente no quieras hacerlo.

Entonces aquí llegamos a esta cita, que es o tal vez no de Abraham Lincoln. Dame seis horas para cortar un árbol y pasaré las primeras cuatro horas afilando el hacha. La idea aquí es, en lugar de simplemente lanzarnos directamente a una tarea, nos aseguraremos de estar usando la herramienta adecuada. Y si tenemos un hacha a mano, nos aseguraremos de saber cómo usarla y que esté afilada y lista para usar. Y así, los AST, esa será nuestra hacha y así completaremos estas tareas. Entonces, abordemos nuestra primera tarea. Queremos mantener miles de ejemplos de React, pero el punto de partida es que tenemos todos estos como ejemplos de Vanilla TypeScript. Ese es nuestro punto de partida y necesitamos llegar a ejemplos de React a través del AST.

Entonces probablemente debería detenerme aquí y decir, bueno, ¿qué es un árbol de sintaxis abstracta? He estado diciendo estas cosas, estas grandes herramientas o grandes productos, pero ¿qué es? Entonces, una definición un poco más formal es que un árbol de sintaxis abstracta es una representación jerárquica de la estructura de un programa. Captura la sintaxis, la semántica en una estructura similar a un árbol. O puedes pensarlo, toma tu archivo de texto de tu código y lo convierte en un árbol con el que puedes escribir código. Entonces tendrás nodos y todo se va recorriendo de manera recursiva. Así que hay mucha recursión en los AST, pero todos hemos pasado nuestras preguntas de entrevista sobre el recorrido de árboles. Así que todos deberían ser expertos en esto. Entonces, como un caso simple, esto es cómo se vería un árbol de sintaxis abstracta. Entonces tenemos esta suma de A y B.

4. Comprensión de los AST y estructuras de árbol

Short description:

Tenemos un nodo de declaración de variable con el nombre 'sum' y una expresión binaria dentro de él. La estructura del árbol permite expresiones anidadas.

Entonces tenemos esta suma de A y B. Es un nodo de declaración de variable que luego tiene un nombre, que es la suma. Y luego dentro de esa declaración de variable, pasa a través de una expresión binaria. Entonces puedes ver que tienes el operador y tienes los identificadores derecho e izquierdo ordenados de manera agradable en mi diagrama, solo para mantenerte alerta. Pero esta es la idea. Entonces tomas tu código y forma este árbol. Y puedes ver cómo este árbol puede seguir creciendo. Digamos que A no es un identificador, tal vez sea otra expresión, y luego eso iría más abajo en otro árbol.

5. Writing a Code Generator and Using ASTs

Short description:

El primer paso para escribir un generador de código es categorizar el código fuente. Para AgGrid, tenemos configuraciones estáticas, devoluciones de llamada y funciones independientes. Los AST se utilizan para identificar estas secciones. TypeScript facilita la creación de AST y la extracción de información. Generamos el AST, lo recorremos y pasamos el modelo al generador de código de React. La devolución de llamada cambia de una variable a useState y de una función a useCallback.

Entonces, la primera parte de escribir un generador de código es categorizar el código fuente que vas a utilizar. Parte de las opciones de cuadrícula para AgGrid es que tendremos estas configuraciones estáticas. Por ejemplo, las definiciones de columna predeterminadas, las propias definiciones de columna y luego tenemos estas devoluciones de llamada.

Entonces, se convertirán en devoluciones de llamada de React. Y luego podrías tener estas funciones independientes, que son solo un artefacto del ejemplo para hacer que algo suceda al hacer clic en un botón. Entonces vamos a separar estas secciones, y vamos a usar AST para identificar estas secciones diferentes. Y esta es una excelente herramienta para familiarizarse con los AST. Y tendremos una demostración en vivo de esto en un momento. Pero puedes poner tu código allí, seleccionar qué analizador quieres. Me estoy enfocando en TypeScript, pero hay muchos analizadores diferentes que puedes usar, y todos tienen su propia versión del AST. Y con esto, puedes profundizar, ok, así es como se ve una función. Y a partir de esto, puedes aprender, ok, cuando busco esto, necesito que coincida con este tipo de estructura.

Entonces, en TypeScript, es bastante fácil crear uno de estos AST. Le das el texto fuente, usas el propio compilador de TypeScript, digamos, creas un archivo fuente, y eso te devuelve un AST. Y luego puedes escribir código para recorrer ese árbol y extraer toda la información que queremos. Entonces, esta es una de las coincidencias que hemos implementado. Básicamente, dice que cuando estoy recorriendo los nodos, ¿es esto una llamada a función? Y si encuentro algo que parece una llamada a función, entonces voy a extraer la información del nombre de esta función, cuáles son los parámetros y cuál es el cuerpo. Porque vamos a necesitar reorganizar estos y ponerlos en el formato de React. Y TypeScript nos proporciona algunas formas automáticas o incorporadas de llamar a funciones en un nodo para averiguar qué es. Podría verse algo como esto. Pero estos son detalles muy pequeños y serán diferentes dependiendo de lo que estés intentando escribir realmente. Pero el concepto es que puedes usar TypeScript para identificar estos nodos.

Entonces generaremos el AST, lo recorreremos, extraeremos todo el código en nuestro modelo, y luego pasaremos ese modelo a nuestro generador de código de React. Así es como podría verse esa devolución de llamada. Entonces, en lugar de una variable, ahora tenemos useState. En lugar de una simple función, tenemos useCallback. Ejecutamos nuestro ejemplo. Cuando haces clic en el botón, se supone que las alturas de las filas cambian, pero no está sucediendo nada. Ahora supongo que algunos de ustedes ya han notado qué estaba mal con eso. Si retrocedo.

6. Using AST to Automate Dependency Identification

Short description:

Sin dependencia. Nuestro generador de código no puede simplemente transformar la función. Necesitamos identificar las dependencias del código TypeScript. ¿Podemos usar el AST para automatizar esto? Sí, por supuesto.

¿Puedes ver qué está mal? Sin dependencia. Así que tenemos un cierre obsoleto. Aunque estamos actualizando el estado, nuestro efecto no se vuelve a ejecutar y no recoge ese cambio. Entonces, lo que esto significa es que nuestro generador de código no puede simplemente transformar la función. También tenemos que averiguar, bueno, para una devolución de llamada, cuáles son las dependencias que necesito poner en mi array. Así que cuando nos encontramos con este problema, la respuesta instintiva fue, oh no. Tendremos que hacer esto manualmente. Tendremos que pasar por estos ejemplos y actualizar las dependencias. Y sabes, piensas, oh no, no quiero hacer eso. Porque necesita las dependencias para funcionar, pero necesitamos identificarlas a partir del código typescript. Entonces la pregunta realmente es, ¿podemos usar el AST para automatizar esto? Y no me extenderé, sí. Por supuesto que podemos, de lo contrario no estaría aquí hablando. Seguiría actualizando los ejemplos de react. Así que veamos cómo podría ser esto. Y esto también es, supongo, el ejemplo de cómo puedes usar esta herramienta para resolver cómo necesitas escribir tu código y qué estás buscando.

7. Explorando la Identificación de Dependencias con AST

Short description:

Entonces podemos entrar aquí y si comenzamos a hacer clic en las cosas, se resaltarán a la derecha. Podemos echar un vistazo y decir, en realidad esto está en la declaración de retorno. Está definido aquí. Podemos ver desde nuestro cuerpo, nuestra función, que los parámetros realmente vienen de los parámetros. El único que necesito verificar es la altura de natación. Podemos actualizar nuestro generador y luego la altura de natación se recogerá automáticamente como una dependencia. Cualquier nuevo ejemplo de React que se escriba también pasará por el mismo proceso. Esta es una versión muy simple de la verificación exhaustiva de profundidad de los hooks de React.

Entonces podemos entrar aquí y si comenzamos a hacer clic en las cosas, se resaltarán a la derecha. Aquí he seleccionado la altura predeterminada. Así que esto es, supongo, una constante. Podemos echar un vistazo y decir, en realidad esto está en la declaración de retorno. Entonces, está bien, es un identificador, así que es algo que he usado, pero ¿dónde está definido? Bueno, está definido aquí. Y si vamos aquí, podemos decir, bueno, esto es una declaración de variable. Así que es como, bueno, en realidad esta variable ha sido definida dentro de mi función, así que no voy a necesitar agregar eso a mi array de dependencias.

Entonces, si buscamos algunas variables más aquí, bueno, podríamos ver deporte, y eso es un identificador. Pero eso no es algo que debería estar en el array de dependencias porque, bueno, en realidad es el objeto params, que podríamos necesitar verificar. Así que aquí podemos hacer clic en el params y ver dónde existe en el árbol. Esto es una expresión de acceso a propiedad. Y tienes que recorrer ese árbol para encontrar los params. Y una vez que hayas llegado al final donde ya no puedes recorrer más, entonces puedes averiguar, bueno, este identificador en sí es el que debo verificar. Pero nuevamente, podemos ver desde nuestro cuerpo, nuestra función, que los parámetros realmente vienen de los parámetros. Así que tenemos que construir esta especie de lógica de, bueno, en realidad, el único que necesito verificar es la altura de natación. Así que eso es algo que hay un identificador dentro del cuerpo de mi función. Oops. Eso tampoco ha sido definido como otra variable o viene de los parámetros. Así que volvemos.

Entonces podrías terminar con una lógica como esta diciendo, bueno, encuéntrame todas las propiedades de acceso. Busca todos esos identificadores. Y luego, ¿es una variable local? Variable. ¿Es uno de los argumentos que se ha pasado? Y luego también haz alguna especie de verificación global porque podríamos estar usando cosas del ámbito global que no queremos incluir en nuestras dependencias. Una vez que tengamos esta especie de lógica, podemos actualizar nuestro generador y luego la altura de natación se recogerá automáticamente como una dependencia incluida allí y luego nuestro ejemplo volverá a funcionar, lo cual es genial. Y eso también significa que esto está preparado para el futuro. Cualquier nuevo ejemplo de React que se escriba también pasará por el mismo proceso. Y podemos usar el AST allí simplemente para obtener esto automáticamente correcto. Así que no solo estás ahorrando tiempo ahora, también estás ahorrando tiempo futuro. Y lo que hemos hecho aquí es una versión muy simple de la verificación exhaustiva de profundidad de los hooks de React. El código para esto es mucho más complicado porque tienen que cubrir muchos casos de uso, pero es el mismo proceso.

8. Introducción a la escritura genérica con tsmorph

Short description:

La tarea implica introducir la escritura genérica en todo el código base, lo cual incluye actualizar interfaces y pasar genéricos al nodo de fila. Es una tarea desafiante con cientos de interfaces y tipos. Para simplificar el proceso, recomiendo usar tsmorph, un proyecto que envuelve el compilador de TypeScript y proporciona una abstracción de nivel superior. Con tsmorph, puedes extraer interfaces y razonar sobre ellas fácilmente. Al buscar la propiedad de datos y verificar su tipo, podemos avanzar aún más.

Si observas el código fuente de esto, verás que es un libro que habla sobre nodos y ¿dónde está este acceso? ¿Dónde se ha definido? Espero que te dé una idea de cómo funcionan estos linters de código y qué están haciendo.

Entonces pensamos, relájate, hemos completado esa tarea, tómate un descanso y luego pasa a nuestra segunda tarea, que es introducir la escritura genérica en todo el código base.

Entonces sí, esto es algo que, antes de trabajar en aggrid, esto es algo que quería. Había agregado mis propias interfaces y como tarea, entré y dije, ¿puedo hacer esto, puedo mejorarlo? Y así tenemos esto, tengo permiso pero ahora tengo que hacer el trabajo. Los cambios que esto implica son tomar, por ejemplo, el filtro de análisis de parámetros y ver que tenemos este data, como cualquier cosa, que queremos que sea genérico. Y también necesitamos pasar ese genérico a nuestro nodo de fila. Entonces, cada vez que alguien acceda a data del nodo de fila, tendrán la interfaz correcta allí. Hay muchas interfaces y hay muchas cadenas de interfaces que tendrían que actualizarse.

Entonces, ¿por qué es esto difícil? Bueno, hay alrededor de tres a cuatrocientas interfaces y tipos y hay esta interfaz. Sería posible hacerlo por fuerza bruta, pero podrías pasar por alto algunos o simplemente sería bastante tedioso. Y ahí es donde quería sugerirte un hacha aún más afilada.

Entonces hay este proyecto llamado tsmorph. Y lo que ha hecho es tomar el compilador de TypeScript y envolver esas funciones de coincidencia con una abstracción de nivel mucho más alto. Y esto va a hacerlo mucho más fácil escribir tu lógica de una manera en la que realmente no tienes que saber la diferencia entre los diferentes tipos de nodo o si es solo una expresión de variable o si es una interfaz. Así que hace mucho del trabajo por ti.

Con esto, importamos ts-morph y apuntamos a un archivo de configuración de ts-config y eso nos construirá un proyecto. Y luego, a partir de ese proyecto, puedes decirme, dame este archivo fuente. Así que aquí estoy diciendo, dame el archivo fuente de las opciones de la cuadrícula. Así que me lo da. Y luego puedo decir, bueno, en realidad, dame todas las declaraciones de importación porque quiero saber dónde están los archivos que contienen todas las interfaces utilizadas en nuestras opciones de cuadrícula. Y luego iteramos sobre todas esas importaciones, obtenemos los archivos fuente. Y luego, a partir de cada uno de esos archivos fuente, extraemos todas las interfaces. Así que puedes ver el código que estamos escribiendo aquí debido a tsmorph es bastante sencillo. No tenemos que meternos en los detalles, pero estamos extrayendo toda la información. Estamos recopilando todas estas interfaces para poder razonar sobre ellas. Y luego haremos algo así. Tenemos todas nuestras interfaces. Luego buscaremos la propiedad de datos en ellas. Usando esto como obtener propiedad. Y luego veremos el tipo, decimos, ¿es ese un tipo cualquiera? Y luego esta es la siguiente etapa, que probablemente debería haber resaltado un poco más en las diapositivas.

9. Usando AST para generar y razonar sobre código

Short description:

Podemos usar árboles de sintaxis abstracta para razonar y generar código. AST explorer.net es un excelente sitio para experimentar con código. Comprender los AST puede ayudar a contribuir a los linters de código. Encontrar documentación sobre los AST aún puede ser desafiante, pero hay recursos disponibles. Un buen artículo en dev.ca proporciona ejemplos de cómo escribir un complemento de Babel.

Lo que estamos haciendo ahora no es solo leer, vamos a comenzar a establecer, y vamos a comenzar a cambiar nuestro código a través de estas llamadas. Así que tenemos este tipo de configuración. Entonces lo vamos a establecer en TData. Y también vamos a agregar un parámetro de tipo a esa interfaz. Y le daremos el mismo nombre coincidente. Y vamos a registrar que hemos actualizado esta interfaz. Y una vez que hayamos actualizado todo ese nivel de interfaces, podemos recorrer y buscar esta cadena de jerarquía. Entonces, si encontramos una interfaz que extiende a otra, que hemos actualizado, entonces repetimos el proceso. Y agregamos los tipos genéricos nuevamente. Y lo agregamos a nuestra cola y repetimos el proceso para recorrer automáticamente estos árboles.

Eso parece la misma diapositiva. Sí. Y luego, al final, haces este project.savesync. Y eso hará, insertar todos esos cambios en tus archivos de código, generando, bueno, no generará la solicitud de extracción por ti, pero luego puedes ver, hemos realizado muchos cambios de código solo con nuestro generador único. Y lo bueno de esto es que luego puedes decir, bueno, en realidad no estaba del todo bien, lo voy a ajustar, descartar todos esos cambios, ejecutarlo nuevamente. Entonces, en lugar de ajustar individualmente todos estos archivos, tenemos una forma rápida de realizar un gran cambio de código de manera controlada y estructurada.

Mis conclusiones creo que he llegado justo a tiempo. Entonces puedes usar árboles de sintaxis abstracta tanto para razonar como para generar código. AST explorer.net es un excelente sitio para poner tu código y comenzar a experimentar y ver cómo podría verse. Y con suerte, esto me ayudará a comprender e incluso contribuir a los linters de código. Así que con eso, te dejo para afilar tus hachas de AST. Gracias. Creo que fue hace como cuatro años cuando tuve el plan de escribir un complemento de ES-lint y tuve que mirar un AST. Y lo que descubrí en ese momento es que se puede hacer pero es realmente desalentador porque es un archivo grande, incluso para un pequeño fragmento de código, como cinco líneas de código, es un AST muy largo. Y es realmente difícil, lo fue en ese momento, encontrar cualquier documentation sobre lo que significa cada cosa. ¿Todavía es así? Sí, diría que eso probablemente sigue siendo cierto. Gran motivación para las personas aquí, sí. Pero luego quiero decir, déjame seguir eso. Creo que también hay, probablemente hay mucho más contenido disponible donde las personas han escrito ejemplos sobre cómo escribí mi primer complemento de Babel. Así que hay un buen artículo en dev.ca que también puedo compartir.

10. Usando TS Morph y Generando ASTs

Short description:

Hay contenido disponible con ejemplos reducidos para poner algo en funcionamiento. AG significa Agnostic Grid y admite TypeScript, React, Angular, Vue y más. TS Morph se puede integrar en una herramienta de canalización como Codacy. Puedes generar ASTs a partir de JS básico, pero TypeScript conserva los tipos. AST es una tecnología general aplicable a varios tipos de código.

Donde alguien ha dicho, bueno, he escrito un complemento que extrae las declaraciones debug o convierte las aserciones en console.logs. Así que creo que ahora hay contenido donde las personas han dado, supongo, ejemplos reducidos de, esto es todo lo que necesitas hacer para poner algo en funcionamiento. Entonces la situación ha mejorado, pero todavía es un poco doloroso. Sí, todavía es un poco doloroso, sí.

Pregunta secundaria, ¿qué significa AG? AG significa Agnostic. Agnostic Grid. Agnostic Grid, sí, por lo que admitimos TypeScript, React, Angular, Vue, sólidamente. Sí, es agnóstico y puedes usarlo en cualquiera de esos frameworks. Entonces también podría ser AST grid. Sí.

Bien, primera pregunta del público de Anonymous. ¿Podemos integrar TS Morph en una herramienta de canalización como Codacy? ¿Crees que deberíamos hacerlo? No veo por qué no. Porque sí, TS Morph es solo un paquete npm. Y supongo que si tienes acceso a node en tu canalización de compilación, entonces puedes ejecutarlo y tener esos cambios. Supongo que querrías asegurarte de que no está cambiando demasiado el código antes de confirmarlo y tener controles en ese lugar, pero sí, no veo por qué no. De acuerdo, genial, gracias.

Una pregunta de Chris. ¿Puedes generar ASTs a partir de JS básico también en lugar de TypeScript como estás haciendo? Y si es así, ¿hay alguna limitación? La razón por la que uso TypeScript para esto es que quería conservar los tipos y llevar los tipos de un código TypeScript para poder escribir hooks de React con TypeScript. Y sí, hay analizadores de JavaScript. El hecho de que esto sea TypeScript no es una restricción. Solo tienes información de tipo adicional. Entonces el AST de JavaScript probablemente sea más simple también. Sí, creo que AST es una tecnología general. Corrígeme si me equivoco, pero incluso puedes obtener un AST para un archivo CSS, ¿verdad? Sí, sí, sí. No hay... Sí, es un concepto general. Entonces creo que Babel es otro que producirá su propio AST. Sí, es solo una forma de definir cualquier código. Si es código front-end, back-end, estilos, contenido, interacción, no importa. Entonces, como dijimos, puede ser desalentador al principio, pero de todos modos es interesante y puedes hacer mucho.

11. Construyendo Plugin de ESLint para Nombres de Clases

Short description:

Construí el paquete de nombres de clases con ESLint para garantizar consistencia en la base de código. Aunque me llevó unos días desarrollar el plugin de ESLint, aseguró la compatibilidad futura del código y ahorró tiempo a largo plazo. Las personas en la base de código están agradecidas por esta mejora.

Sí. Lo que construí con ESLint fue el paquete de nombres de clases, que todos usan, ¿verdad? Y en la base de código donde estaba trabajando, la gente lo importaba como SCX, y otros lo usaban como nombres de clases. Así que era inconsistente, y pensé, bueno, simplemente lo forzaré con un poco de ESLint, o podría haber hecho una búsqueda y reemplazo, y toda la base de código habría tardado 10 minutos, incluyendo la aprobación de la PR también. Pasé, como, tres o cuatro días escribiendo este plugin de ESLint solo para hacer cumplir esto. Pero luego, ahí es donde has asegurado la compatibilidad futura del código. Entonces, el método de búsqueda y reemplazo es bueno para casos puntuales, pero si quieres hacer cumplir eso en el futuro, es bueno tener esa regla. Así que, ya sabes, recuperarás ese tiempo. Sí, probablemente todavía haya personas en esa base de código agradeciéndome, oh, Mattin construyó esto, oh, gracias, Mattin.

QnA

ASTs y Code Mods

Short description:

Existen recursos en línea limitados para problemas comunes resueltos con ASTs. Los casos de uso pueden ser bastante específicos y los ejemplos de código a menudo tienen suposiciones incorporadas. Es desafiante escribir una solución completamente genérica, pero herramientas como generadores de código pueden proporcionar alcances específicos. La herramienta para generar ejemplos de código se desarrolla una vez y rara vez se actualiza. Sin embargo, se pueden construir salidas de emergencia para casos excepcionales. En cuanto a los code mods que utilizan ASTs, aparte de AG Grid, un proyecto emocionante llamado Mitosis de builder.io ofrece convertidores ASD para admitir una amplia gama de frameworks.

Muy bien, próxima pregunta de Anónimo. Oh, no marqué esta como completa. ¿Existen recursos en línea para problemas comunes resueltos con ASTs? Excepto, por ejemplo, el ejemplo de callback? El ejemplo de callback, como en para- en general, sí, como dije, no hay mucho contenido. No hay mucho contenido. Tienes que buscar, lo cual es un poco desafortunado, y creo que probablemente se debe a que las personas no están, tal vez no están al tanto, tal vez no ha habido suficientes charlas, ya sabes, diciéndole a la gente cómo usar estos ASTs. Así que tal vez deba escribir una publicación de blog al respecto. Pero también los casos de uso pueden ser bastante específicos. Entonces, como el código que tenemos, tiene suposiciones incorporadas, lo cual simplifica y reduce el alcance del problema. Así que, ya sabes, por eso, ya sabes, el código que tenemos para identificar dependencias, ya sabes, puedes ajustarlo a esta ventana, mientras que la verificación exhaustiva de profundidad oficial de React es, ya sabes, miles de líneas de código. Entonces sí, creo que ahí es donde se vuelve complicado porque escribirlo completamente de forma genérica es realmente difícil y por eso tenemos estas herramientas para hacerlo por nosotros. Pero cuando quieres usar eso, es bueno tener un alcance específico para ello. Y, por cierto, ¿esa herramienta para generar los ejemplos de código, es algo en curso que se está desarrollando continuamente o se desarrolla una vez y ya está? No, prácticamente nunca se le echa un vistazo. A veces puede haber casos excepcionales, pero ahí es donde radica la belleza de este tipo de herramientas que puedes construir salidas de emergencia. Así que no tienes que pasar... Es como la regla del 80-20. Podemos llevar el generador de código al 80% del camino, pero ese último 20% para hacerlo completamente a prueba de tontos te llevaría mucho más tiempo implementarlo. Mientras que a veces es bueno tener una salida de emergencia y simplemente escribir manualmente un ejemplo, que no funciona. Y eso nos da lo mejor de ambos mundos. Podemos escribir un ejemplo realmente complejo, ya sabes, simplemente escribir manualmente el react, pero luego, para la mayoría del trabajo, que es simplemente, ya sabes, tomar este ejemplo, convertirlo y luego simplemente dejarlo así. Suena como un plan. Una pregunta de un anónimo. ¿Alguna vez has construido code mods usando ASDs? ¿Y crees que sería posible transpilar código de un lenguaje a otro usando ASDs? Así que empecemos con la primera pregunta. ¿Alguna vez has construido algún code mod? No fuera de AG Grid. No. Entonces creo que lo que diría es que te señalaría un proyecto realmente emocionante de builder.io llamado Mitosis. Para sus componentes de builder.io que tienen, ellos mismos los escriben en este lenguaje Mitosis, que luego tienen convertidores ASD para React, Svelte, Angular, un rango mucho más amplio de lo que cubrimos. Así que ese es un producto interesante para ver si tú mismo necesitas admitir muchos frameworks diferentes con tu componente principal. Así que hay personas que lo están haciendo.

Explorando Pruebas de AST y Plugins de Babel

Short description:

Mitosis es un recurso recomendado para explorar ASTs. Las pruebas de scripts AST se pueden realizar utilizando un enfoque de prueba de instantánea o comparando el AST generado con la salida esperada. Codeshiftcommunity.com proporciona ejemplos de AST para aquellos interesados. Se pueden construir muchos plugins de Babel utilizando ASTs, incluido uno para eliminar declaraciones de depuración de una base de código.

Sí, eso es Mitosis. Sí, hemos visto la charla de Miska y lo mencionamos. Y sí, ya lo tengo en mi lista de tareas pendientes así que échale un vistazo, Mitosis.

Pregunta de Nick. ¿Hay una buena manera de probar scripts AST? Pregunta importante. Sí, supongo que lo bueno de los scripts AST es que podrías tener un enfoque de prueba de instantánea bastante bueno donde tienes una entrada bien definida o muchos tipos diferentes de entradas, las pasas a tu AST y luego validas lo que sale. Así que realmente se prestan muy bien para las pruebas. O si quieres hacerlo en todo el código base, ya sabes, tener una copia limpia y ver la diferencia de Git que produce. Sí, es una tecnología bastante probada a estas alturas, así que es bastante estable. Así que sí, puedes probarlo, por supuesto, puedes tener un script y generar el AST y comparar la cadena con la salida que esperas, ¿verdad? Sí. Así que tienes cierta estabilidad. Parece, sí, buena pregunta, Nik. Creo que si dependes de ello con una base de código tan grande, entonces es inteligente probar las cosas.

Otra pregunta, pero una nota de un anónimo. Codeshiftcommunity.com presenta ejemplos de AST. Así que cualquiera aquí, puedes ver el enlace allí arriba. Si alguien está interesado en ver ASTs, si estás haciendo algo en tu empresa y piensas, oh, Dios mío, puedo hacer esto con ASTs, hay algunos ejemplos en codeshiftcommunity.com. Así que muchas gracias, anónimo. Gracias. Por compartir eso con nosotros.

Muy bien, esa es la última pregunta. Oh, tenemos una nueva que llega. ¿Alguna idea sobre algún plugin de Babel que se pueda construir utilizando un AST? Ya hay muchos. Sí, hay, sí, se puede hacer mucho. Y ahí es donde, sí, debería haber enlazado este artículo, pero básicamente, comenzaron de manera muy simple diciendo, bueno, ¿puedo eliminar declaraciones de depuración de una base de código utilizando un plugin de Babel? Y así, las líneas, el código para hacer eso es realmente bastante pequeño. Así que sí, hay recursos disponibles. Debería haber obtenido el enlace, pero sí, estoy seguro de que hay muchos y también puedes escribir el tuyo propio. Muy bien. Bueno, muchas gracias, Steven.

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

A Guide to React Rendering Behavior
React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Concurrency, Explained
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
Top Content
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar
A Framework for Managing Technical Debt
TechLead Conference 2023TechLead Conference 2023
35 min
A Framework for Managing Technical Debt
Top Content
Let’s face it: technical debt is inevitable and rewriting your code every 6 months is not an option. Refactoring is a complex topic that doesn't have a one-size-fits-all solution. Frontend applications are particularly sensitive because of frequent requirements and user flows changes. New abstractions, updated patterns and cleaning up those old functions - it all sounds great on paper, but it often fails in practice: todos accumulate, tickets end up rotting in the backlog and legacy code crops up in every corner of your codebase. So a process of continuous refactoring is the only weapon you have against tech debt.In the past three years, I’ve been exploring different strategies and processes for refactoring code. In this talk I will describe the key components of a framework for tackling refactoring and I will share some of the learnings accumulated along the way. Hopefully, this will help you in your quest of improving the code quality of your codebases.

Fighting Technical Debt With Continuous Refactoring
React Day Berlin 2022React Day Berlin 2022
29 min
Fighting Technical Debt With Continuous Refactoring
Top Content
Let’s face it: technical debt is inevitable and rewriting your code every 6 months is not an option. Refactoring is a complex topic that doesn't have a one-size-fits-all solution. Frontend applications are particularly sensitive because of frequent requirements and user flows changes. New abstractions, updated patterns and cleaning up those old functions - it all sounds great on paper, but it often fails in practice: todos accumulate, tickets end up rotting in the backlog and legacy code crops up in every corner of your codebase. So a process of continuous refactoring is the only weapon you have against tech debt. In the past three years, I’ve been exploring different strategies and processes for refactoring code. In this talk I will describe the key components of a framework for tackling refactoring and I will share some of the learnings accumulated along the way. Hopefully, this will help you in your quest of improving the code quality of your codebases.
Monolith to Micro-Frontends
React Advanced Conference 2022React Advanced Conference 2022
22 min
Monolith to Micro-Frontends
Top Content
Many companies worldwide are considering adopting Micro-Frontends to improve business agility and scale, however, there are many unknowns when it comes to what the migration path looks like in practice. In this talk, I will discuss the steps required to successfully migrate a monolithic React Application into a more modular decoupled frontend architecture.
Inside Fiber: the in-depth overview you wanted a TLDR for
React Summit 2022React Summit 2022
27 min
Inside Fiber: the in-depth overview you wanted a TLDR for
I want to provide an in-depth overview of the important concepts behind reconciliation. We'll then explore how React uses the algorithm and go through a few magic words we hear a lot, like coroutines, continuations, fibers, generators, algebraic effects and see how they all relate to React.js.

Workshops on related topic

React Hooks Tips Only the Pros Know
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
Designing Effective Tests With React Testing Library
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Top Content
Featured Workshop
Josh Justice
Josh Justice
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn
Advanced TypeScript types for fun and reliability
TypeScript Congress 2022TypeScript Congress 2022
116 min
Advanced TypeScript types for fun and reliability
Workshop
Maurice de Beijer
Maurice de Beijer
If you're looking to get the most out of TypeScript, this workshop is for you! In this interactive workshop, we will explore the use of advanced types to improve the safety and predictability of your TypeScript code. You will learn when to use types like unknown or never. We will explore the use of type predicates, guards and exhaustive checking to make your TypeScript code more reliable both at compile and run-time. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Are you familiar with the basics of TypeScript and want to dive deeper? Then please join me with your laptop in this advanced and interactive workshop to learn all these topics and more.
You can find the slides, with links, here: http://theproblemsolver.nl/docs/ts-advanced-workshop.pdf
And the repository we will be using is here: https://github.com/mauricedb/ts-advanced