Migrando una aplicación de 1000 componentes de clase a Vue 3

This ad is not shown to multipass and full ticket holders
JSNation US
JSNation US 2025
November 17 - 20, 2025
New York, US & Online
See JS stars in the US biggest planetarium
Learn More
In partnership with Focus Reactive
Upcoming event
JSNation US 2025
JSNation US 2025
November 17 - 20, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

Vue 3 es increíble, pero muchos de nosotros todavía estamos atrapados en un monolito de Vue 2. Algunos de nosotros estamos aún más atrapados debido a las elecciones tecnológicas realizadas antes de que Vue 3 estuviera siquiera en el roadmap. Vamos a describir el proceso de migración de un proyecto grande a Vue 3 y Vite. Técnicas que podemos emplear para obtener algunos beneficios antes, procesos que podemos aplicar para hacer las cosas más rápidamente. Cosas que podemos hacer para lograrlo eventualmente.

This talk has been presented at Vue.js London 2023, check out the latest edition of this JavaScript Conference.

FAQ

Bagel Solutions es una empresa dirigida por Nikola, quien ha estado trabajando en la plataforma de aprendizaje automático V7 durante los últimos cuatro años. Bagel Solutions comenzó enfocándose en la visión por computadora y ha evolucionado hacia un sistema completo de aprendizaje automático de IA.

Nikola comenzó como desarrollador backend en Bagel Solutions y durante el último año se ha enfocado en el frontend. Ha participado activamente en la migración de la aplicación de frontend de Vue 2 a Vue 3, un proceso que aún está en curso.

La aplicación de Bagel Solutions incluye manejo de listas de tarjetas con cientos de miles de elementos y un editor de flujo de trabajo que permite la manipulación de elementos del DOM. Además, cuentan con un UI de anotaciones similar a Photoshop para dibujar anotaciones sobre imágenes o videos.

El enfoque de Bagel Solutions consiste en migrar dos componentes por sprint, con cada sprint durando dos semanas. Este proceso incluye un límite de tiempo de dos horas por componente y prioriza aquellos que están alineados con el desarrollo de nuevas características del producto.

Bagel Solutions utiliza TypeScript en su totalidad, junto con VUEX, aunque están en proceso de cambiar a Pinea. Para las pruebas, utilizan Jest con Vue Test Utils y tienen una configuración de Storybook para catalogar componentes.

Los objetivos incluyen cambiar todos los componentes relevantes a la API de Composición, hacer que la aplicación y el storybook se ejecuten en Vite, y migrar Jest a Vitest para aprovechar la configuración de Vite.

Durante la migración, cualquier código nuevo que se escriba debe utilizar la API de Composición, evitando la introducción de más componentes de clase a la base de código.

Están utilizando tiendas de Pinea como proxy para Vuex, lo que permite una transición gradual de Vuex a Pinea. Además, están configurando Vite para mejorar el rendimiento durante el desarrollo local.

Nikola Begedin
Nikola Begedin
28 min
15 May, 2023

Comments

Sign in or register to post your comment.
Video Summary and Transcription
La charla trata sobre la migración de una aplicación de vista frontend grande de Vue 2 a Vue 3. La estrategia implica convertir componentes al API de Composición, cambiar de Vuex a Pinea y superar los desafíos con la configuración de Vite. El proceso de migración incluye seleccionar componentes basados en el roadmap del producto, mejorar la seguridad de tipos y reducir el boilerplate. Los resultados de la migración incluyen una mejor verificación de tipos, pruebas más rápidas y un código más seguro.

1. Introducción a Bagel Solutions y migración a V7

Short description:

Hola a todos. Mi nombre es Nikola y soy el dueño de una empresa llamada Bagel Solutions. He estado trabajando con V7 en su plataforma de aprendizaje automático, que se ha convertido en un sistema completo de aprendizaje automático de IA. Actualmente, me estoy enfocando en el desarrollo frontend y estoy involucrado en la migración de una gran aplicación de vista frontend de Vue 2 a Vue 3. Esta charla comparte nuestra experiencia, conocimiento y estrategia en este proceso. V7 es un monolito frontend masivo con 360,000 líneas de código, lo que presenta desafíos únicos. Incluye características típicas de una aplicación de una sola página, así como partes caprichosas y similares a Photoshop. Tenemos alrededor de mil componentes, pero una parte significativa será eliminada debido a una reescritura importante del subsistema.

Mi nombre es Nikola y soy el dueño de una empresa llamada Bagel Solutions, porque Bagel es mi apodo. Durante los últimos cuatro años, he estado trabajando con V7 en su plataforma de aprendizaje automático. Comenzó como visión por computadora, pero se ha convertido en mucho más. Ahora es algo así como un sistema completo de aprendizaje automático de IA.

Comencé como desarrollador backend, pero actualmente, desde hace aproximadamente un año, me he enfocado en el frontend. Durante los últimos meses, hemos estado involucrados en la migración de su enorme aplicación de vista frontend de Vue 2 a Vue 3. Aún no hemos terminado, pero esta charla trata sobre ese proceso. Entonces, lo que no es esta charla, es una historia de éxito. Nuevamente, aún no hemos terminado. Todavía estamos en proceso. No es una alarde de lo rápido que lo hicimos de ninguna manera, porque nuevamente, aún no hemos terminado. Tampoco es realmente un tutorial, porque estamos haciendo algunas cosas específicas para nuestro proyecto que funcionan para nosotros. Puede que no funcione para usted. Puede que funcione, pero no hay garantía. Lo que es, es una compartición de la experiencia que tenemos con esto, el conocimiento que hemos adquirido, y la estrategia que hemos utilizado. Y nuevamente, probablemente no sea completamente aplicable a su caso. Pero espero que al menos sea interesante.

