Video Summary and Transcription
La charla de hoy explora los conceptos de compilación y transpilación en JavaScript, destacando los tres pasos involucrados: análisis sintáctico, transformación de código y generación de código. Se discute el proceso de recorrer un árbol de sintaxis abstracta, con ejemplos de herramientas como Babel y ESLint que se pueden utilizar para transformaciones de código. Se presentan herramientas y técnicas de transformación de código, como CodeShift y el complemento T-TypeScript, enfatizando el poder de los árboles de sintaxis abstracta y el patrón visitante. El resumen concluye alentando a explorar más sobre refactorización y transformaciones de código utilizando herramientas como Babel, TSLint y astexplorer.net.
1. Understanding JavaScript Compilation
Hoy vamos a hablar de compilación, o mejor dicho, transpilación. De hecho, cuando hablamos de compilación, nos referimos a ese proceso que toma un código fuente como entrada y produce código binario o bytecode como salida. Toda la fase de compilación se lleva a cabo en tres pasos diferentes. Análisis sintáctico, transformación de código y generación de código.
♪♪♪ Hola a todos y bienvenidos a mi charla, Entendiendo la Compilación de JavaScript. Antes de comenzar, permítanme presentarme brevemente. Soy Michele Riva, Arquitecto Senior en NearForm, autor del libro Real World Next.js, Google Developer Expert y Microsoft MVP.
Hoy vamos a hablar de compilación, o mejor dicho, transpilación. De hecho, cuando hablamos de compilación, nos referimos a ese proceso que toma un código fuente como entrada y produce código binario o bytecode como salida. En JavaScript, es más probable que adoptemos la transpilación. Un ejemplo es el compilador de scripts REST, que toma un código de script REST correcto como entrada y produce código JavaScript correcto como salida. Así que de un código fuente a otro. Podemos hacer lo mismo con Babel, por ejemplo. En ese ejemplo, tenemos el encadenamiento opcional y los operadores nulos, que no son compatibles con versiones antiguas y navegadores antiguos. Queremos hacer que este código sea más compatible, así que tomamos este código fuente, lo alimentamos al compilador de Babel, y obtenemos el siguiente código como salida, que sigue siendo un código fuente válido de JavaScript, que es más compatible con versiones antiguas.
Toda la fase de compilación se lleva a cabo en tres pasos diferentes. Análisis sintáctico, transformación de código y generación de código. Vamos a desglosarlos. El primer paso para el análisis sintáctico es la tokenización. Así que tenemos var foo equals 10, y lo dividimos en tokens separados, var foo equals 10. Luego podemos crear un árbol de análisis. Y aquí podemos ver la estructura de nuestro programa y entender si es correcto o no. Y el siguiente paso sería la creación del árbol de sintaxis abstracta. Es bastante difícil de entender desde estas diapositivas, así que déjenme ir a la otra. Ok, así es como se presenta. Tenemos declaraciones de variables en la parte superior. Y nuevamente, JavaScript puede crear múltiples variables seguidas. En ese caso, creamos solo una variable. Así que terminaremos teniendo solo una declaración de variable. Entonces, var foo equals 10, es la declaración de variable. Podemos desglosarlo en todas las declaraciones de variables que tenemos. En ese caso, solo una. Entonces, declarador de variable, donde declaramos que foo es igual a 10. Podemos desglosar el declarador de variable nuevamente en dos partes diferentes, el identificador, foo, y el literal numérico, que es 10.
2. Understanding Abstract Syntax Tree Traversal
Si estuviéramos escribiendo como foo equals true, habríamos escrito el literal booleano en lugar del numérico. Al leer un árbol de sintaxis abstracta, llamamos a este proceso atravesar el árbol. Con Babel, podemos transformar las declaraciones de variables de var a let. El mismo concepto se aplica a otras herramientas como Prettier, ESLint, Babel, GIS, CodeShift. Con ESLint, podemos informar y corregir errores relacionados con literales de plantilla.
Si estuviéramos escribiendo como foo equals true, habríamos escrito el literal booleano en lugar del numérico, o cadenas o lo que sea, solo para que entiendas. Si bien es bastante fácil entender este árbol, supongo que este, es un poco más desafiante de manejar.
Al leer un árbol de sintaxis abstracta, llamamos a este proceso atravesar el árbol. Es bastante complejo en, por supuesto, programas complejos. Pero afortunadamente, muchas herramientas como Babel, ESLint, Pretier, nos proporcionan una interfaz agradable para atravesar el árbol que se llama el patrón visitante.
En ese caso, con Babel, estamos diciendo, ok, querido Babel, por favor, dame todas las declaraciones de variables o los identificadores, todos los literales numéricos, y simplemente los imprimimos en la consola. Una vez que obtenemos, por ejemplo, todas las declaraciones de variables, podemos comenzar a transformarlas. Así que ese es el caso. Decimos, ok, por favor, dame todas las declaraciones de variables dentro de nuestro código. Y si el tipo de variable es var, simplemente transfórmalo en let, lo cual no es sabio. No estoy sugiriendo que lo hagas, pero es un ejemplo muy sencillo. Así que eso nos facilita las cosas. Dicho esto, a la izquierda, tenemos nuestra entrada var foo equals 10. Y a la derecha, tenemos nuestra salida let foo equals 10. Como puedes ver, en la línea dos, tenemos constante y la dejamos intacta porque no es una variable, es una constante. Como puedes ver en el código, no estamos diciendo si es constante, por favor, cámbialo a let. Así que no estamos haciendo eso. Como dije, el mismo concepto se aplica a otras herramientas, como Prettier, ESLint, Babel, GIS, CodeShift. Y los veremos en detalle ahora mismo.
Con ESLint, tenemos un enfoque similar. Decimos, ok, por favor, ESLint, dame todos los literales de plantilla que puedas encontrar en mi código. Y si encuentro uno, puedo informar a ESLint un error, como por favor, no uses literales de plantilla. Y también puedo proporcionar una solución para ello. Pero en ese caso, si tengo una expresión dentro de mis literales de plantilla, puedo decir, ok, soy demasiado perezoso para eso. Así que solo estoy devolviendo, no estoy corrigiendo esto. Pero si no tengo una expresión, puedo decir, ok, así que no tengo expresión. No tengo ninguna expresión. Así que no hay data dinámica dentro de mis literales de plantilla. Así que simplemente cambia los literales por comillas dobles. Eso es lo que estamos haciendo ahora.
3. Code Transformation Tools and Techniques
JS CodeShift es una poderosa biblioteca desarrollada y mantenida por Facebook para refactorizaciones a gran escala. Te permite encontrar y reemplazar identificadores, facilitando la refactorización del código. Otra herramienta útil es el complemento T-TypeScript, que permite realizar transformaciones como realizar operaciones en tiempo de compilación en lugar de tiempo de ejecución. Al comprender los árboles de sintaxis abstracta e implementar el patrón visitante, puedes lograr transformaciones de código poderosas. Herramientas como Babel, TSLint, YASLint, Recast, Pretier y el sitio web astexplorer.net pueden ayudarte en este proceso. Gracias a todos por estar aquí y no dudes en contactarme para más discusiones sobre refactorización y transformaciones de código.
Y a la izquierda, la entrada y a la derecha, la salida. JS CodeShift, es otro ejemplo impresionante. Es una biblioteca desarrollada por Facebook y mantenida por Facebook mismo. Y está destinada a refactorizaciones grandes, a gran escala. Y el concepto es bastante similar.
Aquí, estamos diciendo, ok, por favor JS CodeShift, encuentra todos los identificadores. Y si los nombres de los identificadores contienen la cadena del nombre antiguo, reemplázalo con la cadena del nombre nuevo. Este es el caso nuevamente para refactorizaciones a gran escala. Entonces tenemos, por ejemplo, el nombre antiguo factory, que se refactoriza en el nuevo nombre factory.
También hay otro complemento impresionante de TypeScript, que se llama T-TypeScript, que puede ayudarnos a implementar nuevamente transformaciones agradables en el código. Por ejemplo, podemos decir, si hay una operación binaria como uno más uno, por favor, infórmamelo. Y luego podemos decir, ok, esta es una operación binaria. Estamos sumando dos números. Y en lugar de compilar a JavaScript, lo cual necesitaría hacer esa operación en tiempo de ejecución, hazlo en tiempo de compilación. Esa es la salida. Const mysum originalmente era 10 más 20. Y como salida, obtenemos const mysum igual a 30. Esa es la potencia de saber cómo atravesar un árbol de sintaxis abstracta e implementar el patrón visitante.
Y lo mismo se aplica con Babel, TSLint, YASLint, Recast, Pretier, JS CodeShift, y también hay un sitio web increíble, que se llama astexplorer.net que realmente puede ayudarte a depurar tus fórmulas y aprender más sobre cómo atravesar un árbol. Así que realmente quiero agradecerles a todos por estar aquí. Ha sido un verdadero placer hablar en Node Congress, y estos son mis manejadores de redes sociales, así que si quieres comunicarte, estaré encantado de hablar contigo nuevamente sobre cómo refactorizar bases de código y realizar transformaciones de código. Eso es lo que me encanta hacer y hablar. Así que gracias de nuevo. Espero verlos a todos pronto.
Comments