Cuanto más trabajas en una aplicación, más complicado se vuelve su enrutamiento y más fácil es cometer un error. "¿Se llamaba la ruta usuarios o usuario?", "¿Tenía un parámetro id o era userId?". Si solo TypeScript pudiera decirte cuáles son los nombres y parámetros posibles. Si solo no tuvieras que escribir una sola ruta más y dejar que un complemento lo haga por ti. En esta charla repasaremos lo que se necesitó para traer rutas automáticamente tipadas para Vue Router.
Deja de Escribir tus Rutas
Video Summary and Transcription
Diseñar APIs es un desafío y es importante considerar el lenguaje utilizado y las diferentes versiones de la API. La ergonomía de la API se centra en la facilidad de uso y los compromisos. El enrutamiento es un aspecto mal entendido del diseño de la API y el enrutamiento basado en archivos puede simplificarlo. Desconectar View Router proporciona rutas tipadas y elimina la necesidad de pasar rutas al crear el enrutador. La carga y manipulación de datos se pueden mejorar con cargadores de datos y rutas predecibles. También se discuten las rutas protegidas y los archivos de índice e ID.
1. Diseño de APIs: Desafíos y Consideraciones
Diseñar una API es realmente difícil. Es uno de los mayores desafíos de cualquier biblioteca de código abierto. Una buena API dificulta cometer errores y evita cambios de contexto. Es importante escribir diferentes versiones de una API y considerar el lenguaje utilizado. El proceso de aprendizaje de una API es subjetivo.
Así que sí, mi nombre es Eduardo. Buenos días, Londres. Feliz de estar aquí otro año. Como miembro de Querty pero también como desarrollador y amante del código abierto, he estado desarrollando muchas bibliotecas, casi durante siete años, creo. No solo PNIA y Vue Router, sino también algunas de las bibliotecas que son adyacentes a Vue en sí. Y he estado dedicando mucho tiempo a pensar cómo diseñar las APIs para estas bibliotecas. A veces, cometiendo errores, mejorándolos después, por supuesto. Pero lo más importante es que diseñar una API es realmente difícil, ¿vale? Y creo que no hace falta decir que este es uno de los mayores desafíos de cualquier biblioteca de código abierto porque tienes que tener en cuenta muchos factores diferentes. Desde cómo cambia esta API, espera, lo siento, necesito cambiar la cosa. Esto va a ser doloroso. Vale. Así que tienes que tener en cuenta muchos factores diferentes, desde, espera, mi software se rompió aquí y pienso, ¿cómo lo hago? Vale, tengo que hacer todo de memoria. Dios, no tengo ninguna nota cuando, se supone que debemos tener notas, muy difícil. Así que tienes que tener en cuenta muchos factores diferentes. ¿Vas a tener en cuenta a los usuarios que tienes? ¿Estás construyendo una nueva API? ¿No estás construyendo una nueva API? Y cómo se siente la API para los usuarios, porque al final, una API buena o mala es muy subjetiva. Y te voy a mostrar por qué. Así que una de las cosas que considero muy importante en una buena API es que sea difícil cometer errores. Ahora, puede ser obvio para algunos y completamente nuevo para otros, pero si usas una biblioteca donde cometer errores es fácil, te hace sentir tonto. Ahora, a nadie le gusta sentirse tonto cuando está usando algo, ¿verdad? Así que definitivamente es un factor importante en mi opinión de cómo puede ser buena o no una API. Otro gran aspecto es evitar el cambio de contexto. Ahora, cuando pensamos en las APIs, primero pensamos en el código que necesitamos escribir. Pero si la API real va más allá del código que escribimos, no solo los archivos, la carpeta que tenemos, sino que también podemos pensar en muchas otras cosas que forman parte de la API porque cuando escribimos código, cuando desarrollamos un programa, no solo estamos escribiendo código en sí. Y luego tenemos que adaptarlo a diferentes experiencias de usuario.
Ahora, esto es muy vago, para ser honesto, pero no es lo mismo escribir una V1 de una API, donde solo tienes nuevos usuarios, que escribir una V2 de una API donde tienes usuarios existentes que están acostumbrados a algo. También tienes que pensar en qué lenguaje estás escribiendo, no es lo mismo escribir una API en Java o Rust que en JavaScript o TypeScript, donde las cosas evolucionan muy rápido. Y me gusta referirme a esta pequeña broma, la curva de aprendizaje del usuario. Entonces, lo que sucede es nuestra experiencia al aprender algo, que también es parte de una API, el proceso de aprendizaje es diferente y es subjetivo. Así que, la broma
2. Diferentes Herramientas y Ergonomía de API
Diferentes herramientas tienen diferentes niveles de eficiencia y productividad. Notepad es rápido pero no eficiente. Pico permite más funcionalidad. Visual Studio tiene muchos atajos pero puede disminuir la productividad. Vee, Veeam y Nveam requieren aprendizaje pero resultan en alta productividad. Emacs y Spacemacs son herramientas poderosas. Esto forma la base de la ergonomía de la API.
3. API Ergonomics and Erasing APIs
La ergonomía de la API se trata de qué tan a menudo y qué tan fácil es usar una función. No es lineal, pero se requieren compensaciones. Las funciones comunes deben ser fáciles de lograr y recordar. Hoy, exploraré cómo borrar una API y me enfocaré en mantener las cosas juntas, reducir la repetición y mejorar la experiencia de desarrollo. El enrutador es un buen lugar para hacer esto, ya que el enrutamiento es ampliamente mal entendido.
4. Challenges of Routing and File-based Routing
Múltiples formas de analizar las URL, diferentes eventos y próximas API, y los desafíos del enrutamiento en una aplicación. Comportamiento propenso a errores y la necesidad de simplificación. El enrutamiento basado en archivos como solución.
5. Enrutamiento basado en campos y manejo de errores
Nuxt elimina por completo la creación del enrutador, abogando por reducir la repetición de código manteniendo la flexibilidad. El enrutamiento basado en campos proporciona un mapeo predecible y elimina la necesidad de aprender múltiples veces. Las herramientas pueden generar código de unión, lo que permite a los desarrolladores centrarse en la parte interesante. Los tipos y errores son cruciales, buscando errores precisos en lugar de genéricos. Los tipos en tiempo de ejecución y las cadenas literales pueden transformar objetos en tipos reales. Generar parámetros para cada ruta puede ser lento y dar como resultado un código ilegible.
Entonces, cuando tenemos enrutamiento basado en campos, lo que tenemos y lo que es muy importante es que tenemos un mapeo predecible uno a uno. Sabemos y tenemos algunas reglas que tal vez aprendamos una vez. Sabemos que index.view, index.HTML simplemente se convierte en una barra al final. Y sabemos que incluso tenemos los corchetes, se convierte en un parámetro. Y lo bueno es que porque esto está justo al lado tuyo en tus archivos, en tu editor, ves esto todos los días. Entonces, realmente no necesitas aprender esto varias veces, ¿de acuerdo? Lo aprendes una vez y luego lo tienes en tu cabeza, está ahí. Y debido a que tenemos un mapeo uno a uno, podemos dejar que todas las herramientas generen el código de unión para que podamos escribir solo la parte interesante, idealmente.
Ahora, esto incluye los registros de ruta y las importaciones, que es algo así como un código repetitivo. Pero también podemos tener tipos que podríamos escribir manualmente pero vamos a generarlos automáticamente, por lo que siempre son correctos. Y también, otros metadatos de ruta y otras cosas que son código más allá de eso. Entonces, la idea aquí es que queremos obtener un error si escribimos algo como esto. Y no queremos el clásico error de TypeScript que dice que una cadena no se puede asignar a un tipo A. Luego tienes tres puntos que ni siquiera puedes hacer clic. Y luego, obtienes algo como que nunca se puede asignar a una cadena. Y ni siquiera sabes qué sucedió en el medio. Idealmente, quieres un error preciso que te diga, oye, este objeto no tiene la propiedad ID, ¿verdad? Este nombre no existe. Esta condición no es posible. Entonces, estos son tipos y errores, ¿de acuerdo? Este parámetro 'other' no existe para esta ruta porque verificamos que el nombre es ID, por lo que la forma del parámetro es un objeto con un ID. Y así, inicialmente, quería hacer esto con tipos en tiempo de ejecución, que es una característica muy interesante de TypeScript. Entonces, tenemos lo que llamamos cadenas literales que realmente podemos analizar y podemos transformar objetos en tipos reales. Todo esto funciona, ¿de acuerdo? Y lo hice... Entonces, lo bueno es que solo necesitas tomar tu matriz de rutas, poner esto como constante al final, y luego puedes generar un objeto que contenga todos los parámetros para cada ruta con nombre. Ahora, el problema es que esto es realmente lento. Y me llevó un tiempo probarlo porque cuando comencé a hacerlo, comienzas con unas pocas rutas. Pero luego, cuando llego a 50, me doy cuenta de que no logro nada más que hacer que el servidor de TypeScript se bloquee, lo cual puede ser un logro en sí mismo, pero no es lo que quiero en mi vida diaria de desarrollo. Y además de eso, tengo
6. Desconectando View Router: Conceptos básicos y Rutas tipadas
He escrito muchos lenguajes como C y Prolog, pero nada se compara con este código. Me di cuenta de que tenía que volver a lo básico y crear un tipo que asocie una ruta a tipos. Desconectando View Router es una biblioteca que funciona con diferentes herramientas y proporciona rutas tipadas. Ya no es necesario pasar la ruta al crear el enrutador.
7. Rutas tipadas y Configuración de Rutas
Puedes modificar las rutas en tiempo de ejecución o en tiempo de compilación. Al pasar parámetros, puedes tipar de forma segura las rutas y ver errores en tu editor. Al usar useRoute, puedes especificar la ruta específica para una página. La forma en que funciona es generando un archivo DTS de tipo de ruta que te permite configurar mapas de nombres de ruta y anulaciones para tu enrutador y funciones.
8. Mejora de las APIs: Carga y Manejo de Datos
La versión que permite pasar un argumento tiene autocompletado. La forma en que funciona es generando un gran archivo DTS de tipo de ruta que puedes configurar. La clave es no comprometer la flexibilidad al hacer tareas comunes más fáciles. La macro de página definida permite pasar propiedades para la configuración de la ruta. La carga de datos es un tema importante con diferentes opciones de manejo. La observación de los parámetros carece de estado, errores y manejo de SSR. Los guardias de navegación se duplican y se vuelven verbosos. Los guardias de navegación globales ofrecen una solución conveniente. El suspense en la superficie es perfecto, pero tiene algunos problemas de manejo de errores y manejo de SSR.
Así que aquí está la macro de página definida, que, bueno, sé que estamos haciendo muchas macros aquí, definir, definir, definir algo, así que solo otra para recordar, pero la idea es que puedes pasar todas las propiedades que estás usando en la configuración de la ruta, en las rutas La diferencia es que estamos en la página, por lo que no hay cambio de contexto, nos quedamos en el mismo componente, estamos definiendo cosas. Y podemos agregar lo que queramos. También podemos tener bloques JSON, o Yaml, u otras cosas si quieres. Y lo bueno es que porque esto va a afectar a los tipos reales, si lo cambias aquí, así que voy a definir la página y cambiar el nombre de esta ruta a otra cosa. Así que estoy cambiando mi propio nombre aquí, voy a guardar, y voy a obtener un error aquí porque este nombre ya no existe. Así que obtienes retroalimentación instantánea así, y luego lo cambio solo para que coincida. De acuerdo, cerrando ese capítulo, hay otras cosas que podemos hacer para mejorar las APIs. Una de ellas es la carga de datos. Ahora, la carga de datos es un tema importante. Pero hoy en día tenemos diferentes formas de manejarlo, y esta es, en mi opinión, una de las razones por las que no es una gran API en este momento. O si hay una API, si no hay una API única. Así que tenemos diferentes formas de hacerlo. Tenemos observación de los parámetros, pero no tenemos estado, no errores, no manejo de SSR. Tenemos todos los guardias de navegación, pero se duplican, y pueden ser verbosos, y definitivamente no están tipados, excepto con el complemento, por supuesto. Luego tenemos guardias de navegación globales, que te permiten crear una solución personalizada de data, y diría que esta es la solución más conveniente. Y luego tenemos suspenser weight, para los cuales tengo una diapositiva completa de todos modos. Pero todos tienen problemas. Todos presentan algunos problemas que no nos permiten usarlos como solución de obtención de data. Así que el suspense en la superficie es simplemente perfecto. Simplemente ponemos un peso en el script. No hay nada tan simple como eso. Y tiene algunas ventajas, como que es muy sencillo de escribir, el más sencillo de escribir,
9. Introducción a los Cargadores de Datos
Los cargadores de datos son funciones que devuelven datos y te proporcionan una composición. Proporcionan acceso a datos, estado de carga, errores y manejan SSR. Exportar cargadores permite reutilizarlos y evitar duplicar solicitudes. Los cargadores pueden tener tipos por defecto y se pueden exportar varios cargadores.
10. Rutas Predecibles y Menos Código Repetitivo
Creamos rutas predecibles con enrutamiento basado en fallos, lo que permite que nuestra herramienta genere tipos automáticamente. Esto crea un entorno con menos propensión a errores y menos código repetitivo, sin necesidad de cambiar de contexto. Consulta las diapositivas en esm.eslash para obtener más información.
QnA
Manejo de Rutas de Tipo y Rutas Protegidas
Puedes usar rutas de tipo sin enrutamiento basado en archivos, pero requiere trabajo manual y es menos propenso a errores. El complemento no admite Vue 2. El manejo de rutas protegidas con enrutamiento basado en archivos implica crear una guarda de navegación o usar Metafields. La funcionalidad de desenchufar ViewRouter puede convertirse en parte de u-router como un complemento separado. Los cargadores se pueden definir en un archivo separado e importarse en varios componentes.
Muchas gracias, Eduardo. Eso fue extremadamente interesante. Y me encanta el design de tus diapositivas. Son súper atractivas. Ok. Así que, veamos las preguntas. Pero antes de la primera de todos, ¿se pueden usar rutas de tipo sin enrutamiento basado en archivos?
Entonces, se pueden usar las rutas de tipo sin enrutamiento basado en archivos, pero la idea es que estás separando la generación de los tipos y la escritura de las rutas, por lo que tienes que hacer algo de trabajo manual, mientras que el objetivo principal de este enfoque es que los tipos sean automáticos y no tengas que preocuparte por ello, por lo que es menos probable que cometas errores, es menos propenso a errores.
Ok, tiene mucho sentido.
Ok, veamos qué tenemos aquí, ¿este complemento admite Vue 2?
Vue 2? No, no hay soporte para Vue 2 porque los tipos en el enrutador son bastante diferentes, por lo que sería un gran, es principalmente una cuestión de tiempo, simplemente no tengo suficiente tiempo para hacer que admita Vue 2 en este momento.
Ok, tal vez en el futuro o? Incluso, dudo que pueda encontrar el tiempo para hacerlo en el futuro, pero invito a cualquiera a copiar el código y bifurcarlo para Vrouter 2, definitivamente.
Ok, lo has escuchado, una oportunidad de código abierto.
Luego, la siguiente pregunta, ¿cómo debemos manejar las rutas protegidas con enrutamiento basado en archivos?
Entonces, las rutas protegidas, por lo general, creas una guarda de navegación, por lo que aún crearías tu propia guarda de navegación, de la misma manera. Tienes la instancia del enrutador en algún lugar, por lo que simplemente router.beforeEach o router.beforeResolve. Hay otros patterns que puedes usar con Metafields, puedes definir Metafields en las rutas, lo que te permite tener guardas de navegación bastante precisas aplicadas a múltiples rutas. Por lo tanto, una sola guarda de navegación que se aplica en varias páginas.
Ok, genial. Creo que es un poco más difícil de explicar sin código.
Genial, tiene sentido.
La siguiente pregunta es, ¿hay alguna posibilidad de que la funcionalidad de desenchufar ViewRouter se integre en Sí, probablemente lo hagamos, pero para hacerlo primero tenemos que pasar por un RFC. La diferencia es que no es, quiero decir, la mayor parte del código no es runtime, ¿verdad? La mayor parte del código está construido. Por lo tanto, seguirá siendo algo que estará un poco aparte, por lo que si se convierte en parte de u-router, seguirá siendo como un complemento vid que se expone a través de una ruta diferente como u-router slash plugin o algo así.
Ok, genial.
La siguiente pregunta es, ¿se pueden definir cargadores en un archivo separado y luego importarlo en varios componentes?
Sí, solo necesitas exportar el cargador desde la página para indicarle al enrutador que esta página está utilizando ese cargador. Eso es todo. Y luego puedes usar el composable en cualquier lugar. Entonces, primero debes importar el cargador y luego exportar esa importación?
Sí, también puedes hacer solo export. No lo mencioné, pero tienes dos scripts, tienes el script regular y luego el script de configuración. Entonces, en el script regular, es donde puedes exportar cosas, y es donde puedes simplemente hacer export algo de algo más o puedes importarlo y luego exportarlo porque aún necesitarás importarlo en la configuración si no lo importas en el otro script. El editor facilita mucho obtener el comportamiento correcto porque simplemente autocompleta.
Ok, tiene mucho sentido.
Manejo de Archivos Index e ID
El número de archivos index.vue e id.vue depende de las rutas y cómo se busquen. Si tienes rutas con la misma ruta común pero nombres diferentes, aún puedes encontrar los archivos fácilmente utilizando la estructura de carpetas. Es como los nodos en un árbol, donde las hojas pueden verse similares, pero los nodos no lo son.
Y la última pregunta es, ¿terminaremos con docenas de archivos index.vue e id.vue? ¿Cuándo? ¿O no, terminaremos con docenas de archivos index.vue e id.vue? Sí, probablemente, pero no necesariamente. Depende si tienes otras rutas que tienen la misma ruta común, pero aún buscas la ruta por otro nombre. Si tienes una página de usuarios y un usuario slash nuevo, tienes un usuario slash index y un usuario slash nuevo.vue. Entonces, cuando buscas los archivos, buscas users index, o probablemente uses mi espacio de usuario, lo siento. Cuando haces Control-P en tu VSCode, aún encontrarás tu camino fácilmente, porque aún tienes la estructura de carpetas que prevalece. OK, sí. Es más como nodos en un árbol en comparación con las hojas. Entonces, las hojas se ven similares entre sí, pero los nodos no lo son. OK, perfecto. Muchas gracias, Eduardo. Y siéntete libre de hacer más preguntas en la parte de preguntas y respuestas de los oradores. Y sí, denos un poco de aplausos.