Entonces, ¿qué es v7? Básicamente, es un monolito frontend enorme. 360,000 líneas de código, más o menos. Y esto solo cuenta el TypeScript, sin contar nada más. Hay partes que se parecen a una aplicación de una sola página típica, gestión de datos, gestión de cuentas. Pero tienen problemas con los que necesitan lidiar, que una aplicación de una sola página típica no tiene, como renderizar listas de tarjetas con cientos de miles de elementos, o cosas así. Hay partes que parecen caprichosas. Este es nuestro editor de flujo de trabajo, donde básicamente arrastras diferentes elementos del DOM sobre un lienzo, los conectas con flechas, cosas así. Y también hay partes que funcionan y se ven como Photoshop. Este es nuestro UI de anotaciones, donde usas diferentes herramientas para dibujar diferentes tipos de anotaciones sobre un lienzo, que renderiza una imagen o un video u otra cosa visual. Tenemos alrededor de mil componentes en el proyecto. Pero para ser justos, estamos en medio o cerca del final de una reescritura importante de un subsistema bastante grande. Estimo que aproximadamente el 20% de esos componentes probablemente serán eliminados.

2. Estrategia de migración y objetivos

Short description:

Inicialmente decidimos utilizar componentes de clase de Vue debido a la falta de ingenieros frontend y nuestra familiaridad con las clases. Sin embargo, migrar a Vue 3 presenta desafíos porque los componentes de clase no se ejecutan en Vite o Vue 3. A pesar del posible soporte para componentes de clase en el futuro, estamos cambiando a la API de Composición como nuevo estándar. Nuestros objetivos de migración incluyen cambiar todos los componentes a la API de Composición, cambiar de UX a Binia, ejecutar tanto nuestra aplicación como el storybook en Vite, y cambiar Jest a Vitest. Para evitar interrupciones y errores, adoptamos una estrategia en la que un ingeniero convierte dos componentes en un sprint, con cada conversión limitada a dos horas. Además, cualquier código nuevo agregado debe utilizar la API de Composición.

Ahora, nos reservamos el derecho de mantener algunos de ellos por razones específicas, pero hablaré de eso más adelante. Tecnológicamente hablando, estamos utilizando TypeScript en su totalidad. Estamos utilizando VUEX, y se ha vuelto bastante cargado con el tiempo. Tenemos una docena aproximadamente de módulos. Ya no se sienten muy bien diseñados, porque hemos sido una startup durante un buen período, por lo que hemos estado agregando iterativamente sin una dirección asombrosa. Ya sabes, las startups cometen errores.

Porque estamos utilizando... Bueno, primero, decidimos utilizar componentes de clase de Vue. Esto fue muy temprano en el ciclo de desarrollo del producto, hace unos tres años y medio más o menos, y decidimos seguir con eso porque, en primer lugar, no teníamos muchos ingenieros frontend. Muchos de nosotros éramos full-stack y las clases eran algo con lo que estábamos más familiarizados. Parecía ser la forma de hacerlo en ese momento, y en ese momento también parecía ser un enfoque que tenía un mejor soporte de TypeScript debido a los decoradores de clase y los decoradores de clase de VueX, que también usamos como biblioteca. Pero sí, esa fue una decisión tomada en ese momento.

Para las pruebas, por supuesto, usamos Jest con Vue Test Utils, y tenemos una configuración de storybook, que utilizamos como catálogo de componentes, pero no dentro del contexto de escribir pruebas ni nada por el estilo. Por lo tanto, claramente, para migrar a Vue 3, el problema número uno es el hecho de que utilizamos componentes de clase. Eso significa que hay más trabajo para migrar un componente que con la API de opciones, y eso significa que desde el principio no podemos comenzar con la configuración de Vite para la compilación frontend en Vite porque los componentes de clase no se ejecutan realmente en Vite o en Vue 3. Ahora, en este momento, según tengo entendido, hay algunas PR en revisión para los componentes de clase de Vue y las bibliotecas de clase de VueX, potencialmente incluso un candidato a versión o algo así, donde se agregará este soporte. Por lo tanto, es posible que para cuando terminemos la migración, también sea posible ejecutar componentes de clase en Vite, pero aún así estamos cambiando a la API de Composición simplemente porque es un nuevo estándar y preferimos utilizar el estándar en lugar de una alternativa de terceros. Bueno, eso es lo que hacemos ahora.

Nuestra lista de objetivos para considerar que esta migración está completa es cambiar todos los componentes a la API de Composición, al menos aquellos que vamos a mantener, y tal vez algunos más, y nuevamente, hablaré de eso un poco más adelante, cambiar de UX a Binia, porque es el nuevo estándar, hacer que nuestra aplicación y el storybook se ejecuten en Vite, y hacer que Jest cambie a Vitest, lo que significa que también utiliza la misma configuración de Vite, lo cual es una gran ventaja con Vitest o Jest.

