This graph shows how many times the word ______ has been mentioned throughout the history of the program.
Hoy vamos a empezar con DinoFresh. ¿Qué es DinoFresh? ¿Para qué sirve DinoFresh?
Bueno, DinoFresh es seguramente el framework más prometedor que tenemos ahora mismo entre manos
y una de las mayores, mejores y más interesantes alternativas a Next.js.
Y vas a ver por qué es una alternativa y por qué es tan interesante.
DinoFresh, como dice su nombre y como te puedes imaginar, obviamente,
tiene mucho que ver con Dino y poco con Node.
Y además tienes, por eso, la posibilidad de utilizar TypeScript sin instalar absolutamente nada
y además también tienes soporte a JSX, nativo.
¿Esto qué quiere decir? Pues lo que quiere decir es que sin ningún tipo de compilación
DinoFresh va a poder servir cualquier página web, lo cual es espectacular.
¿Qué más tiene? Hace el renderizado al vuelo.
Esto significa que tú haces la petición, lo renderiza al vuelo y te lo devuelve.
Tiene el sistema de arquitecturas de islas, que lo vamos a ver luego en detalle.
Tienes cero runtime porque por defecto es todo estático.
Sería algo parecido a los React Server Components.
O sea, que no envía JavaScript a no ser que lo necesites.
Y luego, también lo que tenemos es que utiliza Preac.
Esto es un poquito especial, pero no te preocupes.
Preac y React son muy parecidos.
Preac, para que lo sepas, es una alternativa muy liviana y muy pequeñita a React.
Ocupa muy poquito, tiene una API muy parecida y lo vas a ver.
Que ahora, cuando estemos trabajando con ello, no vas a notar ningún tipo de diferencia.
Pero, ¿por qué deberías aprender DinoFresh?
¿Qué es lo que lo va a hacer realmente interesante?
Pues con todo esto que estábamos comentando, ya te habrás dado cuenta.
El hecho de que no tenga compilación, vas a conseguir tener despliegues a producción en cero segundos.
En cero segundos, ¿tú te imaginas desplegar una aplicación y ver los cambios inmediatamente en producción?
Pues eso lo vas a poder conseguir con DinoFresh.
Y hoy lo vamos a ver.
Porque vamos a ver cómo hacer el despliegue de nuestro proyecto.
Y vamos a ver justamente dónde lo vamos a hacer, en qué hosting lo vamos a hacer.
Totalmente gratis, súper rápido, con cero segundos casi de delay.
O sea, impresionante.
Lo vamos a hacer con DinoDeploy.
Esto que tenemos por aquí.
DinoDeploy cuesta 10 dólares al mes si haces más de 100.000 requests al día.
Yo creo que si haces un portfolio, un blog o lo que sea, yo creo que lo tienes bien.
Así que vamos a empezar con un poquito de DinoFresh.
Vamos a empezar con este proyectito.
Ah, y una cosa también muy importante.
También tiene soporte desde cero, DinoFresh, a algo muy parecido a Tailwind.
Se llama Tailwind.
No es Tailwind exactamente, pero es muy parecido y te va a servir casi, casi, casi igual.
Casi igual.
Así que ahí lo tenemos.
Venga, vamos a empezar.
Y para empezar, podríamos empezar con DinoFresh.
Yo voy a poner aquí DinoBlock.
Le voy a llamar DinoBlock.
Porque vamos a hacer un blog y vais a ver cómo lo vamos a ir haciendo cada vez un poquito más complejo y tal.
Y con el DinoBlock lo que quiero es empezar como de cero y luego ejecutaremos DinoFresh encima.
Pero lo que quiero enseñarte es un poco cómo funciona Dino, cómo lo puedes instalar, porque necesita Dino.
¿Por qué necesita Dino?
Porque no utiliza Node esto.
Utiliza esta alternativa que se llama Dino, que es del mismo creador de Node y que tiene un montón de ventajas,
como he comentado, lo de TypeScript, lo de JSX y también que apuesta mucho por utilizar la plataforma web.
O sea, que puedes utilizar el local storage, puedes utilizar un montón de APIs de la web.
Eso es una de las cosas más interesantes de Dino, porque resulta que muchas de las cosas que vas a aprender con Dino,
las vas a poder utilizar no solo en cualquier web, en cualquier programación web que quieras hacer,
sino con BAN, por ejemplo, o en otros runtimes que se apuestan mucho por la plataforma web.
Así que lo primero que necesitamos es tener instalado Dino.
Dependerá del sistema operativo, ¿vale?
Yo en mi caso tengo Macos, así que yo debería utilizar este o podría utilizar el de Brew, este también.
En mi caso voy a utilizar este, aunque no me acuerdo si había instalado con Brew anteriormente.
Voy a ejecutar este a ver si funciona y ahora veremos si se ha estado correctamente.
Si utilizas Windows, si utilizas otra cosa, pues ten en cuenta aquí que tienes todas las diferentes instrucciones.
Vamos a poner DinoVersion, que me dice, ¿vale?
Y dice que tengo la versión 1.29.1, que creo que debe ser la última.
Ahora que ya se ha instalado Dino, ¿qué es lo que podríamos hacer?
Bueno, ya he creado aquí un proyecto.
Vamos a empezar, vamos a abrirlo por acá.
Y voy a crear un fichero.
Le voy a llamar main.tis.
Y ahora aquí podríamos poner console.log.
Esto es Dino, que se pronuncia Dino, ¿vale?
Pero le vamos a poner Dino aquí.
Y ahora, abriendo la terminal, podríamos ejecutar justamente este fichero.
¿Cómo lo ejecutamos?
Pues deberíamos ponerle Dino main.ts o Dino run main.ts.
¿Ves? Y ya tenemos este console.log.
O sea, con esto ya lo tendríamos instalado perfectamente.
Hay una cosa muy interesante de Dino, antes de continuar, para que más o menos lo tengas en cuenta,
y es que Dino es seguro por defecto.
Esto es algo totalmente diferente a cómo funciona Node.
¿Por qué?
Porque Node, tú cuando escribes Node.index.js, Node por defecto, no tiene ninguna seguridad
y por lo tanto puedes escribir y leer ficheros del disco, puedes hacer peticiones a la red,
o sea, que tienes acceso a internet, tienes, digamos, total acceso a todos los recursos del ordenador.
En cambio, Dino no es tan así.
Si tú quieres, por ejemplo, vamos a intentar hacer aquí un fetch, ¿vale?
Vamos a poner midudev.
Creo que esto no debería funcionar y debería quejarse, ¿vale?
Fíjate, ¿ves?
Nos dice, oye, que Dino me está pidiendo acceso a midudev.
¿Crees que deberíamos ejecutar de nuevo este comando, pero dándole acceso a internet?
¿Vale?
Así que ya puedes ver que es como seguro por defecto,
porque nos está evitando que nuestro código o cualquier dependencia que tengamos,
pues puede hacer una petición sin ningún tipo de seguridad,
sino que simplemente importamos una dependencia y va y se pone a hacer cosas, ¿no?
Pues bueno, en este caso ya vemos que es seguro por defecto.
Esto es muy importante que lo sepamos,
porque en Fresh vamos a necesitar pasarle estos parámetros para que funcione correctamente.
Así que esto sería una pequeña introducción, muy rápida obviamente,
de cómo funciona Dino,
pero hay otra cosa muy importante de Dino que marca la diferencia
y voy a crearme aquí una carpeta, le voy a llamar VS Code.
Vamos a poner por aquí, la carpeta.
Vamos a poner VS Code.
Y es que hay un tema muy interesante con Dino.
Y es que Dino tiene tanto un linter como un formateador por defecto.
Así que vamos a tener aquí en el Settings, este,
vamos a poner que en el Settings de este Workspace,
no sé si lo sabías, pero esto es súper útil,
que puedes tener una carpeta VS Code y puedes poner un Settings.json.
Y esto sería una configuración para tu editor Visual Studio Code
que solo va a funcionar en este proyecto.
O sea, que tú puedes tener configuraciones a nivel de proyecto.
Y aquí lo que vamos a decir es, vamos a activar Dino,
vamos a ponerlo aquí a True,
y vamos a poner Dino, Lint y lo vamos a poner a True.
Ahora, para que esto funcione, obviamente,
te tienes que asegurar que las extensiones
tengan la extensión de Dino activada.
Yo en este caso, ¿ves? La tengo desactivada,
lo cual te recomiendo que hagas si no lo vas a utilizar.
Creo que puedes hacer que te la instalas y la desactivas,
pero luego la activas a nivel de Workspace.
Luego verás que esto lo voy a hacer también con un archivo
para que lo vean más claro,
pero ahora lo dejamos así, ¿vale?
Hacemos un Enable Workspace y ya está.
Y además, luego también, si no me equivoco,
a la hora de formatear, bueno, luego lo miro,
pero creo que aquí podríamos poner TypeScript,
dos puntos, no, no es así, es con, entre comillas,
para que el formateador funcione,
tendríamos que poner esto, ¿vale?
Le tendríamos que decir Dino Lint, Visual Score,
no sé qué, no sé cuánto.
Vale, dice que ese valor no es válido,
pero me parece que es porque estaba desactivado antes
y ahora no.
Aquí lo que tenéis que poner es el nombre de la extensión.
Si hago esto, ¿vale?
Ahora no me lo está formateando.
Voy a cerrar el Visual Studio Code.
Voy a cerrarlo, no sé si cerrarlo así.
Vamos a cerrarlo así.
Vamos a volver a abrirlo así.
Vale.
Y a ver si ahora funciona.
Tampoco funciona.
Pues igual es que el formateador este,
hola, he liado.
Pero esto debería formateármelo, ¿eh?
Igual se me ha olvidado.
Vamos a poner Editor, Default, Formatter.
Vamos a poner, ¿ves?
Ahora sí que me sale por aquí.
No sé si lo he puesto bien.
Bueno, debería haberlo dicho.
Ah, igual no tengo lo de Format on Save este.
True.
Vamos a probar.
Ahora sí, ¿vale?
Es que no tenía la configuración de formatear al guardar, ¿vale?
Pero, bueno, lo podéis hacer de diferentes formas.
Esto lo podéis poner a false, que es como lo tenía.
Y podéis buscar el comando y poner el formato, lo que queráis.
Pero lo interesante es que ya habéis visto que sin instalar dependencias a nivel de Dino,
tenemos tanto el inter, que lo vais a ver aquí, ¿ves?
Tenemos como un slint ya que viene de serie,
como un formateador que cuando tú guardes,
si lo ponemos aquí a true, cuando nos guarde, nos va a formatear el código.
O sea, no necesitas ni slint, ni pretter, ni nada de esto.
Así que, para que veas cómo de interesante es esto.
Vale, pues ahora que ya tenemos esto,
vamos a hacer una cosa.
Oye, espérate.
Vamos.
¿Hasta aquí todo bien?
¿Todo bien?
No os habéis perdido.
Vamos justamente con esto de iniciar el proyecto, ¿vale?
Habíamos dicho que habíamos hecho esto,
pero queremos utilizar DinoFresh.
¿Cómo tenemos que utilizar DinoFresh?
Pues tenemos que ejecutar un comando.
Para ejecutar el comando, vamos otra vez a la terminal,
vamos a limpiar la terminal y le decimos,
el comando es DinoRan menos A mayúscula,
que esto significa que le vamos a dar acceso a todos los recursos,
o sea, a internet, al disco y todo esto.
Y le decimos que lo que tiene que ejecutar es el script
que tenemos aquí en fresh.dino.dev.
¿Y dónde lo debe ejecutar?
En punto, o sea, en la carpeta actual en la que estamos.
Esto sería como para inicializar nuestro proyecto, ¿vale?
Y el A sería que le damos acceso a todos los recursos.
Y con esto le damos a punto,
se descarga todas las dependencias que necesita,
ya nos dice fresh, Next Gen Web Framework.
Nos dice que el directorio donde queremos inicializar el proyecto
no está vacío, le decimos que no nos importa,
porque va a sobreescribir lo que hemos hecho aquí,
que tampoco es mucho, le decimos que sí.
Dice que Fresh tiene soporte para Tailwind CSS.
Si lo queremos utilizar, le vamos a decir que sí,
que nos va a facilitar la vida.
Que sí, que utilizamos Visual Studio Code.
Y ya está.
Bueno, fijaos que ahora ha cambiado bastante la cosa.
Ya nos ha puesto aquí un montón de ficheros,
que no está nada mal.
Y vamos a ver qué nos ha hecho y por qué nos ha hecho esto.
Vamos a cerrar todo esto.
Vamos a ver qué nos ha quedado por aquí, ¿vale?
Y le echamos un vistazo para que lo veamos paso a paso.
Lo primero que tenemos que ver es el dino.json.
Sería como el Package.json que tenemos en Node,
pero para dino.
Y ya tenemos en task, estos serían como los scripts, ¿vale?
Del Package.json.
Y tenemos uno que nos permite inicializar nuestro proyecto,
que es el que utilizaremos después.
Fíjate que en lugar de tener dependencias,
lo que tenemos es una cosa que se llama Import Map.
Esto es súper importante porque es un concepto
que vamos a utilizar el día de mañana,
también en las páginas web que hacemos con JavaScript sin frameworks,
que es muy interesante.
Y esto lo que es, es que le podemos decir
dónde van a estar nuestras dependencias a partir de una URL.
Porque como no necesitamos utilizar npm,
en dino podemos hacer un import de una URL directamente.
Lo veremos también en el curso, ¿vale?
Y luego algunas opciones del compilador de TypeScript,
que básicamente lo que estamos diciendo es que tiene que soportar JSX,
pero que a la hora de importar JSX lo que hacemos es utilizar PRIAC.
Porque DinoFresh utiliza PRIAC en lugar de RIAC.
Aunque se parecen muchos y no lo vas a echar en falta.
Ya verás como no lo echas ni en falta, ¿vale?
Venga, ahora, revisando más cosas del JSON.
Tenemos el settings.json muy parecido al que habéis visto antes,
aunque le faltan las opciones que yo había puesto,
así que vamos a poner algunas.
Esto depende de cada uno.
Yo, por ejemplo, le voy a cambiar, ¿por qué?
Porque si no seguramente me va a intentar pillar las opciones
que ya tengo en mi configuración.
Así que lo que le voy a decir es que tanto para TypeScript
como para RIAC, JavaScript RIAC, como para TypeScript RIAC,
quiero que me utilice el formateador de Dino, ¿vale?
Para que me formatee el código con el de Dino
y que no intente Preacher ni nada de esto.
Así que, vale, aquí no sé por qué me había puesto esto sin guardar
porque yo no he hecho ningún cambio aquí, que yo sepa.
¿Vale?
Vale.
Así que estos eran los settings de Visual Studio Code
para nuestro proyecto.
Y aquí a Extensions tendríamos las extensiones recomendadas.
Esto es algo que es totalmente ajeno a Dino
y que te recomiendo muchísimo.
Y es que si tú tienes un proyecto
que sabes que necesita ciertas extensiones
para que funcione el proyecto bien,
creas un archivo .biscode.extensions.json
y haces esto, recomendaciones, Dino, no sé qué,
y aquí le pones el nombre de la extensión.
¿Por qué?
Porque cuando alguien inicie ese proyecto,
le aparecerá, oye, ¿quieres instalar las extensiones recomendadas?
Y la aparecerá automáticamente, ¿vale?
En este caso yo creo que igual las tengo ya instaladas, ¿vale?
¿Ves? Ya están instaladas, las dos.
Entonces no aparecía.
Para saber cuál es la que tendrías,
de dónde sale este nombre,
este nombre de aquí,
¿ves este nombre de aquí?
Porque alguien puede decir, ¿de dónde sale este nombre?
Este es el ID de la extensión
y te lo puedes copiar de aquí.
Le das aquí, Copy Extension ID,
y entonces lo añades aquí,
y ya está, ¿vale?
Por si tenías dudas de cómo hacerlo.
Pero muy buena idea tenerlo en proyectos,
y esto es un archivo que te recomiendo incluso
que subas a tu código en GitHub.
¿Por qué?
Porque así cualquier persona que se descargue el proyecto
va a tener estas recomendaciones.
Más cositas.
Ya hemos visto en la carpeta Visuals Code,
pero vamos a ver un poco cómo está
toda la estructura de carpetas.
Tenemos en Components,
componentes, como os podéis imaginar.
En Islands tenemos unos componentes especiales
que lo que significa es que son interactivos,
que esto también lo vamos a ver a lo largo del curso.
No te preocupes si ahora mismo no lo entiendes,
porque luego con un ejemplo lo verás clarísimo.
Pero básicamente,
todo lo que haces en Dino Fresh,
por defecto, es estático.
O sea, quiere decir,
que no se renderiza en el cliente,
sino que se renderiza en el servidor.
Esto es algo que está muy de moda,
y que poco a poco lo vamos a ir viendo
cada vez más en más frameworks,
pero que es muy interesante.
Y en el caso de Dino,
lo que hace es que tú tienes que crear en las islas
los componentes que son interactivos.
Así que luego lo tendremos en cuenta
y veremos cómo funciona.
En rutas, tendríamos las rutas.
Utilizan un enrutado similar,
si lo conoces, a Next.js,
que tenemos dentro de rutas,
tendríamos APIs,
tendríamos también rutas.
Aquí en cada fichero que tengamos aquí,
vamos a tener una ruta.
Vale, fijaos aquí que me está diciendo
este Relative, Import Path, no sé qué.
Esto, estos errores que veis aquí,
normalmente es por culpa
de que no ha pillado bien la extensión.
Si os aparece esto,
voy a ver si en Dino,
si tengo Dino,
tengo la extensión activada.
Vale, porque me sale aquí...
Le voy a dar Enable otra vez.
Vale, ¿veis que me sale en rojo?
Es un poco raro.
Si cierro y normalmente vuelvo a abrir,
me debería pillar correctamente eso
y no me debería dar a salir esos errores.
Vamos a ver.
Vale, ahora sí que me ha pillado aquí el TypeScript.
Vale, ahora sí.
Entonces, si os salen esos errores,
no os asustéis,
porque quiere decir que no ha pillado bien
la extensión de Dino
y no ha entendido muy bien
que el archivo que quieres tocar
es con Dino Fresh.
Pero veis que he cerrado el editor,
lo he vuelto a meter y ya está.
¿Por qué?
Porque no utiliza React
y por eso se hace un poco un lío
y se lía y te salen esos errores.
Pero bueno,
con esto ya lo tendríamos solucionado.
Más allá de esto,
tenemos una carpeta
para los archivos estáticos
y cosas interesantes.
Dev sería el punto de entrada
en nuestra aplicación
para cuando estamos en modo desarrollo
y Main sería el punto de entrada
en producción.
Así que ten en cuenta
que estos son dos archivos
que ya están generados
y normalmente no los vas a tener que tocar.
Pero cuando despleguemos
nuestra aplicación,
le vamos a tener que decir
que nuestro punto de entrada
es Main.ts.
Luego lo vamos a ver, ¿vale?
Y entonces lo tendrás más claro.
Pero que tengas en cuenta
que el Main.ts
es el punto de entrada
en nuestra aplicación
en producción
y el de Dev
en modo desarrollo.
¿Y qué más nos faltaría?
Bueno, Fresh Gen.
El Fresh Gen este,
este es un archivo
que es como el manifiesto
que también se genera,
que no lo tienes que editar,
pero es para que sepas
que aquí, digamos,
que es donde automáticamente
Dino Fresh va a meter
donde tienes todas las rutas,
todas las dependencias
y todo esto.
Pero lo bueno es que
esto te lo genera
justamente para no tener
que luego compilarlo
en tiempo de despliega-producción.
O sea, lo hace bastante interesante.
Y luego,
este import map
que te decía,
esto es muy interesante
porque esto no tiene
no tiene nada que ver
con Dino.
Esto en realidad
es algo que es de
tecnologías web.
A ver, voy a quitar el...
Hay gente que dice
que se está petando el stream.
Voy a quitar cosas
a ver si así funciona mejor.
Vale.
Pues el import map
no tiene nada que ver
con Dino en realidad.
Esto es algo
que es de tecnologías web,
es algo de la plataforma web.
Y eso es lo que lo hace
muy interesante
porque si aprendéis esto,
esto el día de mañana
lo vamos a tener que utilizar
en nuestras webs.
¿Por qué?
Esto lo que le decimos
es que cuando tú hagas
un import en JavaScript,
import lo que sea,
from,
y tú aquí le pongas
por ejemplo,
priak,
lo que le estás diciendo
es cuando tú pongas aquí
priak,
entonces ve a buscarlo aquí.
Es básicamente esto.
¿Vale?
Es como un mapa.
Es que es import map,
es que es un nombre perfecto
porque es que es justamente
lo que tiene que...
lo que hace, ¿vale?
Un mapa de importación.
Vale.
Pues creo que ya te he comentado
todos los ficheros.
O sea, que yo creo que ya
con esto podemos seguir.
Ya he explicado la estructura
de un poco de carpetas.
Vamos a iniciar el proyecto.
Vamos a poner
dino task start.
¿Vale?
Para inicializar cualquier proyecto,
vale, no se ve.
Os lo voy a poner...
Espérate.
Vamos a poner esto más para aquí.
A ver si...
dino task start.
¿Vale?
Este sería el comando
para inicializar nuestro proyecto.
Le damos a enter.
¿Vale?
Ya nos dice que está
escuchando en el puerto 8000.
Nos dice que ha generado
tres rutas y una isla.
Nos vamos al puerto 8000
y este es el proyecto
que tiene de prueba ahora mismo.
Así que nada,
ahora mismo este sería
el proyecto de cero
y ya está.
Este proyecto, como veis,
es muy sencillo,
pero lo interesante que tiene
es que podamos ver
que tiene su contador aquí
que es interactivo.
O sea, tenemos aquí
botones interactivos
y ¿cómo funciona esto?
Pues funciona gracias a las islas.
Pero si vemos
cómo...
qué es lo que ha cargado,
que luego lo veremos todo esto
con mucho más detalle
y lo vas a ver más claro.
¿Vale?
Pues veríamos que ha cargado
mucho menos de lo que necesita.
O sea, por ejemplo,
este Welcome to Fresh
lo ha renderizado directamente
en el servidor
con server-side rendering,
pero no se ha descargado
el JavaScript.
De hecho, si buscas aquí
el Welcome to Fresh,
¿ves?
Lo tendríamos aquí.
¿Vale?
Pero bueno,
no te preocupes por esto,
luego lo vas a ver al detalle
porque lo vamos a hacer
para que lo entendamos
y que veas la potencia
que tiene Dino.
Vale, pues ahora que
ya hemos hecho esto,
voy a cerrar esto.
Vamos a ponerlo aquí.
Esto lo voy a hacer pequeñito.
Esto lo voy a tirar para acá.
Una cosa que a mí me gusta mucho
cuando trabajo con proyectos así
que se van cambiando,
me gusta ponerlo
en Pandora Completa.
Esto ponerlo para acá.
Y esto ponerlo aquí al ladito
y así iremos viendo
todos los cambios que hacemos.
¿Vale?
Cerramos esto.
Cerramos todo.
Vamos a eliminar
este name, por ejemplo,
que no lo necesitamos.
¿Vale?
Y en el index vamos a eliminar
todo esto
y así empezamos nosotros de cero.
Quitamos esto aquí
y vamos a empezar aquí.
Obviamente tiene
Home Module Replacement,
tiene Live Refresh
y todo esto.
¿Hay alguna cosa que no tiene?
No te preocupes
que te lo voy a comentar también.
Esto ya funciona.
¿Vale?
Guardamos los cambios.
¿Vale?
Y aquí ya, pues ves,
esto ya funciona.
Lo teníamos aquí.
Si ponemos Class,
e importante,
no hace falta que utilices ClassName,
puedes utilizar Class
porque Priak
soporta Class.
No necesitas utilizar el ClassName.
y aquí ya podríamos utilizar,
como puedes ver,
tenemos todo el tema de Tailwind.
Pero asegúrate una cosa,
no es exactamente Tailwind,
es Tailwind,
que es muy parecido,
pero no exactamente igual.
Y aquí, pues,
le podríamos poner,
yo que sé,
que esto es text.xl, tal.
Así que fíjate que esto ya
también lo tienes
sin hacer nada.
O sea,
no hemos configurado nada
y esto ya lo tenemos funcionando.
El proyecto que vamos a hacer hoy,
vamos a intentar hacer un blog
que vamos a ir poco a poco,
lo vamos a ir complicando.
Y además,
mientras hacemos el blog,
vamos a ver tanto testing
como benchmarking.
O sea,
vamos a ver cómo puedes hacer test en Dino,
vamos a ver cómo puedes hacer benchmarks en Dino
y lo vamos a ver en mitad del proyecto.
Y además,
luego lo vamos a desplegar.
O sea,
vamos a ver también
cómo le puedes añadir interactividad,
o sea,
vas a ver unas cuantas cositas,
o sea,
que no pienses que es un blog y ya está.
Voy a hacer un blog
porque es un ejemplo sencillo,
pero que vamos a ver un montón,
por ejemplo,
cómo leer archivos estáticos,
cómo,
cómo podemos hacer un server server rendering,
todo esto lo vamos a ver,
aunque sea un blog,
porque es un ejemplo sencillo,
pero lo que quiero es que te enfoques mucho en el código
y no tanto en el producto,
porque eso no es lo más importante en este caso.
¿Vale?
Así que,
en este ejemplo,
vamos a poner aquí el div,
bueno,
pero como muchas veces,
eso sí,
lo que no me gusta es que las cosas sean feas,
vamos a intentar ponerle un poquito de,
vamos a poner que esto es el main,
¿vale?
Main,
main,
main,
y vamos a ponerle,
no sé si podríamos poner,
no sé si tiene blur esto,
a ver si tiene blur,
no,
no tiene blur todavía,
qué pena,
es que es una de las cosas que más le falta a esto,
es el tema del blur,
pero bueno,
da igual,
vamos a dejarlo por ahora así,
aquí le ponemos un margen de 4,
un padding de 4,
¿vale?
y este punto y coma aquí,
aquí hay un punto y coma que se ha escapado,
este de aquí,
¿vale?
Fuera,
punto y coma,
vamos a poner esto un poco más pequeño,
esto ya funciona,
vamos a poner aquí mi blog,
es un blog que va a ser,
como os digo,
sencillo,
pero es interesante porque lo vais a poder utilizar para crear vuestro blog,
si queréis,
vamos a empezar a crear,
por ejemplo,
aquí vamos a poner content,
y vamos a tener en el content,
vamos a tener los posts,
y vamos a tener aquí ya uno que sea hello world,
y aunque es un blog,
vamos a tener los,
o sea,
vamos a hacer un,
vamos a hacer un blog,
pero que los archivos estáticos de markdown los tengas en el propio sitio,
y los transformes con markdown y tal,
o sea,
que va a estar interesante eso también,
porque esto que vas a aprender también lo vas a poder hacer en otros sitios,
pero bueno,
vamos a ponerle un título,
hello world,
le vamos a poner también que tenga una fecha,
vamos a poner que es del 2022,
el 12 del 12,
por decir algo,
vamos a ponerle un excerpt,
que sería como una pequeña descripción del,
del,
del título,
o sea,
del,
del artículo,
y ponemos hello world,
this is my first post,
vamos a poner aquí algún heading,
this is a heading to,
this is a paragraph,
yo que sé,
this is a list,
vamos a hacer un poquito para que veamos que realmente luego lo renderizamos bien,
ok,
esto por acá,
perfecto,
guardo los cambios,
ya tenemos un,
uno,
vamos a,
vamos con el segundo,
vale,
el segundo,
para tener dos,
más que nada,
second post,
punto MD,
me voy a copiar esto,
pero le vamos a cambiar aquí,
second post,
y esto de que,
ya vamos a poner que es,
del 18,
this is my second post,
y aquí vamos a poner nombres de la gente que está en el chat,
vamos a ver,
hay gente en el chat,
como por ejemplo,
net for tibems,
tenemos sierra,
podemos,
ikuro time,
están,
en el chat,
también,
también Miguel RB,
a ver,
y el chico de la foto de perfil,
vale,
no sé quién es el chico de la foto de perfil,
Gijacopail,
pero vale,
está bien,
me parece correcto,
vale,
ya hemos puesto esto,
¿qué necesitamos ahora?
Obviamente,
lo primero que deberíamos hacer,
sería leer estos archivos,
pero necesitamos un sitio donde lo podamos renderizar,
para eso,
vamos a crear,
aquí en el,
en las rutas,
voy a crear,
malamente,
pero vamos a hacer aquí un href,
que le vamos a poner,
que vaya a barra,
y,
¿cuál es el primero que queremos?
Hello world,
por ejemplo,
¿no?
Hello world,
vamos a querer poder,
entrar al artículo este,
entrar al artículo,
hello world,
¿vale?
Aquí tenemos el,
nuestro enlace,
que no sé por qué,
no sale como,
no se ve absolutamente nada,
le vamos a poner un decoration,
o underline,
¿vale?
Vale,
y ahí lo tendríamos,
y aquí lo típico,
¿eh?
Le podéis poner todo lo que queráis de,
a ver,
blue,
tu,
tu,
tu,
vamos a ponerlo así,
para que al menos se vea un poco,
cuando hacemos el,
tal,
si entramos,
va a petar,
¿por qué?
404,
no encontramos este,
este fichero,
de hecho vamos a hacer lo que sea,
barra blog,
barra hello world,
vamos a,
ahí para atrás,
ahí,
vuelve a cargar,
vale,
ahora sí,
vale,
blog,
barra hello world,
tenemos que crear la ruta,
pues nada,
la creamos,
creamos aquí,
una carpeta,
bueno,
podemos hacer la de una,
podemos hacer blog,
barra,
y aquí,
tenemos que poner hello world,
pero no es lo que queremos,
lo que queremos es que pueda entrar,
a partir de cualquier,
slack,
o sea,
cualquier parte de la url que tenga sentido,
así que vamos a poner aquí id,
por ejemplo,
y .tsx,
aquí es donde vamos a renderizar un componente,
que va a ser el que va a responder con la página que queremos renderizar en este caso,
vamos a copiarnos un poco,
bueno,
no hace falta un copiamos nada,
export,
default,
page post,
se me ha olvidado aquí el function,
vale,
renderizamos aquí cualquier cosa,
ahora mismo,
h1,
esto es el artículo,
guardamos los cambios,
volver a cargar,
venga,
ya empezamos ahí a tener cositas,
vamos a poner aquí un article,
vamos a poner que tenga un poquito de separación,
y aquí,
vamos a poner también que tenga bastante más grande,
vale,
esto es el artículo,
y luego aquí,
pues tendríamos todo el contenido,
vamos a poner loremipsum,
bla,
bla,
ahora lo mejoraremos,
¿por qué?
porque aquí lo que queremos es renderizar justamente lo que tenemos en el punto MD,
¿cómo lo podemos hacer esto?
bueno,
aquí es donde vamos a necesitar crear como algún método que podamos llamar en el servidor para leer la información que queremos de nuestro markdown,
primero vamos a pensar en qué es un post,
o sea,
vamos a tipar la interfaz de TypeScript,
vamos a pensar que es un post,
tenemos un título,
una fecha,
un observe,
tenemos aquí un slack también,
que va a ser como la id también de nuestro post,
y le damos el contenido,
vamos a crear por aquí una carpeta,
bueno,
vamos a crear un archivo aquí,
types.d.ts,
vamos a exportar aquí nuestra interfaz,
vamos a poner que es un post,
le podemos poner que el id,
va a ser un string,
no va a ser un number,
luego tendríamos el title,
sí,
tenemos el contenido,
tenemos el date,
que es del tipo date,
¿qué más tenemos?
tenemos un body,
que es del tipo string,
y creo que con esto,
¿no?
title, date,
bueno,
el excerpt,
bueno,
vale,
he puesto content,
en lugar de,
no sé,
llamarle body o content,
venga,
le vamos a llamar body,
y el excerpt que sería la descripción,
al menos ya tenemos esto,
y ahora vamos a crear nuestra primera utilidad,
y además lo vamos a hacer ya conociendo algo de la API de Dino,
o sea,
que está bastante interesante,
para poder leer justamente nuestro primer artículo,
así que vamos a crear una carpeta,
le puedes llamar utilservices,
como tú quieras,
vamos a poner aquí utilspost.ts,
y ¿qué necesitamos aquí?
vamos a crear una carpeta,
hay una función,
que sea export,
async function,
load post,
¿vale?
vamos a cargar,
load post,
mira,
casi,
casi,
no veas,
¿eh?
cómo se lo,
cómo se la juega aquí,
GeekHackoPilot,
bueno,
no es así,
no es así,
ojalá fuese así,
pero no,
no es así,
lo primero,
necesitamos como el contenido,
vamos a leer el contenido del archivo en concreto que queremos,
voy a poner por ahora aquí,
que esto sea row,
le voy a decir que es un string,
vamos a dejarlo así,
y vamos a intentar,
leer el contenido del fichero,
¿vale?
vamos a decirle que el row,
el row,
digamos que es el contenido sin tratar,
¿vale?
le decimos await,
mira,
esto sí que lo ha hecho bien,
punto red,
text file,
esto es muy interesante,
y es una diferencia muy importante respecto a node,
porque como pueden notar,
no he tenido que importar absolutamente nada,
Dino,
tiene un objeto global que se llama Dino,
¿vale?
valga la redundancia,
en la que vas a tener la posibilidad de acceder a un montón,
pero a un montón ya de utilidades que te da desde escribir archivos,
leer archivos,
yo que sé,
es que tienes un montón de abrir nuevos procesos,
leer carpetas,
cambiar los permisos de una carpeta,
matar procesos,
un montón de cosas,
sin necesidad de importar absolutamente nada,
lo cual está bastante chulo,
¿vale?
esto normalmente es un poco,
porque tienes que decir,
vale,
¿cómo tengo que importar?
y aquí nada,
pones Dino,
punto,
haces comando espacio,
y aquí tienes un montón de cosas que ya puedes utilizar,
y una de esas es read,
read,
text file,
solo le tenemos que decir ya,
¿dónde está el fichero que queremos leer?
en este caso,
tenemos que ir,
no está bien,
lo que está diciendo ahí no está bien,
no os fíéis,
es content,
barra,
post,
y aquí vamos a utilizar,
aquí le está llamando ID,
le vamos a llamar nosotros,
¿cómo le hemos llamado aquí?
ID,
no sé si llamarle Slack,
para que quede más claro,
aunque la habíamos llamado en otro sitio,
en la ruta,
bueno,
vamos a llamarle ID todo el rato,
va,
porque si no,
ID,
¿vale?
y vamos a poner aquí la ID,
punto MD,
con eso,
si todo va bien,
debería,
debería leer correctamente el fichero,
pero si no,
pues vamos a poner aquí un return null por ahora,
luego ya veremos cómo gestionamos el error,
¿vale?
y este error,
pues nada,
lo quitamos así,
no hace falta,
no hace falta este cache,
vale,
esto al menos nos debería decir que funciona,
bueno,
vamos a pasar,
como esto no lo necesitamos así,
vamos a pasar el ID como un string,
y ya está,
esto por ahora debería al menos,
si le hacemos aquí un return row,
esto debería funcionar,
¿cómo podemos probar esto?
¿cómo podemos empezar a probar cómo funciona algo de vino?
¿cómo lo ejecutamos?
¿cómo lo hacemos?
una cosa que podríamos hacer es,
pues poner aquí ya el load post,
podríamos hacer aquí hello world,
¿vale?
y podríamos abrir la terminal,
vamos a abrir aquí otra terminal,
a ver,
voy a leer un momento,
a ver si,
no puedo seguir el ritmo de mi dugout,
bueno,
a ver,
pues venga,
vamos a parar un momento,
¿tenéis alguna pregunta?
os leo,
antes de continuar a,
a Twitch le falta un ajuste de velocidad,
¿dónde nos hemos quedado?
vale,
con esto,
de cómo podemos probar,
ahora justamente,
que,
¿dónde me había quedado?
estoy creando aquí,
un archivo,
que se llama post,
que lo que voy a hacer es cargar,
el post que he creado aquí,
de markdown,
luego lo veremos,
cómo lo podemos transformar,
cómo podemos hacer todo esto,
pero por ahora lo que quiero ver,
es si realmente,
con dino.read.textfile,
que es un método de dino,
para leer archivos,
para leer el contenido de un archivo,
vamos a ver si me está devolviendo lo que quiero,
una cosa que puedo hacer,
es simplemente ejecutar este código,
porque si te fijas,
este código,
podría ser ejecutable tal cual,
tiene diferentes opciones,
una,
podrías escribir creo que dino,
¿vale?
y con dino,
ves,
tienes el repel,
¿no?
que básicamente es read,
execute,
no me acuerdo,
nunca me acuerdo lo que es,
pero es como un playground,
en el que lo que escribes,
te lo ejecuta,
aquí podríamos importar,
importar,
por ejemplo,
load post,
lo podemos,
o sea,
esto está muy chulo,
porque puedes importar un fichero aquí,
y si no hemos hecho esto mal,
debería ser así,
¿vale?
y ya podríamos poner load post,
y podríamos ponerle aquí,
hello world,
y ver si esto devuelve algo,
¿vale?
fíjate que me ha devuelto una promesa,
y cuando la promesa se ha resuelto,
bueno,
no sé si lo ves,
sí,
sí que lo ves,
cuando la promesa se ha devuelto,
pues,
me ha puesto el title,
y todo esto,
aquí se ve,
esta sería una opción,
¿vale?
esta sería una forma de hacerlo,
pero,
si esta forma,
dices,
ostras,
es que no lo veo muy claro,
que tiene sentido,
que no lo veas muy claro,
podemos salir de aquí,
y otra forma que podrías hacer,
es simplemente ejecutar directamente,
este fichero que habíamos creado,
o sea,
podrías ir y hacer aquí,
dino,
run,
y poner directamente aquí,
utils,
barra,
post,
punto ts,
y ahora aquí,
vale,
no me sale nada,
no me sale nada,
porque aquí no he puesto una wait,
y porque no he puesto un console log,
deberíamos hacer las dos cosas,
porque el método es asíncrono,
por eso necesitamos el await,
y luego además,
para que aparezca,
tenemos que hacer un console log,
voy a volver a ejecutarlo,
y ahora sí,
fíjate que me está diciendo,
me está pidiendo acceso de lectura,
ves como por defecto,
es tema de seguridad,
que siempre te está preguntando,
si quieres quitarte el tema de las preguntas,
pues ya sabes,
le pones al menos a,
aquí en mayúscula,
que le da acceso a todo,
o le das el acceso específico que necesita,
vale,
espérate que le he puesto sin espacio,
vale,
y ya está,
ahora ya sí,
tengo aquí justamente,
todo el tema de,
todo el contenido del fichero,
o sea,
ya vemos que sí que está funcionando bien,
pero seguramente alguien dirá,
ostras,
entonces,
esto,
¿qué?
ahora ya sabes que funciona,
ya está,
¿cómo te fías?
bueno,
vamos a hacer una cosa,
porque para que esto no sea el típico tutorial,
que al final siempre se hace lo mismo y tal,
te voy a enseñar cómo hacer test en Dino,
porque se puede hacer test en Dino,
voy a ver si soy capaz también,
porque no me acuerdo muy bien,
pero para ver que esto funciona,
una cosa que podríamos hacer es hacerle un pequeño test,
podríamos ser aquí en utils,
si no recuerdo mal,
es post barra tests,
o test,
ahora luego probaremos,
y puedes hacer Dino punto test,
y con esto ya puedes crear un test,
y puedes poner aquí,
bueno,
load to return null,
if the post doesn't exist,
mira,
esto,
esto es un buen test,
vamos a hacer justamente este test,
vamos a probar con Dino,
vamos a probar,
por cierto,
esto es un rollo,
de que son como unas,
como,
como te lo diría,
es como una,
como un adorno,
que le pone para que sepas a qué se refiere,
porque muchas veces los parámetros,
como no están nombrados,
pues te dice,
esto es el nombre,
que lo sepas,
se puede eliminar,
se puede quitar,
se puede activar,
pero bueno,
lo vamos a dejar por ahora,
para que lo veamos un poco más claro,
vamos a importar el load post también,
vamos a quitar esto,
vamos a poner aquí load post,
lo importamos,
quitamos esto,
y de dónde sacamos el assert equals,
¿vale?
Una cosa que podríamos hacer aquí,
es directamente decirle,
if post es diferente a null,
throw new error,
this is,
o expected null,
¿vale?
Podríamos hacer esto,
y esto en realidad,
no sé por qué,
me dice esto,
porque no he cerrado,
esto,
vale,
y aquí ponemos punto TS,
vale,
con esto hemos creado un test,
directamente,
podríamos decirle,
vale,
para un post que no existe,
espero que devuelva null,
si no es null,
voy a enviar un error,
¿vale?
Como para decirle,
oye,
esto no está bien,
vamos a ver si esto funciona,
lo bueno,
fíjate lo que ha salido aquí,
ha detectado automáticamente,
que esto es un test de Dino,
está súper chulo,
porque con esto aquí,
le puedes dar aquí play,
y ya,
bueno,
aquí en este caso me ha dicho que han pasado cero de cero,
¿por qué?
Pues que algo ha pasado aquí que no le ha gustado,
no ha encontrado el utils.post,
no ha encontrado el utils.post,
test,
utils,
pero esto es como que no ha detectado este de aquí,
esto está bien,
¿no?
post.ts,
vale,
a ver ahora,
ahora sí,
vale,
no sé,
como que esto no lo había detectado este cambio,
pero fíjate que me ha dicho que todos los test han pasado,
o sea,
están los test integrados en Dino,
no he tenido que instalar todavía nada,
fíjate que no he instalado todavía absolutamente nada,
o sea,
está bastante chulo,
porque lo que estamos consiguiendo con esto,
es ya al menos ir probando,
ahora,
una cosa que aquí,
pues seguramente quieres utilizar el assert,
¿no?
Dino,
assert,
vale,
pues Dino no tiene un assert,
¿vale?
No tiene un assert.
Ahora,
¿cómo lo podemos solucionar?
Dino tiene una librería que se llama STD,
STD significa estándar,
son módulos estándar que tiene Dino,
son módulos que no tienen dependencias externas,
y que además están cuidadas por el propio equipo de Dino,
o sea,
que son dependencias que son bastante fiables,
y hay un montón,
tienes un montón para hacer cosas muy típicas,
tratar con cookies,
hacer un render de un markdown,
que luego lo vamos a utilizar,
renderizar diferente contenido,
HTML,
hacer sanitarización,
un montón de cosas.
Entonces,
podemos ver,
a ver si veo la lista,
vale,
creo que,
no sé si ver documentación,
aquí,
vale,
veis aquí hay un índice de un montón de cosas que tenéis,
por ejemplo,
el .env,
para trabajar con asincronía,
con cripto,
con fechas,
encoding,
y hay una que debería ser testing,
hay una carpeta de testing en la de estándar,
¿vale?
y aquí tenéis asserts,
BDD,
TIE example,
mocks,
snapshots,
y en asserts,
tenemos aquí una librería completa para hacer aserciones,
o sea,
no necesitas absolutamente nada,
así que te podrías copiar,
básicamente,
esta línea de código,
ponerla aquí,
y aquí ahora,
deberíamos poder ver lo que trae.
Lo malo,
que como ves,
dice,
un cache or missing remote URL,
es como que no detecta bien la URL,
a veces es como que le tarda,
como que tiene que cargarla,
no sé si,
ves que pone uncache,
no sé qué,
no sé si tengo que,
ves,
tienes que cachearlo,
le tienes que dar,
y entonces una vez que la ha cacheado,
es como que la ha descargado,
y ahora sí que tienes acceso a todo.
La verdad es que no sé por qué tienes este retardo,
en el que tarda a veces,
o te pones encima,
le das a comando punto,
control punto,
le das a quick fix,
y le dices cache,
y ya está,
entonces lo cachea,
y ahora sí tienes acceso a todo.
Pero fíjate que no hemos tenido que hacer una instalación,
o sea,
no he hecho un NPM install,
nada,
o sea,
simplemente lo hemos hecho y ya está.
Y aquí podríamos decirle,
pues eso,
assert equals,
creo que es esta,
si no me equivoco,
y aquí pues decirle,
assert equals,
post y null,
que esto tiene que ser null.
Así quitamos esto,
guardamos los cambios,
le podemos dar otra vez al play,
para ver si esto funciona,
que veo que aquí,
pensaba que detectaría,
que hemos hecho,
voy a poner aquí otra cosa,
hola,
vamos a guardar los cambios,
vamos a darle al play,
vale,
ahora sí que ves que peta,
no me está diciendo,
oye,
esperaba esto,
o sea,
para que veas que sí que funciona,
porque si no,
te vas a quedar así como,
oye,
¿qué ha pasado?
Bueno,
lo que ha pasado es que funcionaba todo perfectamente,
si,
como espera null,
pues le ponemos aquí null,
y ya está,
¿no?
Guardamos los cambios,
le damos otra vez,
una vez que le dé al play,
y sí que pasan los tests.
O sea,
tienes todo el tema de tests,
lo tienes todo integrado aquí,
lo cual está genial,
pero bueno,
al menos para que veas cómo son los tests,
y ahora lo complicamos un momento más.
Vale,
ahora tenemos la pregunta esta,
que es muy interesante,
¿no es muy complicado mantener la versión actualizada en cada URL del import?
Dice Waxalber,
muy buena pregunta,
¿no?
Esto no es un poco rollo,
porque claro,
si yo tengo que importar estas URLs a través de todo mi proyecto,
¿no es un poco rollo cuando sale aquí la versión?
Pues sí,
sí que lo es,
pero por suerte,
¿qué tenemos?
Tenemos nuestro import map,
o sea,
aquí tenemos un import map que nos va a ayudar,
de hecho,
vamos a utilizar este import map,
vamos a poner barra std,
barra,
y aquí vamos a utilizar esto que habíamos hecho aquí,
lo vamos a traer,
me lo voy a copiar aquí,
porque para esto es justamente el import map,
para no tener que mantener en todos los archivos esto,
pues vamos a hacer esto,
¿no?
Y ahora os comentaré esto que dice Kiñe,
pero que es una mala práctica lo que comenta Kiñe,
¿no?
Para que no utilices siempre la última versión.
Lo que comenta Kiñe es,
bueno,
pero puedes quitar esto y ya está,
te funciona y no te dejes preocupar.
Pero esto normalmente no es buena idea,
y os comento por qué.
Aunque cuando quitas la última versión,
pues esto,
o sea,
cuando quitas la versión,
te funciona,
pero fíjate que ya te dice aquí que hay un warning,
te dice,
eh,
que estás utilizando de forma implícita,
estás utilizando siempre la última versión.
¿Qué significa esto?
Significa que no vas a tener una forma de controlar
qué versión se va a instalar.
Directamente se instalará la última y ya está.
Y esto puede ser súper peligroso
y un rollazo a la hora de depurar errores.
Así que os recomiendo que lo evitéis.
Nunca utilicéis directamente la versión.
Intentad siempre poner alguna versión
para tenerlo de algo controlado
y sobre todo que esto lo saquéis al import map.
Y aquí en el import map lo que podéis hacer,
por ejemplo,
sería dejarlo hasta aquí,
¿no?
Y así lo que tendríamos es,
vale,
cuando yo me refiero a STD barra,
lo que voy a hacer es aquí,
toda esta parte de aquí,
en lugar de utilizar todo esto,
vamos a utilizar el STD,
o sea,
STD barra,
así.
Fíjate que además ya lo detecta,
o sea,
tú aquí puedes poner STD barra
y aquí tendríamos,
¿ves?
Testing,
assert,
o sea,
que está encontrando el autocomplete totalmente,
o sea,
que no os preocupéis de que no vais a tener autocomplete,
lo tenéis sin ningún problema.
Y aquí cargamos nuestro,
el que necesitamos,
el de assert,
y ya está.
Pero ya habéis visto que tenéis todo el tema de testing,
lo tenéis en,
lo tenéis integrado directamente en Dino,
¿no?
Así que nada,
con esto ya teníamos un test,
al menos para ir probando que nos devuelve en null,
pero bueno,
nos falta todavía trabajo aquí,
vamos a ver cómo lo podemos hacer,
¿no?
Vamos a volver a nuestro archivo este,
el low post,
porque bueno,
está muy bien,
pero ahora mismo no es justamente lo que queríamos.
Vamos a importar el post de types.ts,
¿vale?
Y le vamos a decir que el low post,
lo que tiene que devolver,
es una promesa que va a ser un post o va a ser null,
porque justamente es lo que hemos dicho que debe ser,
¿no?
Ahora está devolviendo string,
pero no es lo que queremos que devuelva.
Cuando esto funcione bien,
lo que queremos es que devuelva un post.
Así que tenemos que crear el post
y para eso tenemos que leer el archivo
y transformar el front matter y tal.
¿Qué es el front matter?
Porque a lo mejor no sabe lo que es el front matter.
Front matter es esta parte de aquí.
Esto es como una,
digamos,
tenemos un estándar que existe
que se llama front matter
en el que tú arriba
pones información para el markdown
y lo pones entre estas líneas de aquí.
Le pones el título,
la fecha y un excerpt.
Y esta información la puedes leer,
obviamente,
porque si no,
pues para qué serviría.
Y para eso necesitamos algún tipo de dependencia
que permita extraer esa información.
Así que,
¿cómo lo vamos a hacer?
Pues lo vamos a hacer también con el estándar.
Esta librería estándar,
esto es una de las mejores cosas que tiene Dino
que no tiene Node.
No tiene,
Node tiene su propia librería,
o sea,
su propia biblioteca,
su propia API,
pero no tiene,
digamos,
una biblioteca aparte
que sea estándar.
Y por lo tanto,
cuando quieres hacer algo con cookies,
pues tienes que buscar en NPM
cómo trabajar con cookies.
En cambio,
Dino,
como tienes aquí
un montón de cosas ya solucionadas
y que son casi como un estándar,
bueno,
casi no,
es que lo son.
O sea,
no están de alguna forma,
no están dentro del core,
pero es una librería,
una biblioteca
que Dino considera que es estándar.
¿Vale?
O sea,
si tienes que trabajar con cookies,
utiliza esta,
que está comprobada.
Pues lo mismo,
tenemos aquí,
fíjate que tenemos una que pone encoding,
¿vale?
Pues en el encoding,
vamos a ver que tenemos from matter,
¿vale?
Y en from matter,
ya vemos aquí que tenemos todo este churro
y tenemos diferentes métodos,
por ejemplo,
aquí tenemos el extract
y lo tenemos aquí para utilizar.
Fíjate que esto es muy similar
a lo que queremos hacer,
así que vamos a copiarnos esto,
no sé por qué aquí ponen any,
aquí ponen any,
pues bueno,
nos vamos a copiar esto,
vamos a copiarnos esto,
pa, pa, pa,
y nos vamos a ir a nuestro código
y ya,
aquí lo tenemos.
Voy a poner directamente el extract
porque el test no es muy útil
en este caso.
Tenemos otra vez el problema
del uncache,
y no sé qué.
Pero de nuevo,
¿qué tenemos que hacer en este caso?
Bueno,
hemos dicho que esto
no lo íbamos a hacer así directamente,
así que ponemos aquí
estándar,
barra,
y esto le decimos punto
y le ponemos esto del caché.
A mí me encantaría
que esto fuese más rápido,
no sé por qué no lo hace más rápido,
no sé si habrá alguna opción
que lo haga más rápido,
pero ya está.
Bueno,
pues ahora que ya tenemos el extract,
pues lo vamos a utilizar.
¿Cómo lo utilizamos?
Pues con el string,
el contenido del fichero
que teníamos.
Vamos a sacar de aquí,
vamos a,
no me acuerdo cómo es,
voy a poner aquí
extracted,
por poner algo,
y lo que extraemos
es del row,
¿vale?
El contenido que hemos leído.
Voy a poner un console.log,
porque es que no me acuerdo
cómo es esto.
Extracted,
¿vale?
Voy a ver el extracted.
Claro,
el problema ahora,
pues tendríamos que poner,
bueno,
no sé si devolver el extracted
al menos
y así ver qué es lo que tiene,
¿no?
¿Vale?
Obviamente,
TypeScript se queja
porque no está bien el tipo,
pero bueno,
vamos a hacer aquí otro test,
¿vale?
y load test,
returns null,
vamos a decir,
returns a post,
if the post object,
if post does exist,
¿vale?
Vamos a decirle,
uno que sigue exista
es el de hello world,
hello world,
y esperamos
assert
no sé si el match,
la verdad es que nunca
he visto este
bueno,
vamos a poner assert equals
que post.slug
sea
hello world,
¿vale?
Esta debería ser una cosa
y ya está,
que esto
funciona así,
property.slug,
ah,
es id,
perdón,
no es slug,
es id.
Obviamente,
esto nos va a petar
porque todavía no me ha arreglado,
voy a darle al play aquí,
a ver,
¿vale?
Me peta,
undefined,
vale,
me está devolviendo
undefined,
el extract este,
este extract,
este no le ha gustado,
no le ha gustado nada,
es que no me acuerdo,
ah,
bueno,
espérate,
si esto tiene typescript,
o sea,
esto me debería decir
lo que devuelve,
ya está,
atributos y body,
lo que pasa es que no sé
porque extract no,
no,
no me está devolviendo nada,
pero bueno,
ahora que ya sé esto,
que es interesante,
vamos a crear aquí el post,
le decimos que esto es un post,
tendríamos,
la idea sería la idea,
justamente la misma,
vamos a ver el tipo,
el title sería de los atributos.title,
¿vale?
Los atributos que tenemos aquí
es lo que tendríamos aquí,
el title,
el date y el excerpt,
o sea,
estamos extrayendo la información de aquí
y nos las ha transformado en un objeto,
que lo tenemos aquí en el attributes.
Y ahora,
¿qué más tenemos en attributes?
Tendríamos el body,
sería el contenido de nuestro markdown,
o sea,
sería esto de aquí,
¿vale?
Esto de fuera.
Y,
¿qué más tendríamos?
El date,
debería ser,
tenemos que transformarlo en un date,
o sea,
new date attributes.date,
y ahora os explico
por qué me sale tanta cosa en rojo,
que,
claro,
eso es interesante,
porque fíjate,
esto es un problema,
bueno,
un problema,
esto es una feature de TypeScript,
que me dice que los atributos es un record,
donde la key es un string,
pero el valor es unknown,
o sea,
no sabe que es el valor.
Yo se lo puedo decir porque sé que es un string,
o sea,
no hay ningún problema.
Entonces,
una cosa que podríamos decir es,
mira,
tenemos,
voy a decirle que tenemos parámetros,
y que los parámetros son los atributos,
como si fuese un record,
con un string,
y un string.
Lo podrías arreglar de diferentes formas,
pero bueno,
esta sería una,
y así al menos nos deja de dar la turria con ese problema.
¿Qué más tipos tenemos?
El excerpt,
¿no?
El excerpt,
justamente,
hemos dicho que es el parámetros punto excerpt,
¿vale?
Y devolvemos el esto,
pa, pa, pa,
post,
punto.
Mírate optional chaining en JavaScript.
Ah,
a mí,
ah,
no,
se lo está diciendo a rxtl,
¿vale?
Sí,
aquí en este caso no creo que sea necesario,
pero,
pero sí,
a veces puede ser útil.
Y con esto,
pues,
yo creo que ya deberíamos tener ahí el post,
¿no?
Hemos leído el archivo,
hemos extraído la información del markdown,
tenemos el body y los atributos,
nos está quejando TypeScript,
vamos a ver si no funciona el test,
para que luego digáis que no se hacen test,
y ahora el test nos pasa.
Oye,
qué maravilla,
que hemos hecho un par de test,
está bastante chulo,
porque,
no sé,
o sea,
que muchas veces os quejáis de que no hacemos test,
pues mira,
ahí tenemos dos test,
y además los hemos hecho en un momento.
A ver,
no es que deberíamos testear más cosas,
por ejemplo,
tendríamos que asegurarnos que el title lo está devolviendo bien,
o sea,
punto title,
debemos esperar que esto,
pero bueno,
la idea no era que hiciésemos muchos test,
sino que realmente veáis que fácil es hacer test,
y a partir de ahí,
pues que lo podáis hacer vosotros mismos sin ningún tipo de problema,
¿vale?
A ver aquí,
vale,
sigue funcionando,
pues ya está.
No sé,
tiene muchas características que ya vienen de base,
y que llaman bastante la atención.
Bueno,
esto hasta ahora está bien,
si miramos,
hay un problema todavía,
pero lo vamos a arreglar después,
por ahora vamos a intentar llamar este nuevo,
este método que hemos hecho aquí,
que está muy bien,
pero fíjate que todavía no estamos enviando esta información a nuestro blog,
para que un blog sea un blog,
necesitaremos que aparezca.
Así que vamos a ir a nuestro rutas,
a nuestro blog,
a id,
aquí lo estamos poniendo todo a mano,
pero aquí queremos que salga la información real del artículo.
Pues bueno,
para esto lo que necesitamos es llamar a nuestra función de loadPost,
esta que habíamos hecho aquí,
la necesitamos llamar aquí.
¿Cómo se hace esto?
Bueno,
aquí lo que necesitamos es utilizar y crear una cosa que se llama un handler.
Así que exportamos una constante handler,
esto es como funciona DinoFresh,
y aquí en handlers,
le podemos decir,
incluso ya lo podemos tipar,
le podemos decir que esto es un handler,
no sé si esto lo pillará,
no lo pilla,
a ver si le decimos fresh handler,
fresh handler tampoco,
pues pensaba que lo iba a pillar,
si no lo podemos importar.
Handler,
no,
vamos a importar,
a ver,
de fresh,
y no sé de dónde sale este,
no sé si es de server,
server.ts,
esto es para tener los tipos,
pues no,
no sale tampoco,
pues yo creo que sale de aquí,
lo voy a importar,
no sé si es handler,
no sé si es handler,
lo voy a intentar importar,
es declarable but never use,
no,
es que no me lo está pillando,
bueno,
pues no,
no lo sé,
bueno,
lo quería tipar,
pero no me deja,
no sé,
handlers puede ser,
no me está pillando dos tipos,
no sé,
no sé por qué,
pero no me lo está pillando,
y fresh handler me parece que no es,
bueno,
pues lo voy a dejar así como está,
luego lo miramos,
a ver si soy capaz de sacar los tipos,
no sé por qué no me lo está pillando,
vale,
tendríamos que exportar un handler,
vale,
un handler es como el que se va a encargar
de que cuando hagas una petición,
pase por ahí y recupere información,
o renderice la página,
o lo que tú quieras,
aquí puedes hacer lo que tú quieras,
y lo puedes hacer por cada verbo,
o sea,
con el get,
con el post,
con el delete,
además,
a mí me gusta bastante cómo está hecho,
y vas a ver por qué,
vamos a hacerlo con el get,
¿no?
Hacemos async,
y le decimos,
vale,
esto queremos que tenga un get,
y aquí tendríamos tanto la request,
que le va a llegar,
como,
el contexto,
y vas a ver que tiene el contexto,
que es bastante importante,
porque si no,
no te va a funcionar,
espérate,
que la he liado aquí,
que he hecho aquí,
que sport const,
igual,
async,
ay,
perdón,
perdón,
es que he hecho aquí esto como si fuese una función,
y esto no es una función,
¿eh?
esto es un objeto,
ahora,
ahora sí,
el handler es un objeto,
no es una función,
es dentro,
que tienes que poner el get,
el delete,
y eso sí que son funciones,
son propiedades del objeto,
¿vale?
y en este caso el get,
es el que es una función,
¿vale?
aquí que nos pone que el request es tal,
claro,
me está diciendo que es implícito,
porque no me está dejando aquí ponerle el handler,
pero bueno,
no me está dejando poner,
luego,
luego en el chat seguro me decís como tiparlo,
pero debería,
debería dejarme tipar fácilmente,
si no puedo mirarlo en Dino Fresh,
en un momento,
que me imagino que aparecerán los tipos y tal,
pero yo juraría que era,
que evita root,
a ver,
handlers,
a ver si leo,
custom handlers,
a ver si,
¿ves?
ostras,
pues así,
esto es lo que quiero hacer,
pero no sé por qué no me lo estaba pillando,
handlers,
handlers,
ah mira,
ahora sí,
pero no me lo estaba pillando automáticamente,
lo cual era un poco rollo,
vale,
he guardado los cambias,
ahora sí que funciona bien,
y lo está tipando todo bien,
solo poniendo el handlers este,
fíjate todos los métodos que puedes utilizar,
get,
get,
post,
put,
delete,
options,
patch,
vale,
pero fíjate que en cuanto he puesto el get,
pues me ha puesto empty response,
o sea,
me ha petado la página,
me ha dicho,
oye,
ha pasado aquí,
bueno,
esto es súper interesante que tienes que tener en cuenta,
porque lo que estos métodos que pones aquí,
se ejecutan justo antes,
justo antes de renderizar esto,
por lo tanto,
tienes que asegurarte de que renderizas el contenido,
porque si no,
te va a petar,
así que aquí lo que vamos a hacer es cargar el post,
vamos a recuperar el post,
y para eso tenemos que sacar la id,
y no hay que sacarlo de request params,
como pone aquí,
esto está mal,
hay que sacarlo del contexto,
¿vale?
tienes el contexto,
punto,
params,
y aquí es donde tienes la id,
¿vale?
y esta id,
¿de dónde sale?
pues sale justamente de aquí,
¿vale?
del nombre del archivo,
si aquí le hubiéramos puesto otro nombre,
pues este punto,
params,
punto,
aquí sería otro nombre,
o sea que no,
que lo tengas en cuenta,
ahora,
como lo estamos haciendo un destructuring,
pues no hace falta que pongamos el punto idea ahí,
pero que sepas que ese nombre sale de ahí,
¿vale?
o sea que le puedes poner el nombre que tú quieras,
ahora necesitamos recuperar el post,
así que el post,
hacemos una wait,
y utilizamos el método que hemos creado antes,
load post,
lo importamos,
y le pasamos la idea,
y aquí,
pues dependerá de si tenemos post,
o no tenemos post,
pero fíjate que,
si ahora,
pues hago un comentario,
hago un console.log del post,
vamos a guardar los cambios,
recargo la página,
vale,
¿qué puedo ver?
Puedo ver que aquí abajo,
sí que tengo la información del post,
o sea,
hasta aquí bien,
¿no?
Tengo información del post,
pero a la derecha,
todavía no se está enseñando nada,
y es que esto es súper importante,
cuando creáis,
como en este caso,
un,
como,
un handler,
para la página,
tenéis que aseguraros que,
si queréis que renderice esa página,
tenéis que devolver context.render,
¿vale?
Guardamos los cambios,
así que vemos que se renderiza la página,
y mientras que también estamos recuperando esto.
Ahora,
¿cómo hacemos para que esta información,
la podamos recuperar también aquí en el page post?
porque necesitamos que aquí en las props,
que si no me acuerdo mal,
era page props,
que en este,
espero que es que me lo pille,
¿vale?
No me la,
page props,
page props,
es que no me los importa,
page props,
¿ahora sí?
Vale,
más o menos,
más o menos,
no me lo están pillando bien los tipos,
no sé por qué,
¿vale?
Queremos pasarle,
en este page props,
le queremos pasar aquí este post,
pues lo que tenéis que hacer simplemente,
en este render,
es pasarle aquí el post,
y ya está,
¿vale?
Le pasáis el post al render,
se lo pasáis como un objeto,
perdón,
que se lo pasaba directamente,
pasarle un objeto,
page,
así,
directamente,
y ahora,
sí que en las props,
si miramos que tenemos en las props,
vamos a poner aquí props,
¿vale?
Recargamos la página,
y ya podéis ver toda la información que nos llega a las props,
tenemos props,
y tenemos los params,
que sería la ruta de la URL,
donde tenemos la idea,
tenemos la URL entera,
tenemos root,
y en data,
tenemos el post,
y este post,
es el que le estamos pasando justamente aquí,
o sea,
que ya,
teniendo esto claro,
podríamos hacer post,
y esto lo tendríamos que sacar de props,
data,
y ya está,
y ahora esto,
tendríamos aquí,
el post.title,
y aquí tendríamos el post.body,
y podríamos empezar a complicar un poco más,
o sea,
que enseñar más información,
¿no?
El date,
esto lo podríamos hacer con inter-date-time-format,
ese post-date,
creo que es así,
ah,
no,
esto no es así,
perdón,
esto es así,
.format,
¿vale?
Para formatear la fecha con nuestro,
creo que es así,
esto sea el time,
y nos faltaría,
bueno,
el excerpt no lo queremos enseñar,
el title sí,
y ya está,
¿vale?
Y ya tendríamos ahí toda la información.
¿Qué hemos hecho?
Vamos a repasar esto,
y ahora os leo,
a ver si tenéis alguna pregunta,
¿vale?
Pero JSX no era de React,
no,
JSX no es de React,
¿sabes?
O sea,
JSX al final es de,
es un lenguaje,
JSX es un lenguaje,
y hay algunos que puedes utilizarlo con React,
con Angular,
con Vue,
con Preac,
con Quick,
con un montón,
JSX al final es un lenguaje de marcado,
como lo es HTML,
lo que,
cómo se renderiza,
y que normalmente se utilice para React,
pues sí,
de hecho se creó para React,
lo creó Meta,
pero,
se puede utilizar un montón,
no tiene nada que ver con la biblioteca.
¿De dónde sale el Page Props?
Creo que me perdí,
vale,
te lo comento,
no pasa nada.
El Page Props,
este que hemos visto aquí,
este Page Props,
esto sale de este import de aquí,
Fresh,
Dino Fresh,
que es el framework que estamos utilizando,
tiene,
uy,
no sé qué hago aquí,
tiene un montón de tipos,
obviamente,
que te ayuda a tener tu página tipada,
y las Page Props es una de ellas.
¿Por qué utilizamos Page Props?
como interface para tener la información,
porque las Page Props,
como hemos visto,
no solo tiene las Props que nosotros le pasamos,
sino que tiene algunas extras,
y así,
de esta forma,
cuando tú hagas Props,
punto,
vas a tener bien tipado esto,
y tener autocomplete perfecto.
MewDev,
me perdí todo el directo.
Bueno,
no pasa nada,
por suerte se guarda.
Vamos a intentar hacer el tema este de,
de formatear el,
el,
el Front Matter,
¿no?
Porque si no,
estoy pensando,
claro,
es que es un poco rollo,
el hecho de que el Front Matter no,
no lo,
no lo pilla,
voy a mirar a ver si tengo por aquí alguna librería,
en el estándar que pille y haga esto,
y si no,
pues pensamos,
a ver,
¿cómo se llama este?
Vamos a buscar aquí,
eh,
Dino,
eh,
Markdown Compiler.
Mm,
mm,
este no.
Hay uno,
que ya no me acuerdo cómo se llama,
Markdown to HTML.
Bueno,
solo sale este,
no sé,
este,
Dino GFM,
este,
este,
este,
Dino GFM.
Este es el que podemos utilizar,
porque además tiene estilos,
pero bueno,
vais a ver que es súper fácil,
igual que aquí,
pues podemos importar esto,
a ver,
vamos a ver qué versión nos pone esto,
X,
vale,
pues vamos a traernos esto,
voy a dejar esto por aquí,
mientras lo voy leyendo,
y aquí,
vamos a tener,
uy,
este row,
ah,
ah,
bueno,
aquí nos faltaría,
claro,
mirar que si,
if not row,
pues podemos poner aquí,
return,
null,
vale,
directamente.
Vamos a importar aquí,
el render,
from,
aquí,
luego de nuevo,
esto tendríamos que cachear,
tal,
y,
ah,
vale,
sí,
ya estoy mostrando esto,
vamos a mostrar el HTML correctamente,
porque veis,
esto ahora tiene el markdown,
y no tiene mucha,
muy buena pinta.
Podríamos hacerlo aquí,
o lo podríamos hacer en el get,
donde queráis,
lo voy a hacer aquí,
para que quede todo bastante arreglado,
no voy a poner,
mover esto en el import map,
porque ya habéis visto cómo se hace,
y para que no sea repetitivo,
pero,
hacerlo,
vale,
y este body,
vamos a poner render del body,
y entiendo que con esto,
ya debería ser suficiente,
vale,
ahora veis que sí que tengo el HTML,
pero obviamente,
no,
lo está renderizando mal,
lo está renderizando mal,
porque necesitamos que esto,
que ahí lo he puesto,
lo he puesto con una P,
pero eso ya no es correcto,
tenemos que utilizar el set,
o el dangerously set HTML,
tener cuidado con esto,
porque esto lo que significa,
es que nos estamos fiando,
de que este HTML,
no tenga alguna cosa,
de que nos esté intentando hackear,
o lo que sea,
con justamente inyección de código,
con XSS,
¿cómo lo evitamos?
a ver,
obviamente,
este contenido,
se supone que nuestro,
nos fiamos de nuestro propio contenido,
pero no utilicéis esto,
si estáis con algún tipo de información,
que viene de una base de datos,
y donde cualquier usuario,
puede añadir algo,
porque la podéis liar,
aunque seguramente puede ser,
que el GTM este,
o sea,
la librería que estamos utilizando,
para renderizar,
seguramente haga algo,
si veis que queda así,
hay una,
podéis esto estilarlo,
con Tailwind,
podríamos aquí empezar a estilar,
con Tailwind y tal,
pero si os interesa,
justamente la librería,
que hemos cargado,
esta librería,
tiene una cosa,
que se llama aquí,
CSS,
que podéis importar,
y podríais meter,
este CSS,
a manija,
para que quede más o menos,
luego a partir de ahí,
pues ya lo arreglaréis,
también con DangerSet y HTML,
y esto lo que te mete,
es como un CSS,
o debería meter un CSS,
¿vale?
veo que no lo mete,
pensaba que este CSS,
no se iba a arreglar,
porque veo que se ve igual,
DangerSet,
a ver,
si esto,
debería ser así,
¿no?
a ver,
vamos a ver,
si está metido algún HTML,
o sea,
el style este,
style,
FreshTelwind,
vale,
pues ahí sí que veo que ya lo ha metido,
¡ah!
es verdad,
vale,
se me olvidaba un detallito,
se me olvidaba un detallito,
perdón,
se me olvidaba un detallito,
para que esto funcione,
le tenéis que decir,
le tenéis que poner una clase,
si no,
Markdownbody,
esta,
¿ves?
es que tengo el Ritme aquí,
eso te pasa por no leer el Ritme,
¿vale?
y ahora,
¿ves?
ahora sí,
¿veis que ahora ha pillado como un estilo más normal?
bueno,
pues ese es el tema,
bueno,
aquí te está dando este error,
más que nada porque no entiende esta utilidad,
pero bueno,
esto lo podéis desactivar,
le podéis poner qué clases son las que sí que se pueden aceptar y tal,
pero bueno,
esto es un error de DenoFresh,
que evita o intenta que no pongas cualquier clase,
pero lo podéis ir en tweb.config,
aquí podéis ir poniendo todas las opciones,
todas las clases que queráis y tal,
pero bueno,
para que veáis cómo funcionaría esto,
vamos a hacer otra,
que es más interesante,
bueno,
más interesante,
porque nos falta,
claro,
ahora sí que tengo aquí el post,
pero lo que me faltaría justamente leer toda la carpeta,
¿no?
así que vamos a ver cómo puedo leer toda la carpeta,
sanitizado,
exacto,
sanitizado,
ahí está,
me perdí la cosa,
bueno,
Nicola,
no pasa nada,
te puedes quedar y luego ya le tiras para atrás,
no me fío ni de mí mismo,
joder,
está bien que no te fíes de ti mismo,
es una buena práctica,
vale,
¿qué pasa?
que ahora,
vale,
sí,
estamos mostrando el artículo,
pero si vamos a la home,
esto lo habíamos puesto a manija,
vamos a arreglar esto,
¿no?
vamos a hacer que aquí podamos ver todos los,
todos los,
los posts de una,
sin necesidad de tener que ir y ponerlos a mano,
¿no?
porque aquí conforme vamos poniendo,
quiero que aquí aparezcan todos mis artículos,
pues lo que vamos a hacer aquí,
es en utils,
y así vas a conocer una,
mira,
aquí vas a conocer dos cosas,
y una cosa es muy interesante,
y va a ser un premio por haberte quedado,
mira,
vamos a poner,
primero vamos a crear una función que te liste los posts,
así que vamos a tener aquí list posts,
¿vale?
para que nos liste todos los posts que tenemos,
y esto debería devolver una promesa de post,
creo que es,
hace tiempo que,
vale,
esto va a devolver un array de post,
y este post,
pues es el que tenemos,
o sea,
esto tendrá que ser un array,
seguro,
¿cómo vamos a leer esto?
bueno,
como te he dicho antes,
justamente,
una cosa que tiene muy chula Dino,
es que tú pones Dino,
punto,
y ya tienes aquí un montón de utilidades,
y una de ellas,
es la de leer directorios,
o sea,
que podemos hacer read,
dir,
le decimos cuál es el directorio que queremos leer,
no utilices el sync,
¿vale?
o sea,
que utilízate el normal,
y aquí podemos poner punto,
y aquí,
post content,
barra,
post,
y esto nos debería devolver,
no me acuerdo,
si usan la promesa o no iterable,
vale,
un iterable,
interesante,
guau,
que interesante esto,
porque vas a ver una sintaxis,
que no se suele ver mucho,
con los iterables,
los iterables,
son,
como estructuras de datos,
que tienen un método punto next,
que te da la siguiente iteración,
¿vale?
¿ves?
return asing iterator,
muy bien,
que jacopilot,
entonces,
¿qué pasa?
que para iterar esto,
tú no vas a estar,
no vamos a hacer esto,
no vamos a hacer aquí,
it punto next,
it punto next,
lo podrías hacer,
lo podrías hacer,
y lo podrías hacer en un loop normal,
pero lo interesante de los iterables,
es que tienes justamente un for,
que te ayuda a hacerlo,
de hecho,
aquí lo tenemos,
aquí me lo está,
me lo está chivando,
podríamos hacer un for await,
y aquí decirle const,
esto que sería,
la,
cada una de las entradas,
para,
el denotir,
¿vale?
esto es muy interesante,
bastante avanzado,
porque no se suele ver,
este tipo de construcción,
con iterables,
no sabía que el readdir,
normalmente,
por ejemplo,
note,
a la hora de leer un,
readdir note,
yo creo que da una promesa,
o sea,
creo que es un callback,
una promesa,
pero es muy interesante,
que devuelvas,
si ves,
un callback,
claro,
que tiene sentido,
pero es muy interesante,
que utilice un iterable,
porque tiene bastante más sentido,
y en temas de rendimiento,
mejor,
hostia,
como me ha petado,
esta página aquí,
perdón,
igual está petando,
igual está petando el stream,
pero es que,
no sé por qué me ha petado,
la página esa,
es algo así como,
yes,
reactive,
no es como,
yes,
reactive,
si tienes 10.000 posts,
¿cómo haces para mostrarlos por orden?
no tienes que cargar los 10.000,
bueno,
pero está interesante,
porque puedes cargar los que quieras,
no tienes por qué cargar los 10.000,
puedes cargar los 100 primeros,
por ejemplo,
y eso es lo chulo,
de los iterables,
que puedes parar cuando tú quieras,
ahí es lo que está chulo,
mido,
¿cómo hiciste para que se rendirice el markdown,
como html?
pero se lo acabamos de hacer,
ahora te lo enseño,
¿vale?
cuando volvamos,
un iterador de toda la vida en Java,
sí,
un iterador de toda la vida en Java,
pero es verdad,
que al menos a nivel de,
o sea,
a nivel de JavaScript,
no es muy común,
no es muy común,
los iterables,
o sea,
no son muy comunes,
no es una estructura muy común,
porque se suelen utilizar más promesas,
así que es interesante,
se puede leer con callback y con promesas en Node,
ya,
ya,
ya,
pero bueno,
si es con callback es con promesas,
es por eso,
petó porque no está hecha con Dino Fresh,
totalmente de acuerdo,
totalmente de acuerdo,
vale,
vamos a arreglar pues esto,
y os enseño un poquito más esto,
la verdad es que es una pena,
porque mucha gente,
esto,
pues,
luego la gente me pregunta,
¿pero qué tengo que aprender?
pues esto tienes que aprender,
es que es la leche,
hombre,
que si lo tienes aquí en tus manos,
y luego no quieres aprender,
este foro hace que no tengas que hacer un map de promesas,
luego hacer un,
sí que voy a tener que hacer un map de promesas,
seguramente,
vamos a tener que hacer un map de promesas,
justamente para poder seguir leyendo,
o sea,
vamos a hacer un for await,
para leer todas las entradas del directorio,
pero vamos a necesitar aquí un promises,
para luego recuperar la información de los posts,
entonces,
lo que vamos a hacer es,
vamos a recuperar la idea del directorio,
si esto va leyendo el directorio,
bueno,
a ver,
os lo voy a enseñar primero,
de otra forma,
vamos a ver aquí el entry,
el entry debería ser,
por ejemplo,
hello world.md,
y luego el otro,
vamos a hacer esto,
un momento,
list post,
vamos a ejecutar este list post,
a ver si funciona,
podríamos hacer otra vez un test,
pero bueno,
tampoco quiero que hagamos otra vez un test,
dino utils barra posts punto ts,
y este list post lo ejecutamos aquí,
voy a poner aquí una wait,
vale,
phone argument,
vision expected,
ah,
tiene que ser con el run,
vale,
que no se lo olvide,
run,
y esto no lo he guardado,
así que vamos a hacer esto,
ah,
espérate,
hay algo que no he hecho bien,
en este dir,
me faltaba aquí una cosita,
vale,
ahora otra vez,
vale,
que sí,
que si quiere que tenga acceso al fichero,
ves,
me ha devuelto esto,
vale,
mira,
importante,
el entry,
tenemos que recuperar el name,
o sea,
teníamos el name del entry,
y ahora,
para tener el id,
vale,
podríamos hacer esto,
no me gusta utilizar un re,
si puedo evitarme utilizar un regex,
me gusta evitarlo,
entonces voy a hacer esto,
me hace un split,
y me voy a quedar con la primera parte,
el split,
al devolverte un array,
pues,
¿qué pasa?
el split va a separar el nombre del archivo,
por el punto,
por lo tanto,
en la primera posición del array,
voy a tener el nombre del archivo,
y en la segunda posición,
voy a tener la extensión,
así que en la primera posición,
voy a dejar el id,
la segunda posición tendría la extensión,
pero no la voy a utilizar,
así que lo tendría así,
y aquí podríamos,
podríamos hacer una cosa,
ya que estamos aquí,
podríamos recuperar el post,
podríamos hacer,
const,
post,
await,
load post,
podríamos hacer esto,
y de hecho,
podríamos tener aquí todos los posts,
y podríamos hacer,
post,
punto,
push,
pero voy a hacer una pregunta de examen ahora,
a ver si sabéis,
qué es lo que pasaría con esto,
¿vale?
y esto devolver los posts directamente,
return post,
¿vale?
y vale,
dice que puede ser null o undefined,
post,
null tal,
tipo,
claro,
post puede ser undefined,
no,
no es asignable post o null,
ah,
porque post puede ser post o null,
tipo,
no es asignable el tipo,
es no asignable el tipo post,
no asignable el tipo post,
pero ¿por qué puede ser null esto?
por,
no sé,
ah,
por el load post,
por este,
por este,
que el load post este puede devolver null,
claro,
este es el que puede devolver null,
ajá,
en,
bueno,
lo que podríamos hacer,
que si post,
si no tenemos post,
pues continuamos y ya está,
muy bien,
TypeScript,
ahí está,
TypeScript,
esa es la magia de TypeScript,
esa es la magia de TypeScript,
vale,
vamos a quitar esto,
vamos a dejar,
ay,
he cerrado el que no era,
ah,
no,
lo he hecho bien,
vale,
vale,
dejamos esto por aquí,
o sea,
lo que estoy haciendo es,
estoy recuperando cada archivo,
que tenemos en la carpeta ContentPost,
empezaría por Hello World,
y para cada archivo,
lo que hago es cargar el post,
a partir de su idea,
aquí,
estoy cargando,
haciendo todo lo que habíamos hecho antes,
y este post lo guardo en un array,
y si tiene post,
si no es null,
pues lo guardo en el array,
y luego devuelvo todos los posts,
y esto,
pues debería devolverme,
bueno,
aquí podría poner un console.log,
para ver qué hace esto,
post,
que al final no lo he hecho,
pero ahí lo tenemos,
ahí podemos ver todo lo que está haciendo,
aquí tenemos el array,
con el ID,
y tengo los dos posts,
con Hello World,
y el del second post,
también es verdad,
que esto se podría simplificar,
o sea,
se podría hacer algo,
para evitar hacer el renderizado del HTML,
y todo esto,
pero es una utilización,
que te dejo,
para tu goce y disfrute,
pero podrías separar,
en lugar de hacer un load post,
que esto es lo que hace,
es todo el renderizado del HTML,
lo podríamos hacer aparte,
y tener uno que siga renderizado,
y otro que no,
porque aquí no lo vamos a necesitar,
pero,
os decía,
que íbamos a tener una pregunta,
de examen,
entonces,
¿qué nombre tiene este for?
Pues,
for a wait,
ese es el nombre del for,
entonces,
mi pregunta de examen es,
¿qué problema tiene este for?
¿Qué problema tiene este for?
Mientras vais comentando,
Midu,
¿hasta qué tiempo están abiertos,
los cursos que publicaste en Twitter,
como regalo de Navidad?
Están abiertos siempre,
mi contenido gratuito,
siempre y por siempre,
aunque hoy hay gente que ha hecho,
me ha regalado más de 300 subs,
Memory Leak,
no,
Memory Leak no,
Baraban tiene,
tiene,
tiene razón,
es lo que dice,
que se corre,
aunque ponga que es a wait,
esto es un error muy común,
que hay en muchas entrevistas de trabajo,
esto,
aunque sea asíncrono,
se está corriendo de forma secuencial,
¿vale?
Entonces,
no estamos paralelizando,
el trabajo que podría hacer el load post,
el load post,
podría,
podríamos paralelizarlo mejor,
¿qué problema hay?
Y de hecho,
para esto,
os voy a enseñar otra cosa muy chula,
que se llama Dino Bench,
¿vale?
Y claro,
ahora con dos posts,
no vamos a notar mucha diferencia,
¿vale?
No vamos a notar mucha diferencia,
pero si tuviésemos 500 posts,
igual sí que lo notamos,
y esto,
es peor,
que lo que vamos a hacer ahora,
esta sería,
voy a poner list post,
secuencial,
¿vale?
para,
por si luego lo queremos utilizar,
pero,
la forma correcta de hacer esto,
y esto,
os lo juro que es pregunta de entrevista,
porque yo lo he preguntado mil veces,
y mucha gente falla,
sí,
tiene problemas de memory leak,
tengo entendido que todos los for,
generan problemas de memory leak,
no creo,
o sea,
todos los for no generan problemas de memory leak,
la verdad,
y en este caso,
no me parece que tenga memory leak,
¿cómo sería un memory leak?
si le pones aquí lead post,
así,
y esto,
en lugar de hacer este,
utilizas ese,
ahí sí que la lias parda,
porque no puede tener un garbage collection,
y ahí la puedes guardar,
pero,
sí,
tú hubieras fallado,
y mucha gente hubiera fallado,
pero no pasa nada,
para el roca,
para eso estamos estos directos,
para eso te estás quedando,
para no fallar,
donde mucha gente fallará,
por desgracia,
vale,
¿cómo lo arreglaríamos?
Lo que tenemos que hacer,
es poner aquí un promises,
el for await,
lo necesitamos,
porque hemos dicho,
que el readdir,
es un iterador,
y es un iterador asíncrono,
y no hay otra forma,
de que lo podamos hacer,
podríamos transformarlo,
hay que hacerlo así,
y,
esta información,
esto de aquí,
lo vamos a quitar,
o sea,
lo que vamos a hacer es,
podemos hacer esto,
podemos hacer esto,
simplemente,
en promises.push,
lo que hacemos,
es,
pasarle,
la promesa,
del low post,
o sea,
que esto,
el promises,
va a ser un array de promesas,
y al ser un array de promesas,
lo que podemos hacer justamente,
es luego,
hacer un promisol,
entonces,
esta sería la forma correcta,
al menos,
para paralelizar el low post,
que sí que es una cosa,
que podemos hacer,
y aquí,
una vez que esto lo tenemos así,
pues,
hacer cons,
post,
await,
promise,
all,
promises,
aquí esperaríamos todas las promesas,
pero estas promesas las haríamos en paralelo,
¿vale?
En paralelo,
y,
y ya está,
lo que no sé,
lo que no sé,
claro,
cómo evitamos,
en este caso,
bueno,
a ver,
claro,
es que en este caso,
sabemos que no pueden ser,
a ver,
no deberíamos,
pero voy a hacer esto,
en este caso,
sabemos que estos son un array de post,
porque no puede ser null,
porque es un archivo que acabamos de encontrar,
o sea,
podríamos hacer más validaciones aquí,
para evitar que pushe las que,
o sea,
si un archivo no existe,
¿no?
Pues decir,
si no tiene ID,
pues,
continúa,
por ejemplo,
o si tiene ID,
pues,
hace el push,
vale,
para evitar esto,
pero,
más que nada,
para evitar eso en nulls,
tendríamos aquí los post,
y ya está,
a ver,
vamos a ver si somos capaces de utilizar esto,
vámonos aquí al index,
y aquí en el index,
ahora tenemos que hacer un poco lo mismo que hemos hecho aquí antes,
que sería lo del export const handlers,
le vamos a poner otra vez handlers,
no sé por qué no me pilla,
no entiendo por qué no me pilla el,
esto,
pero bueno,
no sé,
no sé por qué,
no le gusta context,
y aquí otra vez lo mismo,
¿vale?
es súper importante,
me voy a importar el list post,
para listar los post estos,
.ts,
voy a,
voy a ponerle los tipos,
para que no se me queje,
que se me está quejando ahí,
handlers,
ta, ta, ta,
este handlers,
y ahí sacas,
hay que sacarlo de,
handlers,
handlers,
y aquí vamos a poner server,
server,
creo que eso,
así,
vale,
ahora lo has tirado bien,
y aquí,
vamos a utilizar list post,
vamos a hacer const post,
recuperamos los post,
la lista de post,
y ya hacemos el return,
.context,
.render,
súper importante esto,
recordad,
si esto lo quitáis,
entonces no se carga la página,
no se va a poder cargar la página,
porque no sabe qué es lo que tiene que pasarle,
así que hay que hacer un context,
.render,
¿vale?
Llevamos handlers,
y esto es handlers,
ahora está bien,
entonces tenemos que hacer el .render,
para decirle,
tienes que renderizar la página,
si tú le quitas esto,
y guardas los cambios,
ves,
empty response,
porque no sabe que tiene que renderizar,
entonces le decimos context,
.render,
y lo que le pasamos aquí,
ves que le estamos pasando este objeto post,
es lo que va a recibir,
en las props,
¿vale?
Page props,
y este page props,
lo sacamos de,
aquí,
esto lo quitamos,
y esto por aquí,
vale,
y ahora,
en este props,
pues ya sabemos que tenemos,
el data,
de props,
y aquí deberíamos tener,
los posts de data,
y ahora,
pues nada,
en lugar de hacer esto,
como habíamos hecho antes,
vamos a hacer un post map,
article,
venga,
lo que diga,
lo que diga,
la hija copa,
ah,
mira,
muy bien,
me ha copiado lo que he hecho antes,
muy bien,
muy listo,
article,
vale,
vamos a ver si esto funciona más o menos,
vale,
pues fíjate,
ya tengo ahí,
hello world,
y yo sé que con post,
mira,
aquí hay una cosa muy interesante,
que además,
os va a servir,
muchas veces para las 20,
pero,
ya veis aquí,
que al menos tenemos este,
ya sabemos,
post.map,
y aquí nos dice el post,
bueno,
nos dice que es un específico,
aquí deberíamos poner que esto es post,
¿vale?
para recargar,
tener correctamente todo el typing,
y ya está,
pero ya tendríamos,
justamente con esto,
aquí hay una cosa que no me gusta mucho,
porque esto,
bueno,
da igual,
no pasa nada,
me gustaría que estuviese envolviendo mejor el hover,
pero bueno,
para que podáis ver al menos,
cómo estamos haciendo el hover,
vamos a poner esto aquí,
así,
y así,
ya sabemos cómo podemos entrar,
hay un problema aquí interesante,
porque claro,
tenemos los artículos,
pero los artículos no están ordenados,
no están ordenados por fecha,
y deberían,
fíjate que me sale el map viejo arriba,
el menos viejo abajo,
esto está mal,
entonces,
hay un error muy común,
en este caso es muy difícil,
pero claro,
para que lo tengan muy claro esto,
que es,
cómo se hace el short,
porque aquí,
cuando hemos devuelto los posts,
aquí deberíamos hacer post.sort,
pero el short no funciona solo,
hay que pasarle aquí un callback,
y tenemos que decirle cómo se tiene que comparar entre dos elementos,
¿no?
Entonces,
joder,
fija que o pilot es la hostia,
es la hostia,
de verdad,
todavía no lo ha pensado,
y sí,
sí,
es que es exactamente lo que hay que hacer,
tendríamos a y b,
¿vale?
y hay que compararlos,
a y b,
y entonces,
¿cómo los comparamos?
lo que tenemos que decirle,
es que lo haga por fecha,
este no está bien,
este que está haciendo aquí no está bien,
estaba mejor el otro,
lo que necesitamos es decirle,
que el del b,
vamos a tomar la fecha,
y vamos a recuperar el getTime,
el getTime,
te devuelve el tiempo en milisegundos,
que ha pasado desde 1970,
según esa fecha,
o sea,
desde 1970 hasta esa fecha,
cuántos milisegundos han pasado,
¿vale?
y entonces esto lo tenemos que restar al tiempo del a,
¿por qué lo hacemos así?
porque de esta forma,
bueno,
espérate,
sí,
yo creo que está bien así,
¿no?
ah,
pues no,
vea,
ahí,
espérate,
que esto hay que hacer un return,
return,
¿ves?
ahora sí,
vale,
es que siempre me cuesta,
cuando es,
cómo es ascendente y cómo es descendiente,
en este caso tenemos,
si queremos que sea descendiente,
tenemos que hacer que el b sea mayor que el a,
o sea,
que lo que devolvemos sea positivo,
por eso,
como este va a tener un número más grande que el otro,
o sea,
esto debería ser algo,
va a ser,
esto debería ser,
imagínate,
si pongamos que el primero,
este sería mil milisegundos,
por decir algo,
menos nueve mil milisegundos,
¿no?
porque en el segundo ha pasado menos tiempo que en el primero,
así que esta sería la forma de ordenarlo,
si lo que queréis es ordenarlo por tiempo,
o sea,
tiene que ser,
quédate en la cabeza,
que si lo que quieres es que sea de más a menos,
es menos b,
o sea,
b menos a,
ya está,
si es de más a menos,
b menos a,
y ya está,
así es como me intento acordar yo,
y ya,
y eso es como estamos ordenándolo,
si tú no le pasas ningún método de ordenación,
no te lo va a ordenar bien,
¿vale?
Siempre tienes que ordenarlo,
y ahora fíjate en otro detalle bastante importante,
y es que,
sí,
sí,
si más o menos sabes lo que haces,
tienes un autocomplice dopado,
sí,
sí,
totalmente,
totalmente,
si quisieras que fuese al revés,
tendrías que hacerlo así,
¿no?
tendrías que hacerlo así,
si quieres que sea el más antiguo arriba,
tendrías que poner el que tiene,
esto debería dar un valor negativo,
¿vale?
el valor negativo,
o sea,
esto sería ascendente,
porque va de menos a más,
y el otro sería descendiente,
porque va de más a menos,
¿ok?
así que,
tenedlo claro,
por si alguna vez lo necesitáis,
que estas serían las dos formas de las fechas,
¿vale?
descendiente,
b,
es mayor que a,
entonces b menos a,
ascendente,
a menos b,
esa es la diferencia,
¿vale?
punto,
pelota,
esto para hacer un short de un array,
en base a una propiedad de un objeto,
en este caso del datetime,
pero como la a,
mira,
esta pues es una,
mira,
ya en el chat,
empieza con la a de ascendente,
muy bien,
extract 98,
buen truco,
si queréis hacer algo,
ascendiente,
a de ascendente,
menos b,
y luego,
descendiente,
con b,
descendiente,
b menos a,
¿vale?
ascendente,
a menos b,
descendiente,
b menos a,
y esto funciona con,
con cualquier,
con números,
con lo que sea,
con lo que sea,
pueden ser números,
pueden ser fechas,
pueden ser lo que sea,
así que,
gracias,
de b nada,
b nada,
b nada,
pero sí,
ascendente,
a menos b,
ya está,
en nuestro caso queremos que sea descendiente,
de más a menos,
así que lo dejamos así,
y ya está,
y ahora,
pues ya estamos mostrando al menos los artículos,
¿ves?
ahora podemos ir para adelante,
para atrás,
y funcionando correctamente,
ahora,
vamos a hacer el despliegue a producción,
vamos a hacer el despliegue a producción,
¿por qué es menos?
¿no funciona con más para descendiente?
es que no,
porque con más siempre estarías devolviendo,
siempre estarías devolviendo un número positivo,
lo que necesitas es hacer la diferencia,
para que sea o negativo o positivo,
y que sepa,
cómo lo tienes que poner,
porque ten en cuenta que lo que devuelve short,
no es un valor numérico,
lo que tienes es que devolver positivo o negativo,
para saber en qué orden los tienes que poner,
¿sabes?
o sea,
tienes que decir,
o es positivo,
negativo,
o neutral,
porque si es neutral,
se supone que hay empate,
¿no?
o sea,
positivo o negativo,
es lo que tienes que decir,
y cero sería como,
es la misma posición,
así que no es un valor numérico,
o sea,
no te sirve nunca,
nunca en ningún caso,
poner un más,
a no ser que uno de los dos,
sea negativo,
porque ya lo has hecho antes,
¿vale?
pero que lo tengas,
lo tengas en cuenta,
vale,
dicho esto,
a ver,
¿qué más os quiero enseñar?
os quiero enseñar a hacer el despliegue,
¿por qué?
porque es muy fácil,
porque vais a alucinar,
y porque,
porque gratis,
y esto que hemos hecho ahora,
pues,
está muy bien aquí,
en mi máquina,
no es que sea la página más bonita del mundo,
pero vais a ver,
que podéis desplegarlo,
muy fácilmente,
gratis,
entonces,
todo el mundo atento,
porque esto,
os va a ayudar un montón,
vais a poder hacer proyectos con esto,
esto hemos aprendido,
que yo sé que no es muy bonito,
pero muchas veces,
para hacer una landing page,
para hacer vuestro portfolio,
lo podéis hacer,
y vais a ver que es muy rápido hacerlo,
y que se desplega súper fácil,
y que además tiene un rendimiento increíble,
entonces,
nos vamos a DinoDeploy,
¿vale?
esta es la página que vamos a utilizar,
en GitCAP,
voy a crear un repositorio,
le voy a llamar DinoBlog,
por ejemplo,
vamos a poner aquí,
y vamos a poner DinoFreshBlog,
necesitáis tener un repositorio también,
vamos a poner que sea público,
ponemos esto por aquí,
creamos el repositorio,
y,
no sé si me ha creado ya esto,
vamos a ver si esto me lo ha creado,
no,
pues GitInit,
y vamos a poner aquí,
añadimos esto,
le decimos,
la rama main,
y,
vamos a comitearlo todo,
a ver,
si necesitamos comitearlo todo,
lo bueno,
es que como veis,
no hay no modules,
no hay ninguna cosa rara,
¿sabes?
o sea,
lo podéis comitear todo,
sin ningún problema,
vamos a añadir aquí,
add,
DinoFreshBlogExample,
hacemos aquí un push,
bueno,
podías hacer git push,
ta ta ta,
pero bueno,
yo es que ya lo tengo así,
miramos aquí,
y aquí ya tenemos todo esto,
así que,
si a alguien le interesa,
me voy a hidratar,
gracias,
oye,
IDX,
felicidades por esos dos meses de suscripción,
IDX,
perdona que hace 10 minutos que lo has hecho,
pero es que me lo he perdido,
porque estaba aquí súper concentrado,
felicidades,
muchas gracias por estar aquí dos años,
Dios mío,
bueno,
ya tenemos el repositorio,
¿no?
Ahora,
SyncIn,
si no está registrado,
es totalmente gratis,
le das a New Project,
ya ves que yo tengo algunos proyectos,
le das a New Project,
y aquí puedes seleccionar un repositorio,
tiene diferentes formas de hacer despliegues aquí,
puedes hacerlo incluso desde aquí,
puedes hacer un despliegue de un código que quieras,
pero bueno,
en este caso queremos un repositorio,
le vamos a decir midudep,
y ahora Dino Fresh Block,
seleccionas la rama que quieres desplegar,
en este caso,
la de main,
y aquí tenemos,
si es automático o es con GitHub Action,
a ver,
esto es súper importante,
si necesitáis hacer algo más,
pues seguramente necesitéis una GitHub Action,
y entonces ya el despliegue no va a ser de cero segundos,
pero no es culpa de Dino Fresh,
es culpa tuya,
porque yo que sé que lo que necesites hacer en el build este,
pues será un problema,
ahora si lo haces automático,
esto significa que cualquier commit que hagas a master,
automáticamente se va a desplegar,
entonces esa es la forma rápida,
pero es verdad que a veces si necesitas tener test,
que se ejecuten antes de desplegar,
pues vas a necesitar el GitHub Action,
es un poquito más lenta,
pero aún así,
una vez que pasen los test,
es bastante instantáneo,
lo voy a poner automático,
más que nada para que alucines,
fíjate ahora que me está diciendo
que tengo que decir qué archivo es,
y aquí tengo una estrellita,
como te he comentado al principio,
el main es el punto de entrada
de nuestra aplicación en producción,
por lo tanto tenemos que seleccionar main.ts,
y ya está,
ahora le damos aquí a link,
linking,
linking park,
clonando repositorio,
descarga unas cuantas cositas,
vamos a ver cuánto tarda,
packaging complete,
y
ya tenemos en producción nuestro blog,
así de rápido,
así de rápido,
así de rápido e instantáneo,
o sea,
rápido e instantáneo,
os voy a decir una cosa
súper interesante de esto,
súper,
súper,
súper interesante,
¿vale?
Lo interesante de esto
es que muchos de ustedes,
os voy a dejar la URL,
¿vale?
Muchos de ustedes
seguramente me,
no sé,
me estén viendo desde Sudamérica,
Norteamérica,
Centroamérica,
entonces les voy a pedir una cosa
para que vean la potencia que tiene esto,
porque esto no es un despliegue normal y corriente,
esto es lo que ha hecho desplegar en el Edge,
o sea,
esto ha distribuido esto que hemos visto
por todo el mundo,
bueno,
si abren las herramientas de desarrollo
y entran a la página del blog
y les dan aquí,
van a ver,
en encabezados,
van a ver una cosa súper interesante,
¿veis aquí que pone server?
Y aquí pone
Dino,
GCP,
Europe,
Southwest,
1,
pues aquí tienen justamente
Europe,
Southwest,
no sé dónde será,
lo podemos buscar,
GCP,
mira,
es justamente,
podemos ver que está desplegado
en el cloud de Google
y podríamos ver que lo ha desplegado
justamente donde lo ha desplegado,
aquí podemos ver todas las zonas
que,
donde lo ha desplegado,
en este caso,
Southwest,
1,
Madrid,
España,
o sea,
está aquí al lado,
está bastante cerca,
Madrid,
España está súper cerca,
o sea,
lo ha desplegado en España,
en mi propio país,
a cada uno de ustedes
le saldrá una cosa diferente,
a alguien le saldrá Sudamérica,
le saldrá Norteamérica,
Estados Unidos,
México,
yo qué sé,
le saldrá diferentes,
pero esta es la gran potencia
y muchas veces yo sé que me pongo muy pesado
y muchos de ustedes,
pues seguramente me ven y dicen,
pero ¿por qué se pone tan pesado
con las Edge Functions?
Pues este es el tema,
lo que acabamos de hacer es que
en muy pocos segundos
he desplegado este blog,
que sé que es un proyecto muy sencillo,
pero bueno,
porque os quería enseñar sobre todo código,
y se ha desplegado súper cerca de ustedes,
este proyecto
tiene que tener la,
no la misma latencia quizá,
pero una latencia muy baja,
independientemente de donde estén situados,
que es algo totalmente diferente
a cuando lo hacemos
y desplegamos,
por ejemplo,
un servidor,
porque el servidor está en un sitio,
que sí,
que al final podemos intentar
que haya más de un servidor comunicado
y tal,
pero es mucho más complicado normalmente,
entonces,
esto lo pueden comprobar
para que vean esto de Dino,
cuando entra la herramienta de desarrollo,
se van a la red,
refrescan,
y aquí en encabezados,
pues verán aquí el servidor,
y aquí pues podrán ver,
a veces incluso pueden ser que cambie,
puede ser que puedan ver en algún momento
que en lugar de Southwest 1,
aparezca el 2,
¿por qué?
Porque el 1 y el 2,
o sea,
ves,
el 1 está en Madrid,
el 2 seguramente o estará en Madrid
o no hay por ahora,
pero igual o el A o el B,
o sea,
que puede cambiar
porque dependiendo de la latencia
te puede llevar a un sitio u otro,
pero al final es súper,
súper rápido,
¿no?
Y luego,
¿qué más sobre esto
que os quería comentar?
Ah,
sí,
claro,
lo que os quería comentar
es que si veis aquí,
vamos a ver esto en mi blog,
¿no?
Ponemos aquí mi blog,
mi blog,
este blog,
el blog de Midu,
el blog de Midu,
guardo los cambios,
¿vale?
Voy a poner aquí
el blog de Midu,
¿vale?
Lo voy a subir,
¿vale?
¿Veis que lo he subido,
¿no?
¿Vale?
Voy a volver al navegador
y aquí voy a refrescar la página,
no está todavía,
otra vez,
otra vez,
¿cuánto ha tardado?
No ha tardado absolutamente nada,
¿no?
Y si necesitas una base de datos,
¿cómo se haría?
¿Todos tienen que acceder
a la misma base de datos
o la tienes que tener replicada?
La deberías tener replicada,
de hecho,
por ejemplo,
y eso cada vez se lleva más,
AppStash,
tú lo que haces es tener replicada,
yo tengo replicada,
para que veáis,
AppStash,
el AppBengis,
vais a ver cuánto dinero
me estoy gastando,
el AppBengis,
solo lo de AppStash,
que es un dinero,
ah,
no,
mira,
46,
no está mal,
ah,
pero creo que,
creo que más,
lo que pasa es que he pagado hace poco,
creo que he pagado hace poco,
creo que he pagado hace poco,
pero bueno,
el tema es que aquí ves,
está global,
esto significa que está replicada
por todo el mundo,
entonces,
no es exactamente,
a lo mejor,
los mismos,
la misma base de datos,
o sea,
los mismos sitios
que en DinoDeploy,
pero,
igualmente está replicada,
pero hay un montón,
hay un montón de sitios
que va a estar replicada,
el blog soporta Mardown,
que llegué tarde,
hemos hecho nosotros,
lo de que soporte Mardown,
de hecho,
lo hemos hecho,
lo hemos transformado nosotros,
para ver cómo se transforma,
otra cosa que es súper interesante,
porque espérate,
que es que hay más cosas,
porque,
a ver,
el blog de Midu,
vale,
está muy bien el blog de Midu,
pero fíjate que si voy aquí,
¿cuánto creéis que de JavaScript
que se está cargando?
¿Cuánto se está cargando?
De JavaScript.
¿Cuánto creéis que el blog de Midu
está cargando de JavaScript?
No está cargando JavaScript,
está cargando cero,
todo,
todo lo que veis,
todo,
con service al rendering,
que estamos utilizando PRIAC,
tiene aquí todo el CSS,
todo,
todo,
que sé que es una página sencilla,
pero tiene cero JavaScript,
no tiene JavaScript,
no ha descargado nada de JavaScript.
Ahora,
¿qué pasa si realmente necesitas JavaScript?
Vamos a ver esto en un momentito,
¿vale?
El tema,
imagínate que en el Hello World este,
por decir uno,
en el blog,
claro,
cuando quieres hacer una página estática,
todo esto está muy bien,
pero imagina que en componentes,
pues,
no sé,
vamos a tener,
mira,
este button lo vamos a reutilizar,
¿vale?
Y vamos a poner,
is browser,
no sé qué,
ah,
mira,
esto está muy chulo,
pero bueno,
por ahora vamos a quitar esto,
vamos a poner aquí,
like button,
like button,
button,
imagínate que quieres tener,
pues,
un botón de me gusta,
en cada,
ay,
anda que yo también,
el useState va aquí arriba,
useState,
ay,
esto me da rabia,
que no tiene bien el autocomplete,
eso es una cosa que deberían arreglar,
y esto es barra hooks,
¿vale?
El useState en Preac se saca de Preac barra hooks,
pero bueno,
muy,
por lo demás es lo mismo,
¿vale?
Es lo mismo,
set like,
like,
set like,
useState,
false,
¿vale?
vamos a poner aquí,
un corazón,
un corazón así,
o un corazón,
corazón blanco,
o negro,
vamos a ponerlo negro,
venga,
negro,
vamos a decir,
si like,
entonces,
el,
este,
y si no,
este,
ahora se verá bien,
me parece,
y vamos a cambiar también el texto,
¿no?
si me gusta,
dejar que me guste,
aquí,
me gusta,
¿vale?
Y este botón,
vamos a utilizarlo por aquí,
en el article,
vamos a ponerlo justo después de esto,
button,
¿vale?
Esto por aquí,
¿vale?
button,
¿esto es donde lo he puesto?
Ah,
esto es la home,
esto no va aquí,
perdón,
esto va aquí,
¿vale?
Dentro aquí,
ah,
vale,
button is not defined,
¿vale?
Porque me lo tengo que traer por aquí,
import button,
.tsx,
creo que es,
vale,
ya tenemos ahí el botón de me gusta,
es un botón muy sencillo,
¿eh?
Me lo perdonáis,
pero bueno,
la idea es que podamos ver cómo funciona esto,
voy a poner aquí el header,
para que me separe esto bien,
porque si no me lo ponen una línea,
y eso no está bien,
vale,
ya tenemos aquí el me gusta,
¿qué pasa con esto?
¿qué pasa con esto?
Imagínate que,
pues tenemos aquí un onclick,
un click,
y le decimos aquí,
pues que lo típico,
bueno,
lo típico no,
porque esto no es lo que deberías hacer,
vamos a poner un alert,
vale,
le doy,
le estoy dando click,
y no funciona,
no funciona,
bueno,
esto es muy importante,
porque vamos a tener que cambiar el chip,
desde ya,
no solo por DinoFresh,
ya has visto que en Next.js también,
están haciendo este tipo de cambios,
en los que por defecto,
van a hacer que los componentes,
solo se renderizan en el servidor,
y en Next.js,
vamos a tener que poner un string,
que sea useClient,
para que funcionen,
y todo este tipo de cosas,
ahora bien,
¿qué pasa?
que en el caso de DinoFresh,
para que los componentes funcionen en el cliente,
los tenemos que poner en un sitio en concreto,
este componente,
por ejemplo,
ves que yo le doy click,
como en Astro,
es que esto va a ser lo de siempre,
entonces,
ves que este botón,
yo le estoy dando al botón,
y este botón no funciona,
porque este un click,
literalmente,
lo está ignorando,
lo está ignorando,
por lo tanto,
aunque yo pusiese aquí,
este set like,
pues le pusiera set like,
y pusiese esto,
es que no va a cambiar,
no,
no cambia,
no está cambiando el estado,
este estado que tengo aquí,
no cambia nunca,
no,
no funciona para nada,
para que nosotros hagamos que realmente esto funcione,
lo tenemos que poner en una isla,
¿qué es una isla?
a ver,
te voy a intentar poner en contexto,
porque esto es una cosa,
Jason Miller,
Airlines,
blog,
a ver si encuentro el blog,
porque es muy interesante,
vale,
Jason Format,
este artículo,
te lo recomiendo muchísimo,
porque este artículo ha tenido un impacto increíble,
en el mundo de la arquitectura de la web,
y sobre todo,
sobre cómo vamos a intentar mejorar el rendimiento de aplicaciones de RIAG,
de PRIAC y todo esto,
¿no?
Y es lo que utiliza Astro y Dino Fresh a la hora de dar interactividad solo a partes de nuestra página,
y sí,
este blog es justamente del creador de PRIAC,
¿vale?
Entonces,
¿qué es la arquitectura de islas?
La arquitectura de islas,
lo que viene a decir es que nuestras páginas deberían ser algunas partes estáticas,
y solo aquellas partes que necesitamos que tengan interactividad son las que deberían cambiar,
por ejemplo,
imagínate una página que tiene un header,
que tiene una barra lateral,
un carrusel de imágenes,
pero a lo mejor el contenido,
todo el texto,
no tiene sentido,
o sea,
en este blog,
¿tiene sentido que todo este contenido esté en JavaScript,
en el cliente?
No tiene sentido.
Esto es algo que Quick,
que es un nuevo framework,
lo lleva al límite,
porque es mucho más granular,
pero yo creo que al menos el sistema de arquitecturas lo vamos a necesitar,
y va a ser bastante fácil de implementar,
como lo vamos a ver ahora.
Entonces,
vamos a tener partes de nuestra página que son estáticas,
y otras partes que son interactivas,
y esas partes que son interactivas se le llaman islas,
así que imagínate que todo el mar sería estático,
y las islas son las que van a tener como interactividad,
son las que van a tener la importancia,
digamos,
¿no?
Entonces,
en este caso tenemos este botón aquí,
que como puedes ver no funciona porque ahora es estático,
pero lo vamos a convertir en una isla de interactividad.
Para eso es súper fácil en Deeron Fresh.
Aquí en Islands lo que tenemos que hacer,
voy a quitar este archivo que no necesitamos,
en Islands lo que voy a hacer es simplemente mover el botón aquí,
¡pam!
Aquí lo tenemos.
He movido el button,
lo he puesto en Islands,
estaba en components,
lo he puesto en Islands,
y ya está,
¿vale?
Y ahora,
aquí el import lo voy a cambiar,
en lugar de components voy a poner Islands,
¿vale?
Guardamos los cambios,
y ahora si le doy click,
pues sí que se funciona,
pero esto es porque algo he hecho aquí que no le ha gustado,
vale,
porque ha petado alguna cosa.
Espérate,
¡ay!
Espérate,
este button,
components,
¿qué ha pasado?
Espérate,
que a lo mejor en algún sitio he estado utilizando el button este.
Amigo,
aquí,
es que estaba aquí este import que me estaba liando,
vale,
ya está.
¿Ah?
Islands más,
ah,
vale,
esto es un tema importante.
Bueno,
está bien,
las islas tienen que ser export default,
¿vale?
Igual que las rutas,
igual que las rutas son export default,
pues las islas también lo tienes que hacer.
Así que vamos a adaptar el import,
y ya está,
importamos el botón así,
volvemos a hacer el start,
y ya está.
Ya tenemos esto en una isla,
ya lo estamos importando correctamente,
hemos cambiado que el export sea por default en lugar de nombrado,
importante,
porque es como lo necesitan las islas,
es como tiene que funcionar,
también es que puede tener sentido,
porque tampoco esperan que le pongan muchos nombres diferentes,
y ahora,
pues ya está,
ya lo tenemos funcionando.
Ya tenemos justamente este botón con interactividad,
solo esta parte es la que tiene interactividad en nuestra página.
¿Qué hemos conseguido con esto?
Obviamente interactividad,
obvio,
¿no?
Alguien me dirá,
bueno,
interactividad,
pero aparte de eso,
fíjate,
vamos a put our first island,
¿no?
Vamos a subir estos cambios,
vamos a desplegarlos,
porque total,
ya lo tenemos todo súper bien,
¿no?
Que en unos segundos deberíamos ver aquí nuestro botón,
un segundo,
dos segundos,
tres segundos,
cuatro segundos.
Bueno,
no está mal,
cuatro segundos para hacer un despliegue.
Bueno,
entonces,
aquí tenemos nuestra isla,
¿vale?
Me gusta,
dejar que me guste.
¿Qué es lo interesante de esto?
Pues que si vamos a la red
y refresco,
vale,
ahora sí vas a ver
que estoy empezando a cargar JavaScript.
Ahora sí que está cargando JavaScript.
¿Por qué?
Porque,
claro,
necesita todo el tema de los estilos para cambiarlo,
o sea,
solo está hidratando,
solo está volviendo a renderizar en el cliente
la parte de la isla.
Por ejemplo,
¿ves este ir island button?
Si vamos aquí,
aquí justamente es donde tenemos nuestro querido botón.
Este,
este es nuestro botón.
Sí,
bueno,
por aquí debería aparecer.
Vale,
¿ves?
Dejar que me guste,
me gusta,
o sea,
solo esa parte es la que se está enviando por JavaScript.
Todo lo demás,
todo lo demás no se está enviando.
Por ejemplo,
this is heading 2,
si lo buscases esto en JavaScript,
no lo tendrías.
Esto es una diferencia muy importante respecto a cómo funciona NextDS,
por defecto,
al menos por ahora,
aunque poco a poco vamos a ver que se está utilizando React Server Components
para crear islas de una forma ligeramente diferente,
¿no?
Pero esta es un poco la idea.
La idea es tener solo en interactivo en las islas
lo que realmente necesita interactividad.
Así que,
fíjate,
tú entrarías en el blog,
el blog tiene cero JavaScript,
aunque hemos utilizado Preact, Tailwind y todo para utilizarlo.
¿Esta será la nueva tendencia?
Esta es la tendencia.
O sea,
no sea nueva tendencia,
esta es ya la tendencia.
De hecho,
los Reaction Server Components no hacen exactamente esto,
pero es la idea.
Y esto lo hace Astro,
lo hace Dino Fresh,
lo hacen cada vez más.
La idea es que esto tiene todo sentido,
porque al final,
una de las cosas básicas de la programación,
una programación del rendimiento web,
es que necesitamos enviar menos información.
Necesitamos que cada vez el usuario reciba solo aquella información que necesita.
Eso es básico en el rendimiento.
¿Y qué estábamos haciendo con React o con Next.js durante mucho tiempo?
Que no es una cosa cara,
lo han arreglado la gente de Next.js.
Estamos enviando toda la información que necesitaba.
Mira,
por ejemplo,
para que tengas una idea,
NextBlockExample.
Voy a buscar un ejemplo de Next.js que sea un blog.
A ver si lo encuentro.
BuildingBlockWithNext.js.
A ver si encuentro un ejemplo de blog,
para que lo veamos.
¿Vale?
Y vais a ver la diferencia,
ya no solo de cuánto ocupa,
sino vais a ver la diferencia de...
A ver si...
Creo que este tiene buena pinta.
Este tiene buena pinta.
Os lo enseño.
Si lo carga.
No veo que cargue.
Ah, no.
Está petando.
Maximum Cal...
Va.
O sea, ha petado este ejemplo.
Pues nada.
Quería ver si había algún ejemplo de Next.js,
pero es que no veo ningún ejemplo.
Si tenéis alguno por ahora.
Entonces me...
Ah, Lerob.
Pero Lerob lo habrá pasado a Next.13, ¿no?
Ya.
Lo habrá pasado a Next.13.
Lo habrá pasado a Next.13, me imagino,
y lo habrá arreglado ya.
Es que con Next.13 lo podéis llegar a arreglar.
Pero veis aquí,
hay un montón de JavaScript,
pero un montón.
Si buscamos entre el JavaScript,
si vamos a Search,
aquí busco esto,
por ejemplo,
Feature Post.
Mira, aquí.
Aquí tenéis el tema.
Mira.
¿Veis esto?
O sea,
esto,
esto es que no sabría explicarlo súper bien
para que lo entendáis, ¿vale?
Pero para que entendáis,
¿qué es lo que está pasando?
Lo que está pasando aquí,
lo que está haciendo aquí en Next.js,
es por un lado,
está haciendo Service.Rendering.
Y el Service.Rendering está enviando todo el string, ¿no?
O sea,
ha renderizado en el servidor toda la página
y se la está enviando al cliente
ya todo el string,
todo el churro.
¿Qué pasa?
¿Cuál es el problema al que nos estamos enfrentando
y por qué la arquitectura de Islas
intenta solucionar todo esto?
El problema que tenemos aquí
es que esta información que tiene
en Louis Robinson,
por ejemplo,
este título,
que es obvio que es estático.
O sea,
este título es estático.
No necesita estar en JavaScript en el cliente
porque no va a cambiar,
no tiene un estado,
no es interactivo,
es estático.
Pero,
en cambio,
podemos ver,
si vemos,
si miramos entre el JavaScript,
podemos ver aquí
toda la información
que tenemos en el JavaScript,
como por ejemplo,
este Children,
Feature Post.
Esto,
esto,
que es estático,
esto sobra.
Esto,
lo único que está haciendo
es dañar el rendimiento
de la página
porque no le está beneficiando
absolutamente nada
que esto,
tengas que descargar el JavaScript,
volver a renderizar en el cliente,
bueno,
hidratar en el cliente
que lo que diríamos es,
vale,
tú me has dado en el servidor
este string
y ahora en el cliente
lo que voy a hacer es
asegurarme que debería renderizar lo mismo
y lo voy a dotar de vida.
Pero no tiene sentido dotarlo de vida
porque es estático,
pero en cambio lo hace.
En cambio lo hace,
¿sabes?
Entonces no tiene sentido.
Entonces,
mira,
hay un muy buen ejemplo,
¿no?
Y si tiene cambio de idioma,
si ocupa JavaScript,
os voy a decir una cosa
que es bastante polémica,
pero que yo recomiendo
que la gente se lo piense dos veces.
Hay una cosa
que no os he contado
de Dino Fresh
y es bastante polémica
y es que Dino Fresh
no tiene,
a día de hoy,
SPA.
No tiene SPA.
Dino Fresh,
los enlaces
no tienen
client-side transitions,
no es client-side rendering,
es todo,
todo es SPA.
Pero,
¿qué pasa?
Dino Fresh apuesta por una cosa.
Dino Fresh apuesta
que una página
que se renderiza
en un tiempo menor
de 100 milisegundos
no se nota.
O sea,
un humano no lo nota.
O sea,
si tú vas aquí,
si vas aquí,
en Dino Fresh,
por ejemplo,
y vas a Hello World,
o sea,
no notas,
normalmente va tan rápida
que no notas la diferencia.
¿Por qué?
Porque la carga
es de menos de 100 milisegundos.
Que haya un client-side
no lo vas a notar.
Un single-page application
es cuando,
en lugar de recargar
toda la página,
mira,
esto sería un single-page application,
¿no?
Estás en la home
y dices,
ah,
pues voy a esta página.
En lugar de recargar
toda la página,
¿no?
Pam.
Lo que hace es
ese playholder
y todo esto.
¿Pero cuánto ha tardado
ese playholder ahí en medio?
¿Cuánto más o menos ha tardado?
Bueno,
pues no sé,
100,
200,
200 milisegundos.
Ahora va bastante rápido.
No sé,
pero si buscamos esto,
no sé,
200 milisegundos,
300 milisegundos,
algo así.
Entonces,
¿qué es lo que pasa?
Que lo que dice Dino
es,
asegúrate
de que tu página
funciona por debajo
de 100 milisegundos
y punto.
Y en este caso,
es verdad que es una página
muy sencilla,
¿vale?
Es una página muy,
muy,
muy sencilla.
Pero aunque sea una página
muy sencilla,
lo cierto es que
yo ya he hecho algunas pruebas
y haciendo server-side rendering
en Dino Fresh
es que tarda muy poco.
Por lo tanto,
si te aseguras
de que lanzas
el JavaScript mínimo
y el renderizado
lo haces en el servidor,
realmente,
como la latencia
es tan baja
porque está cerca
del usuario,
por lo que hemos visto antes
que los servidores
están bien localizados
en todo el mundo,
la latencia es tan baja
y no se nota.
Y lo que buscan
es simplificar eso.
Entonces,
ahora la pregunta,
¿pero qué pasa
si tienes un cambio de idioma?
Pues si tienes un cambio de idioma,
lo que harías en Dino Fresh
es recargar la página.
Uno de los problemas
que a veces tenemos
es que queremos hacer
como SPA,
como Single Page Application,
lo queremos hacer todo.
Queremos que todo sea SPA.
Y hay veces
que no tiene,
no vale,
no vale la pena.
Por ejemplo,
en Fotocasa,
voy a explicar un caso
para que lo entendáis,
en Fotocasa,
en su día,
abajo del todo,
no lo veis,
pero abajo del todo
hay un cambio de idioma.
Aquí.
Yo cuando estaba al principio
en Fotocasa,
esto era una SPA,
lo cual obligaba,
había algunos,
había algunos,
algunos retos.
¿Cómo hacías
que toda la página
se volviese a recargar,
que no sé qué?
Porque claro,
esto,
o sea,
¿cómo cambiabas
todo el contenido
sin recargar la página
porque querías
que fuese una SPA?
Y yo,
lo que dije fue,
pues que le den por culo
a la SPA.
O sea,
no tiene sentido
intentar poner
un montón de,
intentar solucionar
un montón de retos
donde no hay un problema.
Porque,
¿cuántos usuarios
van abajo al footer
a cambiar la página?
Es que son muy pocos.
No tiene sentido
intentar hacerlo todo
en una SPA.
¿Dónde tiene sentido
hacer una SPA?
O sea,
la SPA a veces
tiene sentido
cuando realmente
marca la diferencia
en la experiencia
del usuario.
Por ejemplo,
¿dónde tiene aquí
todo el sentido?
En Fotocasa
tiene todo el sentido
cuando tú estás aquí
y dices,
¿quiero ir al siguiente
detalle?
Claro,
fíjate
que
vas
y no notas nada.
Es que directamente
cambia la información
súper rápido
y ya está.
esa es una buena experiencia
que quieres tener
porque no recargas
toda la página
porque no quieres
que haya un flasheo
no quieres que tenga nada.
Lo que quieres es
le ha dado
y directamente
aparecen las nuevas.
Ya os digo yo
que también creo que
es mejorable
la experiencia.
Pero bueno,
es mejorable
porque se quedan
las imágenes anteriores
creo que debería cambiar
de otra forma.
Pero aquí tiene sentido.
Tiene sentido.
¿Dónde no tiene sentido?
Por ejemplo,
oye,
si estás aquí en Fotocasa
y de repente
quieres seguir
a la guía de barrios
oye,
no pasa nada.
No pasa nada
que se vuelva a renderizar
toda la página
porque al final
no es algo
que el usuario
se vaya...
Es más interesante
que la página
tarde poco en cargar
que no intentar
hacer una SPA
porque la SPA
vas a tener ahí
un montón de retos
de que intentar cargar
el JavaScript
solo cuando lo necesites,
cómo haces
que la top bar
se quede
donde se tiene que quedar
y todo este tipo de cosas.
Y entonces
me parece muy interesante
por eso.
Entonces,
cambios de idiomas.
Yo normalmente
cambios de idiomas
recargaría directamente
la página
y a tomar por saco.
Eso es lo que haría yo,
¿vale?
Pues esto es Dino Fresh.
A ver,
hemos hecho
poquita cosa
pero hemos hecho ahí
lo de
lo de la interactividad,
desplegar a producción...
Bueno,
que sepáis
que podéis tener
archivos estáticos
en la carpeta
de...
de...
en la carpeta esta
de Static
pero que hay una forma
interesante.
O sea,
aquí cuando en Static
ponéis,
por ejemplo,
Static,
aquí ponéis
una imagen,
por ejemplo,
si yo me voy a
Midudev,
voy a guardar una imagen
de Midudev
y la voy a poner por aquí,
logo,
pam,
y tenemos aquí
el logo este de Midudev.
Vale,
pues si no recuerdo mal,
para que lo utilicéis,
tenéis que en rutas,
index,
vamos a poner por aquí,
import asset,
¿vale?
y esto lo sacamos aquí
de fresh
utils.ts
y aquí en asset
pues ponemos el image,
vamos a quitar este
blog de Midudev
que hemos puesto aquí,
vamos a poner aquí
el image,
image source
y aquí
tendrías que utilizar
asset
y decirle
la ruta,
por ejemplo,
logo.png
y con esto,
¿veis?
ya tenéis ahí
el asset,
o sea que esto ya se asegura
directamente
de que lo encuentra,
está chulo porque
no te tienes ni que preocupar
de la ruta,
si tienes que hacer un import,
sino que simplemente
es como si estuvieses
dentro de la carpeta static
independientemente
de dónde estás,
de hecho,
creo que funciona así también,
¿veis?
también funciona así
y esto me gusta mucho,
me gusta mucho
porque no tienes que acordarte
realmente de
cuál es la ruta,
la que tienes que
start ni nada,
sino que simplemente
pones asset,
le pasas el string
como si estuviese
dentro de la carpeta
independientemente
de qué ruta
te encuentras
y todo
y ya está,
me gusta mucho
de cómo lo hacen,
simplifica muchísimo
el tema,
pero bueno,
hay gente que le gusta
más el import,
a mí,
yo sinceramente
me gusta mucho más este,
si me preguntáis,
otra cosa interesante
de esto
es que ni siquiera,
o sea,
otra cosa que podéis hacer,
por ejemplo,
en utils
podéis tener aquí
los assets
y este import asset
en lugar,
si no lo queréis ver
en todos los sitios,
lo podríais tener aquí
y podéis exportar
todos los assets
aquí,
podríais hacer
export,
const,
logo,
y este sería
el asset del PNG
y este logo
pues ya lo podéis utilizar
aquí directamente,
bueno,
tenemos que importarlo,
voy a importar,
logo
y ya está,
ya lo tendríais,
entonces tendríais
como un,
esto sería una buena idea
para hacerlo
en lugar de estar tirando
todo el rato
de utilizar
import asset,
import asset,
yo os recomiendo
que tengáis
un fichero
assets.ts
y ahí directamente
lo que hacéis
es decir,
vale,
pues ahí exporto
todos los assets
que necesito otro,
pam,
lo copio,
lo exporto,
le pongo un nombre
que quiera
y ya está,
a no ser que sea algo
que sea dinámico,
que entonces en ese caso
también podríais hacer
incluso una función
para evitar
tener que repetirlo
constantemente,
pero esto sería
una forma de trabajar
con assets estáticos
en Dino Fresh
y ya veis que es súper fácil
y no os tenéis que preocupar
de nada del tema
de si es complicado
la ruta
y todo esto.
Y ya,
y esto es interesante
porque además
se cachea,
que tenerlo en cuenta
porque dependiendo
de los nombres y tal
a lo mejor
se os queda cacheado.
Tiene otro tema interesante
que es lo de los
Mydelwears,
que puedes crear
Mydelwears,
puedes crear rutas
si tú aquí creas un,
es con barra baja,
si tú aquí creas una ruta
que sea
mydelwears.ts
esa sería
la que se utiliza
por ejemplo
para todo el tema
de autenticación.
Podrías tener aquí
un Mydelwears
y en este Mydelwears
puedes guardar un estado
y este state
veis que pone aquí
state no sé qué
no sé cuánto.
Vale,
pues este state
puedes setear ahí headers
que eso va muy bien
para temas de autenticación.
Puedes tener un estado
que esto puede ir bien
también para temas
de localización,
por ejemplo,
podrías poner aquí
detectar cuál es el idioma
del usuario
y ponerlo aquí.
Y lo interesante
es que este state
entonces puedes acceder
a ello en los handlers.
Aquí podrías ver
el console.log
context.state.data
y si esto ha ido bien,
que no sé si he puesto,
ves,
pone aquí mydata,
mydata viene de este mydata
y este state
es para cada usuario.
Esto es un Mydelwears
por donde pasan
todas las peticiones
que se comparte
solo a nivel
de cada request.
Así que aquí puedes hacer
desde leer cookies,
temas de autenticación,
un montón de cositas.
Ver en qué idioma
quiere ver el usuario
la información.
Aquí podrías hacer
temas de A-B testing.
¿Ese state
se almacena en local storage?
No.
Este state
se almacena en memoria
y dura lo que dure
la request.
Entonces,
lo que hace esto aquí
es poner el state
y aquí este state
le llama state,
pero esto solo a nivel
de request,
¿vale?
De petición.
No tiene nada que ver
con los states
de React ni nada.
Y ya está.
Hola, amigo.
Esto es todo
de Dino Fresh.
Lo que veo es que
básicamente tiene
todo lo de Next10
pero a su manera.
Efectivamente.
Esa sería una
muy buena aplicación.
Tiene todo lo de Next10
a su manera
con diferencias importantes
y muy interesantes.
Y muy interesantes.
¿Por qué?
Porque creo,
sinceramente lo creo
y os lo he dicho,
creo que el 2023
va a ser el año,
no digo que Dino Fresh
vaya a superar
a Next10,
no digo eso.
Pero de verdad
creo que vamos a ver
más desarrollos
con Dino Fresh
por dos cosas.
Uno,
por tema de rendimiento,
o sea,
solo tenéis que ver esto.
PageSpeed Insights,
¿vale?
Vamos a ver la de Lee,
a ver una cosa,
solo por curiosidad,
a ver cómo...
PageSpeed Insights
es una herramienta
para ver el rendimiento
de la página web.
Vale,
va bastante bien,
o sea,
la de Lee Rob
va bastante bien
porque la tendrá
bastante optimizada
y tal,
¿vale?
98 de rendimiento,
o sea,
al final es verdad
que no es una página
que tiene más cositas,
también es normal.
Pero si miramos,
no sé,
la de Dino,
por decir algo,
no sé,
también tiene cosas
por ver,
a ver cómo es.
La de Dino
está hecha con Dino Fresh
y tengo curiosidad
por ver cuánto...
Hostia,
ahora,
bueno,
pues está peor,
está un poquito peor
que la de...
o al menos eso parece,
la veo un poquito peor.
Pero bueno,
era por comparar.
También no se pueden comparar
páginas distintas,
que eso es súper interesante.
Es sólo para compararla.
Pero bueno,
que ya habéis visto
que tampoco está mal.
Pero,
por ejemplo,
la de AprendeJavaScript
la tengo hecha
con Dino Fresh
y funciona súper bien,
súper rápido y tal.
Que esto,
si lo hubiera hecho
con NextEyes,
pues hubiera sido
mucho peor.
La de Midudev
no está hecha
con Dino Fresh.
Perdón la existencia.
Bueno,
perdón,
que a lo mejor
se me escapan
algunos mensajes
y por eso
no los contesto.
Y el año de Linux
en el escritorio.
ya,
a ver,
no digo que Dino Fresh
se vaya a convertir
en la opción preferida
de la gente,
pero sí que creo
que Dino Fresh
va a tener un hueco
más que nada
porque Dino
va a tener mucho empuje
en 2023
y porque
es muy interesante
lo de Dino Deploy.
Es muy barato,
va muy bien,
tiene muy buen rendimiento
y esa es la razón
por la que creo.
Midusor,
¿cuál era el blog
de Island Architecture?
Es jsonformat,
creo que se llama.
Es el blog
de Jason Miller.
Entonces,
perdón la existencia
y no sé
si ya lo contestaste,
diferencias entre Dino Fresh
y Quick.
La diferencia entre Dino Fresh
y Quick,
aparte de lo obvio
que son frameworks distintos,
Dino Fresh
en la biblioteca
que se utiliza
es Priak
y en Quick,
Quick es su propia biblioteca,
¿vale?
Es una biblioteca
que tienes que aprender
también de cero,
Priak es muy parecida a React.
Quick es mucho más agresiva
en cuanto a cómo
crea estas islas interactivas
y de hecho
tiene su propio nombre
que es,
creo,
si no recuerdo mal,
Progressive Hydration,
creo que le llaman,
donde automáticamente
toda parte
que es interactiva
la descarga
solo cuando la necesita.
O sea,
es una optimización
mucho más agresiva
pero también es verdad
que yo,
viendo el código,
me da la sensación
que puede tener
una curva de aprendizaje
un poquito mayor.
O sea,
de algunas cosas
que he visto
que tienes que ponerle
los signos de dólar
y tal,
pero tiene muy buena pinta Quick.
Pero la idea va por ahí.
Y la otra diferencia
es que Quick creo,
si no recuerdo mal,
que no está atado
a Node o a Dino,
sino que cualquier runtime
lo soporta,
creo,
y Dino Fresh
tienes que utilizar Dino
y lo puedes desplegar
en Dino Deploy.
La optimización
depende del programador,
no del framework.
La optimización
depende del programador,
no del framework.
Polémico, ¿eh?
¿Por qué?
Porque un framework
toma demasiadas decisiones
y no es tan fácil
decir que depende
solo del programador.
El framework te habilita
a hacer ciertas optimizaciones.
Puede ser que dependa
del programador,
obviamente,
o sea,
con un framework muy bueno
tú puedes crear
una verdadera salvajada,
pero hay frameworks
que te habilitan
a hacer ciertas optimizaciones.
O sea,
no es lo mismo utilizar
NextGS 13
que NextGS 12.
Y es la misma biblioteca,
¿no?
Para...
Entonces,
creo que tiene razón,
¿eh?
Depende del programador,
pero el framework
tiene que ver.
¿Cómo se hace
para tener ese TypeScript
in Build Support
en Visual Studio Code?
¿Qué opción hay que activar?
Creo que eso es
de la extensión
de Dino.
¿Qué crees que es la mejor?
¿La arquitectura de islas
o la serialización
que utiliza Quick?
No me ignores.
Perdona, Félix.
No te ignoro.
Es que no he podido
leerlo todo.
Yo creo que
como mejor
de óptimo
es la de Quick.
como mejor
de accesible
es la de islas.
Las cosas no siempre
son mejor o peor
como blanco o negro.
Creo que la arquitectura
de islas
es mucho más fácil
de adoptar,
mucho más fácil
de entender,
mucho más fácil
de...
de...
no sé,
de que NextGS 13,
por ejemplo,
empiece a utilizarla.
Pero la de Quick
me parece mucho mejor
en temas de...
creo que va a tener...
o sea,
tiene un impacto
mucho mayor.
Ahora,
¿ese impacto
lo justifica?
Habría que ver.
Midu,
el micro peta.
Creo que son petes
de...
del stream.
No...
No...
Creo que no es el micro
que peta de petar.
Sino que...