El Núcleo de Turbopack Explicado (Codificación en Vivo)

Rate this content
Bookmark

FAQ

Tobias Koppers es un desarrollador que trabajó en Webpack durante 10 años y actualmente está trabajando en TurboPack con la empresa Universal.

TurboPack es una nueva arquitectura diseñada para mejorar el rendimiento y la eficiencia de las compilaciones incrementales en aplicaciones grandes, especialmente diseñada para manejar millones de módulos sin ralentizarse.

La principal motivación detrás de TurboPack es resolver los problemas de escalabilidad y rendimiento que se presentan en Webpack a medida que las aplicaciones crecen y se vuelven más grandes, haciendo que las compilaciones incrementales sean más lentas.

TurboPack utiliza un enfoque de memorización y un sistema de ejecución incremental que permite recalcular solo las partes afectadas de la aplicación cuando se detectan cambios, haciendo que el proceso sea más eficiente.

El sistema de memorización en TurboPack evita la repetición de tareas ya ejecutadas al almacenar resultados de funciones previamente ejecutadas, lo que reduce el tiempo de compilación y mejora la eficiencia.

TurboPack mejora las compilaciones incrementales al permitir invalidar y recalcular solo las tareas afectadas por cambios en los archivos, en lugar de recompilar todos los módulos, lo que reduce significativamente los tiempos de compilación.

Sí, TurboPack es compatible con otras herramientas de Monorepo y se puede integrar como una herramienta de línea de comandos. Además, hay planes para una integración más profunda con TurboRepo para compartir cachés entre ambos sistemas.

Tobias Koppers
Tobias Koppers
29 min
01 Jun, 2023

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Tobias Koppers presenta TurboPack y TurboEngine, abordando las limitaciones de Webpack. Demuestra codificación en vivo para mostrar la optimización de la validación de caché y la eficiencia de compilación. La charla cubre agregar registro y memorización, optimizar la ejecución y rastrear dependencias, implementar invalidación y observador, y almacenar y eliminar invalidadores. También se discute la compilación incremental, la integración con otras herramientas de monorepo, la visualización de errores y la posibilidad de un sistema de complementos para Toolpag. Por último, se menciona la comparación con el Constructor de Bunn.

1. Introducción a TurboPack y TurboEngine

Short description:

Soy Tobias Koppers, el creador de TurboPack y TurboEngine. Estoy aquí para demostrar programación en vivo en JavaScript, enfocándome en el núcleo de TurboEngine. La motivación detrás de TurboPack es abordar las limitaciones de Webpack en el manejo de aplicaciones grandes y compilaciones incrementales. TurboPack introduce una nueva arquitectura para optimizar la validación de caché y mejorar la eficiencia de compilación. Mostraré una aplicación simple que copia archivos JavaScript basados en el grafo de dependencias, con la adición de un encabezado de derechos de autor. A través de la programación en vivo, explicaré el proceso y demostraré cómo TurboEngine mejora las compilaciones incrementales. ¡Comencemos!

Gracias por recibirme. Estoy intentando algo nuevo. Hoy estoy intentando hacer programación en vivo, así que espero que funcione. Mi nombre es Tobias Koppers y trabajé en Webpack durante 10 años y ahora me uní a Universal y trabajo en TurboPack tratando de hacer algo nuevo, algo mejor y sí, estoy tratando de enfocarme, como dije, en un aspecto de TurboPack y trato de explicar un poco cómo funciona TurboPack o el núcleo de TurboEngine en detalle, así que estoy tratando de demostrar algo con eso, así que estoy tratando de hacer programación en vivo en JavaScript un poco del núcleo de TurboEngine.

La motivación de eso es que en las aplicaciones de Webpack vimos que las aplicaciones crecen y crecen, cada vez más grandes y la arquitectura de Webpack no está diseñada para eso, las compilaciones incrementales tienden a volverse más lentas a medida que la aplicación crece. No es un problema enorme, pero sí puede convertirse en un problema en unos años cuando las aplicaciones tengan millones de módulos o algo así y algunos problemas que aislamos fueron que hacemos muchas búsquedas en caché, tenemos que calcular muchas cosas para validar la caché, como verificar si los archivos siguen siendo los mismos, hacer hash de cosas y ese es el problema porque todo este sobrecosto, lo pagas en cada compilación incremental y queremos hacer algo nuevo, una nueva arquitectura para abordar este problema. Y por eso creamos TurboEngine y TurboPack, es una nueva arquitectura y puedo explicar un poco haciendo programación en vivo.