Entonces, necesitamos una estrategia para esto, y desde el principio decidimos que un gran esfuerzo único no es una buena idea. No podemos hacer un gran esfuerzo de simplemente migrar, migrar, migrar hasta que terminemos, y luego pasar a otra cosa. En primer lugar, nuestro equipo es bastante grande ahora, tenemos alrededor de 30 ingenieros, e incluso con ese tamaño, probablemente llevará semanas migrar todos esos componentes, especialmente porque nos pisaremos los unos a los otros. Estamos garantizados de crear errores de esta manera, hay demasiado código que se está cambiando como para que eso no suceda. Y habrá demasiados retrasos en nuestro trabajo de producto, así que sí, no estamos de acuerdo con eso. Para mejorar nuestro proceso, decidimos que debe ser algo que nos brinde beneficios a medida que avanzamos, y no cuando terminemos, y debe ser lo menos disruptivo posible.

Entonces, el enfoque básico que adoptamos es que un ingeniero convierte dos componentes en un sprint, y nuestro sprint dura dos semanas, para nosotros, y esta conversión de un solo componente tiene un límite de tiempo de dos horas. Eso significa que si parece que llevará más de dos horas, ese ticket se pone inmediatamente en espera y tomamos el siguiente. El razonamiento es que a medida que adquirimos experiencia haciendo estas conversiones, podemos aumentar la velocidad, tal vez cambiar las reglas para elegir más componentes, y luego podemos volver a visitar esos tickets que pusimos en espera, para ver si tal vez será más rápido esta vez porque sabemos más. Y luego, como parte de todo este esfuerzo, hay una regla adicional de que cualquier código nuevo que escribamos, cualquier componente nuevo que agreguemos a la base de código, debe utilizar la API de Composición. Por lo tanto, no más introducción de componentes de clase adicionales a la base de código.

3. Selección y Ejecución de Componentes

Short description:

La estrategia para seleccionar componentes implica alinearse con la hoja de ruta del producto, migrar componentes antes de que comience el desarrollo e identificar áreas en el código para una migración paralela. El enfoque se centra en construir conocimiento, mejorar la seguridad de tipos, reducir el código repetitivo y acelerar el trabajo de funciones. La ejecución implica retrasar la migración de algunos componentes, marcar secciones de la aplicación como migradas y convertir componentes basados en un mapa de componentes de clase a la API de Composición. El objetivo es recopilar conocimiento y mejorar como equipo.

La siguiente parte de la estrategia es cómo seleccionamos estos componentes, y aquí, una vez más, fue importante para nosotros no ser demasiado disruptivos. Por lo tanto, la primera prioridad es alinearse con el producto. Eso significa que entendemos cuál es la hoja de ruta del producto, cuáles son las próximas características que se desarrollarán y qué componentes en el código serán afectados por ese desarrollo. Entonces nos enfocamos en migrar esos componentes primero antes de que comience ese desarrollo, para que el trabajo de funciones se realice en código moderno y no se vea ralentizado por ninguna conversión.

Además de eso, identificamos áreas en nuestro código que podemos migrar juntas, para que partes de la aplicación se modernicen lo antes posible. Y con islas nos referimos a componentes que están relacionados con la construcción de una parte específica del producto, una página específica, tal vez alguna subcaracterística. Y también componentes que interactúan con los mismos Vuex modules, porque presumiblemente eso también se alinea, y nos permite cambiar de Vuex a Pina más fácilmente en paralelo.

El mantra aquí es que, a medida que hacemos esto, necesitamos construir conocimiento. Aprendemos sobre todas las advertencias que podemos, documentamos todo esto y lo compartimos con el resto del equipo para que todos sean más rápidos, y a medida que avanzamos, volvemos a aumentar la velocidad. Esa es nuestra prioridad número uno. Entonces, los efectos que esperamos y que estamos viendo con esta estrategia es que a medida que avanzamos, obtenemos una mejor seguridad de tipos, porque en primer lugar, la API de Composición por defecto tiene una inferencia de tipos más directa y ligeramente mejor. Pina es mucho mejor en inferencia de tipos y verificación de tipos que Vuex. Hay menos código repetitivo, reducimos la cantidad de errores en algunas categorías relacionadas con todo esto. Aceleramos el trabajo de funciones, en realidad, porque las nuevas funciones se construyen sobre un código moderno y obtenemos conocimiento sobre otras cosas que podemos hacer a medida que migrarnos. No solo conversiones, sino también otras cosas en nuestro código, porque efectivamente mientras hacemos esto, estamos auditando nuestro código y encontrando cosas que hicimos mal al principio, o encontrando cosas que podríamos hacer mejor ahora que sabemos más, cosas como esas. Encontrar código no utilizado, agregar documentación que nos falta, encontrar cosas que podríamos reescribir de una mejor manera, agregar pruebas que nos faltan. Fuimos una startup durante gran parte de la vida de este producto, por lo que ahora que somos más grandes y tenemos el tiempo y la capacidad para hacer las cosas correctamente, queremos hacerlo a medida que avanzamos.

