Migración de jQuery a Next.js: una guía

Esta guía le mostrará cómo migrar su sitio jQuery a React con Next.js , lo cual es una tarea importante, especialmente para bases de código grandes. Sin embargo, esta migración le permite utilizar conceptos más nuevos (como la obtención de datos en el momento de la compilación) para ayudar con el rendimiento y la capacidad de mantenimiento de nuestro código.
jQuery ha servido bien a los desarrolladores durante muchos años. Sin embargo, las bibliotecas (como React) y los frameworks (como Next.js) ahora nos brindan características más modernas para ayudar con el rendimiento y la capacidad de mantenimiento de nuestro código. Esta guía le mostrará cómo reescribir su sitio jQuery usando Next.js para aprovechar todas estas nuevas características, como el enrutamiento del lado del cliente para transiciones más fluidas y la capacidad de separar el código en componentes para hacerlo más reutilizable.
Empezando
La forma más sencilla de comenzar con Next.js es ejecutar npx create-next-app
. Esto estructurará un proyecto para usted. Sin embargo, para entender qué hace este comando, crearemos nuestra aplicación desde cero.
Primero, crearemos nuestro proyecto Next.js usando npm init
. Puede continuar con la configuración predeterminada, ya que la cambiaremos más adelante. Luego, queremos instalar React y Next.js usando:
npm install react react-dom next
A continuación, podemos abrir el package.json
archivo y reemplazar el predeterminado scripts
con:
"scripts": { "dev": "next", "build": "next build", "start": "next start"}
Esto le permite ejecutar npm run dev
para iniciar el servidor de desarrollo; npm run build
para construir su aplicación; e npm run start
iniciar un servidor de esa aplicación construida.
Para agregar páginas, como lo haría index.html
con jQuery, cree un directorio con nombre pages
y cree un archivo con nombre index.jsx
en él. Dentro de este archivo, coloque el siguiente código:
export default function Index() { return h1Hello World/h1 ;}
Ahora, al ejecutar npm run start
y navegar hasta localhost:3000
, debería ver una h1
etiqueta en pantalla. El nombre de esta función no es importante, por lo que puedes llamarla como quieras. Sin embargo, no utilice una función de flecha anónima, ya que esto impedirá que funcione la actualización rápida .
CSS
En jQuery, puedes especificar CSS por página, importando diferentes hojas de estilo para diferentes páginas. Esto también es posible en Next.js usando el next/head
componente y una link
etiqueta de la misma manera que jQuery. De todos modos, hay formas más amigables con el rendimiento de hacer esto en Next.js.
Hoja de estilo global
La primera forma es con una hoja de estilo global. Para hacerlo, necesitamos crear una costumbre App
creando el archivo _app.js
dentro del pages
directorio. El punto de partida de este archivo es el siguiente:
function MyApp({ Component, pageProps }) { return Component {...pageProps} /}export default MyApp
En la parte superior de este archivo, puede agregar una declaración de importación e importar cualquier archivo CSS que desee. Por ejemplo, si creó una carpeta separada en el nivel raíz llamada styles
y main.css
la colocó, entonces agregaría:
import "../styles/main.css"
Ahora, todo lo que pongas dentro de este archivo se aplicará en toda tu aplicación.
Módulos CSS
La siguiente opción son los módulos CSS, que le permiten especificar CSS en cualquier lugar de su aplicación. Crearán nombres de clase únicos a partir de las clases que usted proporcione, de modo que pueda usar el mismo nombre de clase en varios lugares del código de su aplicación.
Ampliando el ejemplo inicial de hola mundo , podrías crear un archivo index.module.css
en el mismo directorio y luego escribir la importación:
import styles from "./index.module.css"
Luego, si tuvieras que definir una heading
clase en el archivo CSS, podrías hacer lo siguiente:
export default function Index() { return h1 className={styles.heading}Hello World/h1 ;}
y esos estilos se aplicarán solo a ese elemento.
JSX con estilo
La última opción incorporada tiene el estilo JSX . Esto es muy similar a incluir una style
etiqueta en la parte superior de su página para definir algunos estilos. Simplemente agréguelo jsx
a la style
etiqueta y use una cadena de plantilla dentro, como esta:
style jsx{` .heading { font-weight: 700 `}/style
Esta opción tiene la ventaja de poder modificarse en tiempo de ejecución. Por ejemplo, si desea proporcionar el peso de la fuente en los accesorios de su componente, puede hacer:
style jsx{` .heading{ font-weight: ${props.fontWeight} `}/style
La única desventaja de este método es que introduce JavaScript de tiempo de ejecución adicional en su aplicación, aumentando el tamaño en 12 kb (3 kb comprimidos).
Eventos
En jQuery, es posible que tengas eventos configurados para responder a elementos DOM. Para darle una idea, es posible que desee ejecutar código cuando p
se hace clic en una etiqueta y hacerlo así:
$( "p" ).click(function() { console.log( "You clicked a paragraph!" );});
En cambio, React utiliza controladores de eventos , que quizás hayas visto en HTML, como onclick
. Tenga en cuenta que React usa camelCase en su lugar, por lo que onclick
se debe hacer referencia a él como onClick
. Por lo tanto, reescribir este pequeño ejemplo en React quedaría así:
export default function Index() { function clickParagraph(){ console.log("You clicked a paragraph!"); } return p onClick={clickParagraph}Hello World/p;}
Cada método tiene sus ventajas y desventajas. En jQuery, es fácil que algo suceda para todos los párrafos, mientras que en React, debes especificar por párrafo. Sin embargo, para bases de código más grandes, tener que especificar hace que sea fácil ver qué sucederá con la interacción con cualquier elemento, donde es posible que se haya olvidado de la función jQuery.
Efectos
Los efectos se utilizan en jQuery para mostrar y ocultar contenido . Es posible que ya tengas algo como esto:
$( "p" ).hide();
En React, este comportamiento se implementa mediante renderizado condicional . Puedes ver esto combinándolo con el reemplazo de eventos que acabamos de ver:
import {useState} from "react"export default function Index() { const [show, setShow] = useState(true); function clickButton(){ setShow(false) } return ( div h1Hello world/h1 {show button onClick={clickButton}Click me/button} /div )}
Cuando hace clic en este botón, cambiará el valor de show
a false
y, por lo tanto, la declaración no mostrará nada. Esto se puede ampliar con el operador condicional para mostrar una cosa u otra, dependiendo del valor así:
show ? pShow this if show is true/p : pShow this if show is false/p
Obtención de datos
En jQuery, Ajax se utiliza para recuperar datos externos sin recargar. En React, esto se puede hacer usando el useEffect
gancho. Para este ejemplo, obtendremos el tipo de cambio de una API pública cuando se cargue la página:
import { useState, useEffect } from "react";export default function Index() { const [er, setEr] = useState(true); useEffect(async () = { const result = await fetch("https://api.exchangerate.host/latest"); const exchangerate = await result.json(); setEr(exchangerate.rates["GBP"]); }, []); return ( div h1Hello world/h1 pExchange rate: {er}/p /div );}
useEffect
toma una función y una matriz de dependencia. La función obtiene los datos, utilizándolos async
como fetch
API de forma asincrónica. Luego podemos establecer cualquier estado que queramos allí y se actualizará en la página. La matriz de dependencia determina qué cambios de valor ejecutarán la función. En este caso, está configurado en una matriz vacía, lo que significa que la función solo se ejecutará cuando la página se cargue por primera vez.
Más allá de esto, Next.js también ofrece opciones para recuperar datos en el servidor o en el momento de la compilación. Para la recuperación de datos en tiempo de compilación, getStaticProps
se puede utilizar la función. Esta función proporciona una mejora en el rendimiento, ya que los datos se pueden proporcionar con la página, en lugar de esperar a un servicio externo. Para usarlo, cree esta función en una página ya que no funciona en componentes.
export async function getStaticProps() { return { props: {}, }}
Puede realizar cualquier recuperación de datos que desee antes de la devolución y, después de eso, pasar los datos a la página siguiente props
; luego, los datos se proporcionan a la página y se puede acceder a ellos en los accesorios.
Al reemplazar el nombre de la función de getStaticProps
a getServerSideProps
, la función se llamará en cada solicitud , lo que le brinda la flexibilidad de usar funciones de Node.js si es necesario. También le permite realizar muchas solicitudes de datos en el servidor y procesarlas para reducir el ancho de banda utilizado por el cliente.
También tienes la opción de un término medio entre los dos llamado Regeneración Estática Incremental . Esta opción generará una página estática de la misma manera que getStaticProps
, pero le permite especificar un período de revalidación , que regenerará la página cuando llegue una solicitud con una frecuencia máxima del período que especifique. Para ello, además de los accesorios, también deberás incluir una revalidate
clave con el tiempo en segundos que quieras.
Objetos en elementos DOM
Con jQuery, debes tener cuidado con el método que utilizas para convertir un objeto en elementos DOM. El ejemplo más común de esto es crear una lista de elementos porque, con jQuery, un bucle sobre los elementos agregaría cada uno al DOM uno por uno. Con React, el DOM virtual se utiliza para crear diferencias entre el nuevo estado y el actual. Esto significa que a pesar de agregar elementos en un bucle, se agregan al DOM real como una sola operación.
Esto se hace usando la map
función en JavaScript, donde puedes asignar cada elemento a algún JSX.
export default function Index() { const fruits = ["Apple", "Orange", "Pear"]; return ( div h1Hello world/h1 ul {fruits.map((fruit) = ( li key={fruit}{fruit}/li ))} /ul /div );}
Observe que el elemento dentro de map
necesita un key
accesorio. Esto se utiliza en el proceso de diferenciación discutido anteriormente, lo que facilita que React distinga entre cada elemento, por lo que cada uno de ellos debe ser único.
diferidos
El uso de diferidos en jQuery se puede reemplazar con la promise
funcionalidad nativa de JavaScript. La sintaxis de diferidos se diseñó para reflejar la funcionalidad de las promesas , por lo que la sintaxis debería ser familiar y no requerir demasiadas modificaciones. Un ejemplo de dónde se podrían utilizar los diferidos es en la obtención de datos . Si hace esto con el fetch
método en JavaScript, puede agregar un .then
al final de la búsqueda, ya que devuelve una promesa. Este código solo se ejecutará cuando se complete la búsqueda y, por lo tanto, los datos (o un error) estarán presentes. Puedes ver esta funcionalidad en uso aquí:
fetch("example.com").then((response) = { console.log(response)}).catch((error) = {console.error(error)})
Esto buscará example.com
y registrará la respuesta obtenida a menos que ocurra un error; en este caso, se registrará como un error.
Además de esta sintaxis, async/await
también se puede utilizar la sintaxis más nueva. Estos requieren una función definida como a
sync
, de la misma manera que podría exportar una función. Puedes declararlo así:
async function myFunction(){ return}
Dentro de esta función, puedes llamar a más funciones asíncronas colocándolas await
delante de ellas, por ejemplo:
async function myFunction(){ const data = await fetch("example.com") return data}
Este código devolverá una promesa que se resolverá cuando se obtengan los datos, por lo que debe llamarse dentro de una función asincrónica para esperar el resultado. Sin embargo, para detectar también errores, deberá escribir un condicional para verificar el estado de la respuesta ; si data.ok
no es verdadero, se debe generar un error. Luego, puede envolver estas declaraciones de ausencia en un bloque try catch, en lugar de usar .catch
. Puede leer más sobre estos métodos en este artículo .
Mejoras
Enrutamiento
Next.js utiliza enrutamiento del sistema de archivos , que es muy similar al uso de diferentes .html
páginas en un sitio web tradicional. Sin embargo, este sistema también ofrece funciones más allá de eso, proporcionando rutas dinámicas y permitiendo acceder a una página desde una variedad de URL.
Por ejemplo, si tiene un blog, puede mantener todos sus archivos en /blog/*
, creando un archivo [slug].jsx
dentro de la blog
carpeta, lo que permitirá que ese contenido se publique en todas las páginas en blog
. Luego, puede usar el enrutador en Next.js para encontrar a qué ruta se navegó, así:
const router = useRouter()const { slug } = router.query
Rutas API
Las rutas API también le permiten escribir su backend dentro de su aplicación Next.js. Para utilizar estas rutas, cree una api
carpeta en su pages
directorio; ahora, cualquier archivo creado dentro de ella se ejecutará en el servidor en lugar del cliente, como ocurre con el resto de las páginas.
Para comenzar con esto, necesita exportar una función predeterminada del archivo, y esto puede tomar dos parámetros. La primera será la solicitud entrante y la segunda le permitirá crear la respuesta. Una ruta API básica se puede escribir así:
export default function handler(request, response) { response.status(200).json({ magazine: 'Smashing' })}
Limitaciones
interfaz de usuario jQuery
Puede usar jQuery UI en su aplicación para la interfaz de usuario, pero React no proporciona una biblioteca de UI oficial como esta. Sin embargo, se ha producido una serie de alternativas. Dos de los más populares son Reach UI y React Aria . Ambas alternativas se centran fuertemente en la Accesibilidad, asegurando que el proyecto que cree sea utilizable por una mayor variedad de usuarios.
Animación
Si bien puedes usar renderizado condicional en lugar de efectos, esto no proporciona la misma funcionalidad, ya que no puedes hacer cosas como atenuar el contenido. Una biblioteca que ayuda a proporcionar esta funcionalidad es React Transition Group , que le permite definir transiciones de entrada y salida.
Conclusión
Pasar de jQuery a Next.js es una tarea grande , especialmente para bases de código grandes. Sin embargo, esta migración le permite utilizar conceptos más nuevos (como la recuperación de datos en el momento de la compilación) y lo configura para tener rutas de migración simples a nuevas versiones de React y Next.js, junto con las características que ofrecen.
React puede ayudarlo a organizar mejor su código (lo cual es particularmente importante para bases de código grandes) y brinda una mejora sustancial del rendimiento mediante el uso de un DOM virtual. En general, creo que vale la pena el esfuerzo de migrar de jQuery a Next.js y espero que, si decide migrar, disfrute de todas las funciones que React y Next.js tienen para ofrecer.
Lecturas adicionales sobre la revista Smashing
- “ Cómo migrar de jQuery a Next.js ”, Facundo Giuliani
- “ Qué, cuándo, por qué y cómo de la nueva función de middleware de Next.js ”, Sam Poder
- “ Localización de su aplicación Next.js ”, Átila Fassina
- “ Cómo mantener una aplicación Next.js de gran tamaño ”, Nirmalya Ghosh
(nl)Explora más en
- Codificación
- javascript
- SiguienteJS
- Reaccionar
Deja un comentario