Lo que quiero mostrar es una especie de aplicación pequeña que es súper simple, no es un empaquetador pero algo similar a un empaquetador, toma cualquier aplicación JavaScript y simplemente copia la aplicación siguiendo el grafo de dependencias a otra carpeta y al hacerlo también agrega un encabezado de derechos de autor solo para demostrar algo. Con eso, comienzo con la aplicación básica escrita en JavaScript y la explico más adelante y luego trato de agregar algo similar a TurboEngine para hacerlo más eficiente, para hacer compilaciones incrementales posibles de una manera similar a cómo funciona en TurboPack, en Rust y con TurboEngine. Para eso, preparé esta pequeña aplicación, es realmente simple, es solo un montón de archivos de Node.js. Usamos Acron para obtener el grafo de dependencias de algo, la ruta allí, los módulos.

Y recorro un poco la aplicación para que la entiendas. El proceso principal es realmente simple, obtenemos el directorio base, como el directorio de origen, tenemos un directorio de salida y luego tenemos un archivo de entrada que es en realidad este archivo en el que estamos mirando. Así que en realidad estamos copiando nuestra propia aplicación a otra carpeta. Y luego comenzamos a seguir el grafo de dependencias desde ese punto de entrada y copiamos eso desde la capa base a la capa de salida. Y para complicarlo un poco más, agrego este archivo de encabezado que básicamente es, déjame mostrarlo, es como una declaración de derechos de autor que se debe agregar a cada archivo para que sea un poco más interesante. Luego invocamos esta función llamada copiar grafo, que básicamente calcula la salida del archivo actual simplemente reubicándolo. Llamando a la función de copia que copia el archivo, súper simple. Y luego llama a otras dos funciones que se llaman obtener referencias que veremos más adelante, es como obtener las referencias, como todos los archivos que se han importado desde un archivo y luego recorrer eso y llamarse a sí mismo de forma recursiva para copiar toda la aplicación. Sí. Así que copiar también es bastante simple, leer el encabezado, leer el archivo y escribirlo en otro archivo. Nada super complicado aquí. Obtener referencias es un poco más complicado pero sí, no es realmente necesario entenderlo. Es como llamar a analizar para obtener un AST del módulo y como recorrer o hacer algo de magia para extraer las declaraciones de importación y devolver una lista de todos los archivos referenciados por ese tipo de archivo. Analizar también es bastante simple, llamando a Akon, que es una biblioteca de análisis de JavaScript. También leyendo el archivo obviamente y luego devuelve el AST. Y después de eso, inicio todo y eso debería copiar la aplicación a la nueva carpeta. Así que vamos a intentarlo. Oh. Algunas cosas que quiero explicar. También tengo esta función de tarea que en realidad no está haciendo nada actualmente.

2. Agregando Registro y Memorización

Short description:

Entonces, básicamente, solo estamos agregando un registro para que puedas ver lo que está haciendo la aplicación. Más adelante agregaremos más lógica a eso. El primer paso es agregar algún tipo de sistema de memorización que funcione como una caché. Almacenamos la caché en algún lugar utilizando un mapa. Ahora deberíamos tener este tipo de memorización, es bastante simple en realidad.

Entonces, básicamente, solo estamos agregando un registro para que puedas ver lo que está haciendo la aplicación. De lo contrario, no imprime nada, eso es bastante aburrido. Así que solo tiene registro y lo que hago es llamar básicamente a la función con registro. Lo ves, pero no es algo directo, no está haciendo nada especial.

Agregaremos más lógica a eso más adelante. Entonces, lo que terminarás viendo es toda esta aplicación en ejecución, por lo que se llama a main, se llama a copy graph, se llama a copy y se llaman a todas estas funciones en una especie de tres tipos de metales. Esto es básicamente una traza de pila.

Pero también verás muchos problemas con esta aplicación. Por ejemplo, estamos leyendo el encabezado varias veces, como aquí y aquí y aquí. Y también estamos llamando a copy graph varias veces. Estamos llamando a fs copy graph desde taskKey, porque se referencia desde fs. Y estamos llamando a copy graph desde task. Estamos haciendo mucho trabajo duplicado que no queremos hacer porque eso es lo que queremos hacer.

El primer paso es agregar algún tipo de sistema de memorización que funcione como una caché. Entonces, si ejecutas la misma función dos veces, simplemente devolvemos un resultado existente. Así que agreguemos eso. Para agregar una caché, almacenamos la caché en algún lugar. Y en JavaScript, podemos usar simplemente un mapa para eso. Y lo que queremos hacer es obtener la tarea del mapa como primer paso, la función de la caché. En realidad, queremos obtener la función y todos estos argumentos. Porque puedes llamar a la misma función con diferentes argumentos, que es básicamente una tarea diferente. Y luego, si tenemos una tarea, simplemente, si no tenemos una tarea, simplemente podemos crear una. Lo que significa que creamos un nuevo objeto que tiene algún resultado, que es indefinido para el y luego establecemos el resultado, que es básicamente lo que estábamos haciendo antes, así que copiamos eso aquí. Y luego, en cualquier caso, devolvemos el resultado. Así que ahora deberíamos tener algún tipo de sistema de memorización.