Entonces, ¿cómo ejecutamos esto? En primer lugar, hay algunas partes fáciles que podemos hacer. Retrasamos la migración del 20% de los componentes que eventualmente queremos eliminar, pero esto no es una regla estricta. Tenemos esas áreas para convertir que queremos cambiar, por lo que si hay un componente allí que nos permita marcar una gran sección de la aplicación como migrada, entonces podemos dedicar una hora o dos para migrar ese componente. Siempre son una opción. Y luego, la otra parte es que si miramos nuestro código, tenemos alrededor de 100 componentes que se ven como este ejemplo que estoy mostrando. Básicamente, el componente no tiene lógica, es solo una plantilla, solo CSS, y todo lo que hace es exportar una clase vacía, efectivamente. Reemplazamos eso con una exportación predeterminada que simplemente exporta un objeto con un nombre, y técnicamente podríamos reemplazar esto con solo un bloque de script en blanco, o incluso omitir completamente el bloque de script, pero debido a un problema específico, tenemos que exportar este nombre, y lo explicaré en unos pocos diapositivas. Entonces, la siguiente parte de la ejecución son las conversiones reales de componentes, y aquí, realmente, es solo un mapa de lo que es una cosa en componentes de clase y lo que se convierte en una API de Composición. Entonces, realmente no hay mucho de qué hablar aquí. Hay un poco más de complejidad cuando agregamos decoradores de VuexClass, pero aún así, solo estamos mapeando cosas a computadoras, funciones o refs, básicamente, u objetos reactivos. Entonces sí, nada de eso es demasiado difícil. Esto no es un trabajo altamente especializado ni nada por el estilo. Es solo trabajo de rutina, y la parte importante que debemos extraer de esto, y que estamos tratando de extraer de esto, es esa recopilación de conocimiento y difundir ese conocimiento en todo el equipo de ingeniería, y simplemente ayudarnos mutuamente a mejorar en esto.

4. Migración de Vuex a Pinea

Short description:

Una gran parte de la ejecución implica pasar de Vuex a Pinea. Definimos una tienda de Pinea que es un proxy para Vuex. Cambiamos gradualmente del uso directo de Vuex a la tienda de Pinea, componente por componente. La tienda de Pinea comienza completamente tipada, proporciona una mejor documentación y permite la fragmentación en tiendas más pequeñas.

Una gran parte de la ejecución implica pasar de Vuex a Pinea, y esto es algo que especialmente me gusta. Este enfoque que hemos desarrollado es una forma de tener una tienda de Pinea que es un proxy para Vuex. Lo que hacemos aquí es definir una tienda, como lo harías con cualquier otra tienda de Pinea, pero en lugar de usar refs, reactive, getters y acciones para definir el estado interno de la tienda, en su lugar definimos computed que actúan como proxy para el estado o los getters de Vuex, y definimos acciones que actúan como proxy para store.dispatch o store.commit, y luego esos se devuelven mediante el componible de la tienda de Pinea.

Desde el exterior, el efecto de esto es que desde el exterior, la tienda de Pinea se ve como cualquier otra tienda de Pinea, pero internamente, está utilizando Vuex. Esto nos permite cambiar gradualmente del uso directo de Vuex para estas cosas al uso de esa tienda de Pinea, componente por componente, paso a paso, en solicitudes de extracción separadas, conjuntos de cambios separados, y así sucesivamente. Y una vez que encontramos que la parte de Vuex ya no tiene uso directo y todo se hace a través de la tienda de Pinea, podemos eliminar la parte de Vuex y pasar completamente a Pinea al declarar realmente esos refs, esos objetos reactivos y esas acciones dentro de la tienda de Pinea. Y esto es, nuevamente, un solo paso, cambiando solo un archivo y luego eliminando algo de código de otros archivos, y eso es todo.

Como beneficio de esto, hay algunos beneficios adicionales. Uno de ellos es que la tienda de Pinea comienza completamente tipada, por lo que la interfaz está completamente tipada, a diferencia de Vuex que se basa en dispatch y commit, y la única forma de tiparlo realmente es volver a declarar los tipos localmente. Obtenemos una mejor documentación porque ahora la estamos escribiendo nosotros, y esos antiguos módulos probablemente no estén tan bien documentados, y todo está en un solo lugar. Y también podemos fragmentar en tiendas de Pinea más pequeñas, no hay una regla que diga que debe haber una tienda de Pinea por cada módulo de Vuex. Podemos dividir ese módulo en múltiples tiendas o podemos seleccionar diferentes cosas de diferentes módulos de Vuex en una sola tienda de Pinea, si tiene sentido. Y todo esto tiene un riesgo extremadamente bajo.

5. Configuración de Vite y Desafíos de Migración

Short description:

Encontramos algunos desafíos al ejecutar la migración, como problemas de compatibilidad entre Webpack y Vite, el uso de módulos CommonJS y cargadores personalizados en nuestra configuración de Vue-CLI. Sin embargo, pudimos superar estos desafíos utilizando complementos definidos, reemplazando módulos CommonJS y reescribiendo los cargadores personalizados en la sintaxis de beat. Actualmente, estamos utilizando beat como una configuración paralela para el desarrollo local, pero no para las compilaciones de implementación. Además, enfrentamos problemas con Vue testutils v1 y los componentes de script setup, los cuales resolvimos agregando un segundo bloque de script sin el atributo de setup.

Y luego, otra parte de la ejecución es Vite. Así que mucho antes, antes de comenzar esta migración, intentamos configurar una configuración de Vite para ejecutar nuestra aplicación en Vite en lugar de la configuración de Webpack que proporciona Vue CLI. No pudimos hacerlo debido a los componentes de clase, y esto podría ser posible en unas pocas semanas o algo así. Incluso podría ser posible ya, no lo he verificado recientemente. Pero en ese momento no lo era. Así que decidimos ir primero con la migración.

Ahora que tenemos algunas de esas islas migradas de la API de Composición, podemos configurar una configuración de Vite que se ejecutará. Y cuando estamos desarrollando en esas islas, es decir, desarrollando nuevas características, podemos usar esa configuración de Vite en el desarrollo local. Esto hace que sea más rápido, con mejor rendimiento y más agradable de usar. Y luego, si tenemos esta configuración, también podemos usarla para cambiar gradualmente a Vitest, podemos usarla para Storybook, podemos usarla para la extensión de vista previa de JS en VS Code, cosas así.

Hay algunos bloqueadores que tuvimos que identificar y solucionar, pero no son muchos y no fue tan difícil. El primero, el más obvio, es que Webpack se basa en process.env para las variables de entorno, mientras que Vite se basa en import.meta.env, y esto se puede hacer compatible fácilmente utilizando un complemento definido en Webpack o en Vite. Básicamente, en Webpack, usamos el complemento definido para mapear process.env a import.meta.env, y luego el código accede a import.meta.env en todas partes, y esto luego funciona tanto en la configuración de Vue-CLI como en la configuración de Vite. Recomiendo este enfoque y no al revés, simplemente porque cuando eliminamos Vue-CLI, solo tenemos que eliminar esa configuración y no tenemos que cambiar nada en el código base.

La otra parte con la que tuvimos un problema es que todavía estábamos usando algunos módulos CommonJS en algunos lugares, muy raramente, principalmente código heredado o código que hemos tomado de otro lugar. Y esto no fue realmente tan difícil de reemplazar, pero hubo algunas peculiaridades al importar imágenes dinámicamente o cosas por el estilo. Aún así, fue relativamente sencillo de manejar. Y también tenemos un par de cargadores personalizados en nuestra configuración de Vue-CLI. Por ejemplo, tenemos una forma especial de incrustar archivos SVG como componentes Vue. Para eso, tendríamos que eliminar el uso de esos cargadores, es decir, no hacer esas cosas, o reescribirlos en beat, dentro de la sintaxis de beat. Y decidimos optar por esta segunda opción porque realmente no fue tan difícil. Nos llevó tal vez dos o tres horas reimplementar nuestros cargadores en beat. De todo eso, puedo decir que estamos usando beat como una configuración paralela para el desarrollo local. Pero aún no lo estamos utilizando para las compilaciones de implementación.

Ahora, por supuesto, encontramos algunos problemas al ejecutar todo esto. El más notable probablemente es que Vue testutils v1, que es compatible con Vue 2.7, tiene algunos problemas con el script setup. Algunos se solucionaron, pero el que aún está activo para nosotros es que si tienes un componente de script setup y escribes una prueba para un componente que es el padre de ese componente, y tienes una captura de pantalla en esa prueba, el componente hijo que es script setup se renderizará como un stop anónimo. Por lo tanto, no tendrá un nombre en la captura de pantalla. Esto se debe a que, aparentemente, Vue TestUtils v1 no puede inferir el nombre del nombre de archivo para el componente de script setup. Lidiamos con esto agregando un segundo bloque de script en cada componente de script setup, que es un bloque de script normal sin el atributo de setup.

6. Migración de Componentes y Mejoras en las Pruebas

Short description:

Y ese solo exporta el nombre del componente. Crea un problema con un complemento que usamos para ordenar las importaciones en nuestros archivos. Estamos esperando una solución para ese complemento. Otro problema está en el antiguo Vue clásico, dependemos de complementos y extendemos la instancia base de Vue con cosas como Store, Router, Route, etc. Para seguir usando estos, necesitamos composables. Comenzamos a usar JustMock para simular directamente el UseStoreComposable. Cambiamos por completo a PascalCase en nuestras plantillas. Cambiamos gradualmente de Wrapper.find a Wrapper.findComponent. Preferimos usar solo mock o inyectar mocks como store o router en la llamada de shallow mount. Estamos encontrando y eliminando bibliotecas de solo vista.

Y ese solo exporta el nombre del componente. Y esta es la razón por la que así migrados esos componentes básicos hace unas pocas diapositivas atrás. Entonces esto hace que las instantáneas funcionen de nuevo. Pero crea un problema con un complemento que usamos, que es un complemento de prettier que usamos para ordenar las importaciones en nuestros archivos. Cuando un archivo Vue tiene dos bloques de script, el complemento no puede ordenar las importaciones correctamente. Eso significa que probablemente un par de docenas de nuestros archivos Vue no tienen sus importaciones ordenadas, y estamos esperando una solución para ese complemento. No es un gran problema. Sería bueno que todo funcione, pero en unas pocas semanas probablemente lo hará y hará un prettier fix all y eso es todo. Hay algunos problemas más que tenemos que resolver. Uno está en el antiguo Vue clásico, dependemos de complementos y extendemos la instancia base de Vue con cosas como Store, Router, Route y algunas otras cosas que usamos, pero estas son las más comunes. Y para eso, para poder seguir usando estas cosas, necesitamos composables, porque en setup realmente no accedemos a esto. Para obtener un composable de algo como esto, podemos confiar en la función GetCurrentInstance que importamos de Vue, y es extremadamente sencillo. Simplemente llamamos a GetCurrentInstance y luego devolvemos el almacén proxy de esa instancia. Ahora, internamente eso significa que un componente debe estar montado para que esto se defina y se devuelva. Eso significa que el mismo caso también debe estar en la prueba. Por ejemplo, si tienes un composable que internamente usa store, o llama UseStore, entonces ese composable no se puede probar directamente. Debe estar montado en un componente para ser probado. Alternativamente, simplemente usamos JustMock para simular directamente el UseStoreComposable, y luego esto no sucede en absoluto. Simplemente devolvemos algo a través de la simulación, y luego podemos probar el otro composable más directamente. Esto es lo que comenzamos a hacer, simplemente porque encontramos que las pruebas son un poco más unificadas, y la configuración es más fácil, y es bastante sencillo. Hay algunas otras cosas que comenzamos a hacer. Como dije, mientras hacíamos esto, buscábamos cosas en el código base que también podríamos hacer. Algunas cosas que hicimos es que cambiamos por completo a PascalCase. Realmente no teníamos una regla sobre si estábamos usando PascalCase o KebapCase en nuestras plantillas. Ahora, estamos usando completamente PascalCase en las plantillas, con una regla. Comenzamos a cambiar gradualmente de Wrapper.find a Wrapper.findComponent, porque hace las pruebas un poco menos frágiles y un poco más estructuradas. Comenzamos a preferir el uso de solo mock, o inyectar mocks como store o router en la llamada de shallow mount. Esto hace que las pruebas, suena contradictorio, pero un poco más agnósticas del framework, porque cambiar a BTest es tan fácil como hacer una búsqueda y reemplazo en este caso. Nuevamente, las pruebas son más unificadas, como pruebas unitarias, menos integración, y tienden a ejecutarse un poco más rápido debido a ello. Otra cosa que estamos haciendo es encontrar y eliminar bibliotecas que son solo para vista.