Me faltó algo, así que en realidad tengo que establecer la caché, sí, así. Y hay un error, probablemente lo veas si eres un desarrollador de JavaScript, el mapa no funciona con matrices porque se almacena por identidad, así que lo que realmente necesitamos hacer es almacenarlo por un tipo de valor de eso, así que para eso preparé algo que es como un TupleMap. Que necesito importar. Copiar carga, no lo hagas mal. Y ahora deberíamos tener este tipo de sistema de memorización, es bastante simple en realidad.

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

Vite: Repensando las Herramientas de Frontend
JSNation Live 2021JSNation Live 2021
31 min
Vite: Repensando las Herramientas de Frontend
Top Content
Vite is a next-generation build tool that leverages native ES modules for improved performance. It eliminates the need for bundling and improves hot module replacement. Vite provides an opinionated default configuration while still allowing advanced customization through plugins. It is framework agnostic and can be used for React and other applications. Vite is being adopted by Next.js and Create React App, and integration with Nuxt 3 offers significant speed improvements.
Compilador React Forget - Entendiendo React Idiomático
React Advanced 2023React Advanced 2023
33 min
Compilador React Forget - Entendiendo React Idiomático
Top Content
Joe Savona
Mofei Zhang
2 authors
The Talk discusses React Forget, a compiler built at Meta that aims to optimize client-side React development. It explores the use of memoization to improve performance and the vision of Forget to automatically determine dependencies at build time. Forget is named with an F-word pun and has the potential to optimize server builds and enable dead code elimination. The team plans to make Forget open-source and is focused on ensuring its quality before release.
Acelerando tu aplicación React con menos JavaScript
React Summit 2023React Summit 2023
32 min
Acelerando tu aplicación React con menos JavaScript
Top Content
Mishko, the creator of Angular and AngularJS, discusses the challenges of website performance and JavaScript hydration. He explains the differences between client-side and server-side rendering and introduces Quik as a solution for efficient component hydration. Mishko demonstrates examples of state management and intercommunication using Quik. He highlights the performance benefits of using Quik with React and emphasizes the importance of reducing JavaScript size for better performance. Finally, he mentions the use of QUIC in both MPA and SPA applications for improved startup performance.
SolidJS: ¿Por qué tanto Suspense?
JSNation 2023JSNation 2023
28 min
SolidJS: ¿Por qué tanto Suspense?
Top Content
Suspense is a mechanism for orchestrating asynchronous state changes in JavaScript frameworks. It ensures async consistency in UIs and helps avoid trust erosion and inconsistencies. Suspense boundaries are used to hoist data fetching and create consistency zones based on the user interface. They can handle loading states of multiple resources and control state loading in applications. Suspense can be used for transitions, providing a smoother user experience and allowing prioritization of important content.
De GraphQL Zero a GraphQL Hero con RedwoodJS
GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
De GraphQL Zero a GraphQL Hero con RedwoodJS
Top Content
Tom Pressenwurter introduces Redwood.js, a full stack app framework for building GraphQL APIs easily and maintainably. He demonstrates a Redwood.js application with a React-based front end and a Node.js API. Redwood.js offers a simplified folder structure and schema for organizing the application. It provides easy data manipulation and CRUD operations through GraphQL functions. Redwood.js allows for easy implementation of new queries and directives, including authentication and limiting access to data. It is a stable and production-ready framework that integrates well with other front-end technologies.
Los Átomos de Jotai Son Simplemente Funciones
React Day Berlin 2022React Day Berlin 2022
22 min
Los Átomos de Jotai Son Simplemente Funciones
Top Content
State management in React is a highly discussed topic with many libraries and solutions. Jotai is a new library based on atoms, which represent pieces of state. Atoms in Jotai are used to define state without holding values and can be used for global, semi-global, or local states. Jotai atoms are reusable definitions that are independent from React and can be used without React in an experimental library called Jotajsx.

Workshops on related topic

Uso de CodeMirror para construir un editor de JavaScript con Linting y AutoCompletado
React Day Berlin 2022React Day Berlin 2022
86 min
Uso de CodeMirror para construir un editor de JavaScript con Linting y AutoCompletado
Top Content
WorkshopFree
Hussien Khayoon
Kahvi Patel
2 authors
Usar una biblioteca puede parecer fácil a primera vista, pero ¿cómo eliges la biblioteca correcta? ¿Cómo actualizas una existente? ¿Y cómo te abres camino a través de la documentación para encontrar lo que quieres?
En esta masterclass, discutiremos todos estos puntos finos mientras pasamos por un ejemplo general de construcción de un editor de código usando CodeMirror en React. Todo mientras compartimos algunas de las sutilezas que nuestro equipo aprendió sobre el uso de esta biblioteca y algunos problemas que encontramos.