7. Resultados, Consejos y Recomendaciones

Short description:

Reemplazamos bibliotecas con componibles de vista. La biblioteca Vue.tsc mejoró la comprobación de tipos y aceleró las pruebas. Migramos 400 componentes, eliminamos los módulos Vue.x y mejoramos el tiempo de compilación. La base de código es más segura y no afecta el trabajo del producto. Se recomiendan PINIAproxies y 2REF.

Principalmente, estamos haciendo esto reemplazando esas bibliotecas con algunos componibles proporcionados por la biblioteca view-use, o un conjunto de bibliotecas. Todo ese conjunto de bibliotecas es increíble para nosotros y realmente nos está ayudando mucho con la migración.

También comenzamos a usar la biblioteca Vue.tsc para la comprobación de tipos. Este es el comprobador de tipos que utiliza Volar, la extensión para VSCode, y hace un trabajo mucho mejor al comprobar los archivos de vista que el comprobador de TypeScript normal. Esto nos permite, además, usar el modo aislado de la opción modules, establecerlo en true en Jest, lo que hace que nuestras pruebas sean mucho más rápidas. Esto tiene el costo de una seguridad de tipos ligeramente menor en las pruebas, pero como la comprobación de Vue.tsc se ejecuta en nuestra CI, esto realmente no es un problema para nosotros y en realidad nos hace más seguros en general, con la ventaja de que las pruebas se ejecutan tres o cuatro veces más rápido.

Entonces, ¿cuáles son los resultados de todo esto? Nos quedan alrededor de 400 componentes por migrar. Nuevamente, comenzamos con 1,000 menos el 20% de los componentes de la V1, que todavía están ahí. Por lo tanto, efectivamente estamos en alrededor de 800 a 200 ahora. Hemos eliminado completamente un par de módulos Vue.x. Tenemos varios procesos PNA en marcha, por lo que estamos en camino de eliminar más módulos Vue.x a medida que avanzamos. Nuestras pruebas, debido a algunos de los cambios, se ejecutan cuatro veces más rápido, si no más. El conjunto completo de pruebas se ejecuta en aproximadamente dos minutos y medio localmente en modo de un solo hilo. Nuestro tiempo de compilación es aproximadamente tres veces más rápido porque pudimos eliminar algunas cosas de allí. Hay menos código, porque la API de composición tiene menos código repetitivo y pudimos eliminar parte del código. En general, encontramos menos errores. La base de código en su conjunto es un poco más segura. El trabajo del producto no se ve afectado en absoluto. En promedio, apostaría a que es más rápido. Realmente no hicimos ninguna medición. Es difícil medir algo así. Realmente nunca retrasamos el trabajo del producto por nada, y cualquier nueva función se está trabajando en una base central más moderna. No puedo imaginar que sea más lento. Como mínimo, está al mismo ritmo.

Como una de las últimas diapositivas, lo que hemos aprendido es básicamente una colección de consejos del día sobre cosas. Solo un par de cosas. PINIAproxies, el proceso que he descrito, es realmente excelente para iniciar gradualmente la experiencia de usuario. Realmente lo recomendaría. 2REF es una función impresionante si desea pasar una propiedad o una clave en un objeto reactivo a un componible como algo reactivo. Esto le permite pasar una sola propiedad en lugar de pasar todas las propiedades a un componible porque el componible realmente solo necesita esa única propiedad.

8. Composables, Assertions, and Future Steps

Short description:

No es necesario reutilizar componibles para justificar su creación. Está claro que los comportamientos separados se pueden organizar dentro de un componente utilizando componibles más pequeños. Las aserciones en las pruebas son más útiles que las pruebas de instantáneas, ya que detectan errores. El conjunto de bibliotecas view-use cubre la mayoría de nuestras necesidades. Nuestras estimaciones incluyen completar los componentes a finales del verano, pasar a PiNeo poco después, una migración completa a Vite y Vue 3 en otoño y, finalmente, pasar completamente a Vitest debido al volumen de pruebas.

Realmente no es necesario reutilizar componibles para justificar su creación. Por lo tanto, puedes tener un componente más grande que tenga varios comportamientos diferentes implementados. Algunos podrían argumentar que debería separarse en componentes más pequeños. Pero también se podría argumentar que puedes organizar esas cosas diferentes dentro del componente en diferentes componibles más pequeños. Aunque se utilicen solo una vez, queda claro que son varias cosas separadas. Proporciona un poco de auto-documentación. Y te permite probar esos comportamientos de forma aislada, lo cual siempre es genial.

Lo otro que encontramos, y esto probablemente sea para nosotros, tal vez para algunos de ustedes, pero definitivamente funciona para nosotros. Las aserciones en las pruebas son mucho más útiles que las pruebas de instantáneas. Encontramos muchas pruebas de instantáneas en nuestro código heredado que realmente no hacen absolutamente nada. Entonces, ni siquiera representan lo que esperaríamos que representaran, porque la configuración para la prueba no estaba como debería haber estado. Y esto estaba en el código, pasó la revisión, realmente no le prestamos atención. Entonces, la prueba no estaba haciendo nada por nosotros. En cambio, si reemplazamos esas pruebas de instantáneas con aserciones explícitas en las cosas en las que realmente estamos interesados, funcionan mucho mejor para nosotros y realmente detectan errores.

Y luego el último consejo o lo que aprendimos es, nuevamente, view-use, ese conjunto de bibliotecas es increíble, cubre el 90% de, bueno, no tus, pero probablemente nuestras necesidades, tal vez las tuyas. Entonces, como última diapositiva, nuestras estimaciones, dónde esperamos estar. Esperamos terminar con los componentes a finales del verano. La gente se tomará tiempo libre, todo eso. Probablemente se ralentizará hacia el final. Esperamos terminar con PiNeo poco después porque lo estamos haciendo en paralelo, hasta cierto punto. Nos gustaría hacer una migración completa a Vite. Entonces, todo, la aplicación, storybook a principios del otoño y luego una migración completa a Vue 3 a mediados del otoño porque ahora estamos convirtiendo la API de composición, ¿verdad? Una vez que hayamos terminado con todo eso, todavía habrá algunos pasos involucrados para realmente cambiar a Vue 3. Y luego la última parte que probablemente terminaremos haciendo es pasar completamente a Vitest, simplemente debido al volumen de pruebas que tenemos. Y sí, eso es todo. Gracias. ¿Hay alguna pregunta?

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.
Todo Más Allá de la Gestión de Estado en Tiendas con Pinia
Vue.js London Live 2021Vue.js London Live 2021
34 min
Todo Más Allá de la Gestión de Estado en Tiendas con Pinia
Top Content
State management is not limited to complex applications and transitioning to a store offers significant benefits. Pinia is a centralized state management solution compatible with Vue 2 and Vue 3, providing advanced devtools support and extensibility with plugins. The core API of Pinia is similar to Vuex, but with a less verbose version of stores and powerful plugins. Pinia allows for easy state inspection, error handling, and testing. It is recommended to create one file per store for better organization and Pinia offers a more efficient performance compared to V-rex.
Bienvenido a Nuxt 3
Vue.js London Live 2021Vue.js London Live 2021
29 min
Bienvenido a Nuxt 3
Top Content
Nux3 has made significant improvements in performance, output optimization, and serverless support. Nuxt Bridge brings the Nitro engine for enhanced performance and easier transition between Nuxt 2 and Nuxt Read. Nuxt 3 supports Webpack 5, Bytes, and Vue 3. NextLab has developed brand new websites using Docus technology. Nuxt.js is recommended for building apps faster and simpler, and Nuxt 2 should be used before migrating to Nuxt 3 for stability. DOCUS is a new project that combines Nuxt with additional features like content modules and an admin panel.
Un Año en Vue 3
Vue.js London Live 2021Vue.js London Live 2021
20 min
Un Año en Vue 3
Top Content
Vue 3 has seen significant adoption and improvements in performance, bundle size, architecture, and TypeScript integration. The ecosystem around Vue 3 is catching up, with new tools and frameworks being developed. The Vue.js.org documentation is undergoing a complete overhaul. PNIA is emerging as the go-to state management solution for Vue 3. The options API and composition API are both viable options in Vue 3, with the choice depending on factors such as complexity and familiarity with TypeScript. Vue 3 continues to support CDN installation and is recommended for new projects.
Utilizando Rust desde Vue con WebAssembly
Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilizando Rust desde Vue con WebAssembly
Top Content
In this Talk, the speaker demonstrates how to use Rust with WebAssembly in a Vue.js project. They explain that WebAssembly is a binary format that allows for high-performance code and less memory usage in the browser. The speaker shows how to build a Rust example using the WasmPack tool and integrate it into a Vue template. They also demonstrate how to call Rust code from a Vue component and deploy the resulting package to npm for easy sharing and consumption.
Vue: Actualizaciones de Características
Vue.js London 2023Vue.js London 2023
44 min
Vue: Actualizaciones de Características
Top Content
The Talk discusses the recent feature updates in Vue 3.3, focusing on script setup and TypeScript support. It covers improvements in defining props using imported types and complex types support. The introduction of generic components and reworked signatures for defined components provides more flexibility and better type support. Other features include automatic inference of runtime props, improved define emits and defined slots, and experimental features like reactive props destructure and define model. The Talk also mentions future plans for Vue, including stabilizing suspense and enhancing computer invalidations.

Workshops on related topic

Monitoreo 101 para Desarrolladores de React
React Summit US 2023React Summit US 2023
107 min
Monitoreo 101 para Desarrolladores de React
Top Content
WorkshopFree
Lazar Nikolov
Sarah Guthals
2 authors
Si encontrar errores en tu proyecto frontend es como buscar una aguja en un pajar de código, entonces el monitoreo de errores de Sentry puede ser tu detector de metales. Aprende los conceptos básicos del monitoreo de errores con Sentry. Ya sea que estés ejecutando un proyecto de React, Angular, Vue, o simplemente JavaScript “vainilla”, mira cómo Sentry puede ayudarte a encontrar el quién, qué, cuándo y dónde detrás de los errores en tu proyecto frontend.
Nivel de la masterclass: Intermedio
Usando Nitro - Construyendo una Aplicación con el Último Motor de Renderizado de Nuxt
Vue.js London Live 2021Vue.js London Live 2021
117 min
Usando Nitro - Construyendo una Aplicación con el Último Motor de Renderizado de Nuxt
Top Content
Workshop
Daniel Roe
Daniel Roe
Construiremos un proyecto Nuxt juntos desde cero usando Nitro, el nuevo motor de renderizado de Nuxt, y Nuxt Bridge. Exploraremos algunas de las formas en que puedes usar y desplegar Nitro, mientras construimos una aplicación juntos con algunas de las restricciones del mundo real que enfrentarías al desplegar una aplicación para tu empresa. En el camino, dispara tus preguntas hacia mí y haré lo mejor para responderlas.
Vue3: Desarrollo Moderno de Aplicaciones Frontend
Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Desarrollo Moderno de Aplicaciones Frontend
Top Content
Workshop
Mikhail Kuznetsov
Mikhail Kuznetsov
Vue3 fue lanzado a mediados de 2020. Además de muchas mejoras y optimizaciones, la principal característica que trae Vue3 es la API de Composición, una nueva forma de escribir y reutilizar código reactivo. Aprendamos más sobre cómo usar la API de Composición de manera eficiente.

Además de las características principales de Vue3, explicaremos ejemplos de cómo usar bibliotecas populares con Vue3.

Tabla de contenidos:
- Introducción a Vue3
- API de Composición
- Bibliotecas principales
- Ecosistema Vue3

Requisitos previos:
IDE de elección (Inellij o VSC) instalado
Nodejs + NPM
Embarcándonos en una aventura con Nuxt 3, Motion UI y Azure
JSNation 2022JSNation 2022
141 min
Embarcándonos en una aventura con Nuxt 3, Motion UI y Azure
Workshop
Melanie de Leeuw
Melanie de Leeuw
¡Nos encantan las aplicaciones web fáciles de crear y desplegar! Entonces, veamos qué puede hacer una pila tecnológica muy actual como Nuxt 3, Motion UI y Azure Static Web Apps. Podría ser perfectamente un trío de oro en el desarrollo web moderno. O podría ser una hoguera de errores y problemas. De cualquier manera, será una aventura de aprendizaje para todos nosotros. Nuxt 3 se lanzó hace apenas unos meses y no podemos esperar más para explorar sus nuevas características, como su compatibilidad con Vue 3 y el Motor Nitro. Agregamos un poco de estilo a nuestra aplicación con la biblioteca Sass Motion UI, porque el diseño estático está pasado de moda y las animaciones vuelven a estar de moda.Nuestra fuerza impulsora de la pila será Azure. Las aplicaciones web estáticas de Azure son nuevas, casi listas para producción y una forma ingeniosa y rápida para que los desarrolladores desplieguen sus sitios web. Así que, por supuesto, debemos probar esto.Con algunas Azure Functions esparcidas por encima, exploraremos lo que puede hacer el desarrollo web en 2022.
TresJS crea experiencias 3D de forma declarativa con componentes Vue
Vue.js London 2023Vue.js London 2023
137 min
TresJS crea experiencias 3D de forma declarativa con componentes Vue
Workshop
Alvaro Saburido
Alvaro Saburido
- Introducción a 3D- Introducción a WebGL- ThreeJS- Por qué TresJS- Instalación o configuración de Stackblitz- Conceptos básicos- Configuración del lienzo- Escena- Cámara- Agregar un objeto- Geometrías- Argumentos- Props- Slots- El bucle- Composable UseRenderLoop- Callbacks antes y después de la renderización- Animaciones básicas- Materiales- Material básico- Material normal- Material Toon- Material Lambert- Material estándar y físico- Metalness, roughness- Luces- Luz ambiental- Luz direccional- Luces puntuales- Sombras- Texturas- Cargar texturas con useTextures- Consejos y trucos- Misceláneo- Controles de órbita- Cargar modelos con Cientos- Depuración de tu escena- Rendimiento
Construyendo formularios Vue con VeeValidate
Vue.js London Live 2021Vue.js London Live 2021
176 min
Construyendo formularios Vue con VeeValidate
Workshop
Abdelrahman Awad
Abdelrahman Awad
En este masterclass, aprenderás cómo usar vee-validate para manejar la validación de formularios, gestionar los valores de los formularios y manejar las presentaciones de manera efectiva. Comenzaremos desde lo básico con un formulario de inicio de sesión simple hasta el uso de la API de composición y la construcción de formularios repetibles y de múltiples pasos.

Tabla de contenidos:
- Introducción a vee-validate
- Construcción de un formulario básico con componentes vee-validate
- Manejo de validación y presentaciones de formularios
- Construcción de componentes de entrada validables con la API de composición
- Arrays de campos e inputs repetibles
- Construcción de un formulario de múltiples pasos
Prerrequisitos:
Configuración de VSCode y un proyecto Vite + Vue vacío.