Nuxt.js: un marco minimalista para crear aplicaciones universales de Vue.js

¿Quieres aprender Vue.js desde cero? Obtenga una colección completa de libros de Vue que cubren conceptos básicos, proyectos, consejos y más herramientas con SitePoint Premium. Regístrese ahora por solo $ 14.99 / mes.

JavaScript universal (o isomorfo) es un término que se ha vuelto muy común en la comunidad de JavaScript. Se utiliza para describir el código JavaScript que se puede ejecutar tanto en el cliente como en el servidor.

Muchos marcos de JavaScript modernos, como Vue.js, están destinados a crear aplicaciones de una sola página (SPA). Esto se hace para mejorar la experiencia del usuario y hacer que la aplicación parezca más rápida, ya que los usuarios pueden ver las actualizaciones de las páginas al instante. Si bien esto tiene muchas ventajas, también tiene un par de desventajas, como un largo “tiempo para el contenido” durante la carga inicial de la aplicación mientras el navegador obtiene el paquete de JavaScript, y algunos rastreadores web de motores de búsqueda o redes de bots sociales no verán el toda la aplicación cargada cuando rastrean sus páginas web.

La representación de JavaScript del lado del servidor implica la carga previa de aplicaciones de JavaScript en un servidor web y el envío de HTML procesado en respuesta a una solicitud del navegador para una página.

La creación de aplicaciones de JavaScript renderizadas del lado del servidor puede ser un poco tediosa, ya que necesita realizar una gran cantidad de configuraciones antes de comenzar a codificar. Este es el problema que pretende resolver Nuxt.js para las aplicaciones Vue.js.

Desarrollado por10Ubuntu 20.04 Desktop Tour: descubra las nuevas funciones ShareNextStay para Angular y Next.js para React.

De acuerdo con los documentos de Nuxt.js, “su propósito principal es la representación de la interfaz de usuario mientras se abstrae la implementación del cliente/servidor”.

Generación estática

Otra gran característica de Nuxt.js es su capacidad para generar sitios web estáticos con el generatecomando. Es bastante bueno y ofrece una funcionalidad similar a las herramientas populares de generación estática como Jekyll.

Bajo el capó de Nuxt.js

Además de Vue.js 2.0, Nuxt.js incluye lo siguiente: Vue-Router, Vuex (incluido solo cuando se usa la opción de almacenamiento), Vue Server Renderer y vue-meta. Esto es genial, ya que elimina la carga de incluir y configurar manualmente las diferentes bibliotecas necesarias para desarrollar una aplicación Vue.js renderizada por servidor. Nuxt.js hace todo esto desde el primer momento, mientras mantiene un tamaño total de 57kB min+gzip (60KB con vuex).

Nuxt.js también usa webpack con vue-loader y babel-loader para agrupar, dividir código y minificar código.

Como funciona

Esto es lo que sucede cuando un usuario visita una aplicación Nuxt.js o accede a una de sus páginas a través de nuxt-link:

  1. Cuando el usuario visita inicialmente la aplicación, si la nuxtServerInitacción está definida en la tienda, Nuxt.js la llamará y actualizará la tienda.
  2. A continuación, ejecuta cualquier middleware existente para la página visitada. Nuxt primero verifica nuxt.config.jsel archivo en busca de middleware global, luego verifica el archivo de diseño correspondiente (para la página solicitada) y finalmente verifica la página y sus elementos secundarios en busca de middleware. El middleware se prioriza en ese orden.
  3. Si la ruta visitada es una ruta dinámica y validate()existe un método para ella, la ruta se valida.
  4. Luego, Nuxt.js llama a los métodos asyncData()e fetch()para cargar los datos antes de mostrar la página. El asyncData()método se usa para obtener los datos y representarlos en el lado del servidor, mientras que el fetch()método se usa para llenar la tienda antes de representar la página.
  5. En el paso final, se muestra la página (que contiene todos los datos correctos).

Estas acciones están correctamente representadas en este diagrama, obtenido de los documentos de Nuxt:

Esquema Nuxt.js

Creación de un sitio sin servidor estático con Nuxt.js

Ensuciémonos las manos con algo de código y creemos un blog simple generado estático con Nuxt.js. Digamos que nuestras publicaciones se obtienen de una API y nos burlaremos de la respuesta con un archivo JSON estático.

Para seguir correctamente, necesita un conocimiento práctico de Vue.js. Puede consultar la excelente guía de introducción de Jack Franklin para Vue.js 2.0 si es nuevo en el marco. También usaré la sintaxis de ES6 y puede obtener una actualización aquí: sitepoint.com/tag/es6/.

Nuestra aplicación final se verá así:

Blog Nuxt SSR

El código completo de este artículo se puede ver aquí en GitHub, y puede consultar la demostración aquí.

Instalación y configuración de aplicaciones

La forma más fácil de comenzar con Nuxt.js es usar la plantilla creada por el equipo de Nuxt. Podemos instalarlo rápidamente ssr-blogen nuestro proyecto ( ) usando vue-cli:

vue init nuxt/starter ssr-blog

Después de ejecutar este comando, se abrirá un mensaje con un par de preguntas. Puede presionar Returnpara aceptar las respuestas predeterminadas o ingresar sus propios valores.

Nota: si no tiene instalado vue-cli, primero debe npm install -g @vue/cliejecutarlo para instalarlo.

A continuación, instalamos las dependencias del proyecto:

cd ssr-blognpm install

Ahora podemos lanzar la aplicación:

npm run dev

Con suerte, debería poder visitar http://localhost:3000 para ver la página de inicio de la plantilla Nuxt.js. También puede ver el código fuente de la página, para ver que todo el contenido generado en la página se representó en el servidor y se envió como HTML al navegador.

A continuación, podemos realizar algunas configuraciones sencillas en el nuxt.config.jsarchivo. Agregaremos algunas opciones:

// ./nuxt.config.jsmodule.exports = {  /*   * Headers of the page   */  head: {    titleTemplate: '%s | Awesome JS SSR Blog',    // ...    link: [      // ...      {        rel: 'stylesheet',        href: 'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css'      }    ]  },  // ...}

En el archivo de configuración anterior, simplemente especificamos la plantilla de título que se usará para la aplicación a través de la titleTemplateopción. Establecer la opción titleen páginas o diseños individuales inyectará el titlevalor en el %smarcador de posición titleTemplateantes de renderizar.

También incorporamos mi marco CSS favorito actual, Bulma, para aprovechar algunos estilos preestablecidos. Esto se hizo a través de la linkopción.

Nota: Nuxt.js usa vue-meta para actualizar los encabezados y los atributos HTML de nuestras aplicaciones. Luego puede echar un vistazo para comprender mejor cómo se configuran los encabezados.

Ahora podemos dar los siguientes dos pasos agregando nuestras páginas de blog y características.

Trabajar con diseños de página

Primero, definiremos un diseño base personalizado para todas nuestras páginas. Podemos ampliar el diseño principal de Nuxt.js actualizando el layouts/default.vuearchivo:

!-- ./layouts/default.vue --template  div    !-- navigation --    nav role="navigation" aria-label="main navigation"      div        div          nuxt-link to="/"            Awesome JS SSR Blog!          /nuxt-link          nuxt-link active-class="is-active" to="/" exactHome/nuxt-link          nuxt-link active-class="is-active" to="/about" exactAbout/nuxt-link        /div      /div    /nav    !-- /navigation --    !-- displays the page component --    nuxt/  /div/templatestyle  .main-content {    margin: 30px 0;  }/style

En nuestro diseño base personalizado, agregamos el encabezado de navegación del sitio. Usamos el nuxt-linkcomponente para generar enlaces a las rutas que queremos tener en nuestro blog. Puede consultar los documentos en nuxt-linkpara ver cómo funciona esto.

El nuxtcomponente es muy importante al crear un diseño, ya que muestra el componente de página.

También es posible hacer un par de otras cosas, como definir plantillas de documentos personalizadas y diseños de errores, pero no necesitamos eso para nuestro blog simple. Le insto a consultar la documentación de Nuxt.js sobre vistas para ver todas las posibilidades.

Páginas y caminos simples

Las páginas en Nuxt.js se crean como componentes individuales de archivos en el pagesdirectorio. Nuxt.js transforma automáticamente cada .vuearchivo de este directorio en una ruta de aplicación.

Creación de la página de inicio del blog.

Podemos agregar la página de inicio de nuestro blog actualizando el index.vuearchivo generado por la plantilla Nuxt.js en el directorio de páginas:

!-- ./pages/index.vue --template  div    section      div        div          h1            Welcome to the JavaScript SSR Blog.          /h1          h2            Hope you find something you like.          /h2        /div      /div    /section  /div/templatescript  export default {    head: {      title: 'Home'    }  }/script!-- Remove the CSS styles --

Como se indicó anteriormente, especificar la opción titleaquí inserta automáticamente su valor en titleTemplateel valor antes de representar la página.

Ahora podemos volver a cargar nuestra aplicación para ver los cambios en la página de inicio.

Creación de la página Acerca de

Otra gran cosa acerca de Nuxt.js es que escuchará los cambios en los archivos dentro del pagesdirectorio, por lo que no necesita reiniciar la aplicación al agregar nuevas páginas.

Podemos probarlo, agregando una about.vuepágina simple:

!-- ./pages/about.vue --template  div    div      h2About this website./h2      pCurabitur accumsan turpis pharetra strongaugue tincidunt/strong blandit. Quisque condimentum maximus mi, sit amet commodo arcu rutrum id. Proin pretium urna vel cursus venenatis. Suspendisse potenti. Etiam mattis sem rhoncus lacus dapibus facilisis. Donec at dignissim dui. Ut et neque nisl./p      br      h4What we hope to achieve:/h4      ul        liIn fermentum leo eu lectus mollis, quis dictum mi aliquet./li        liMorbi eu nulla lobortis, lobortis est in, fringilla felis./li        liAliquam nec felis in sapien venenatis viverra fermentum nec lectus./li        liUt non enim metus./li      /ul    /div  /div/templatescriptexport default {  head: {    title: 'About'  }}/script

Ahora podemos visitar http://localhost:3000/about para ver la página acerca de, sin tener que reiniciar la aplicación, lo cual es genial.

Mostrar publicaciones de blog en la página de inicio

Nuestra página de inicio actual es bastante simple, por lo que podemos mejorarla mostrando publicaciones de blog recientes. Haremos esto creando un postscomponente y mostrándolo en la index.vuepágina.

Pero primero, debemos guardar nuestras publicaciones de blog JSON y colocarlas en un archivo en la carpeta raíz de la aplicación. El archivo se puede descargar desde aquí, o simplemente puede copiar el JSON a continuación y guardarlo en su carpeta raíz como posts.json:

[    {        "id": 4,        "title": "Building universal JS apps with Nuxt.js",        "summary": "Get introduced to Nuxt.js, and build great SSR Apps with Vue.js.",        "content": "pLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum./p",        "author": "Jane Doe",        "published": "08:00 - 07/06/2017"    },    {        "id": 3,        "title": "Great SSR Use cases",        "summary": "See simple and rich server-rendered JavaScript apps.",        "content": "pLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum./p",        "author": "Jane Doe",        "published": "17:00 - 06/06/2017"    },    {        "id": 2,        "title": "SSR in Vue.js",        "summary": "Learn about SSR in Vue.js, and where Nuxt.js can make it all faster.",        "content": "pLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum./p",        "author": "Jane Doe",        "published": "13:00 - 06/06/2017"    },    {        "id": 1,        "title": "Introduction to SSR",        "summary": "Learn about SSR in JavaScript and how it can be super cool.",        "content": "pLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum./p",        "author": "John Doe",        "published": "11:00 - 06/06/2017"    }]

Nota: lo ideal es que las publicaciones se obtengan de una API o un recurso. Por ejemplo, Contentful es un servicio que se puede usar para esto.

Los componentes residen en el componentsdirectorio. Crearemos el postscomponente de archivo único allí:

!-- ./components/Posts.vue --template  section    div      h1        Recent Posts.      /h1      div        div v-for="post in posts" :key="post.id"          div           header            p              {{ post.title }}            /p          /header          div            div              {{ post.summary }}              br              small                by strong{{ post.author}}/strong                 {{ post.published }}              /small            /div          /div          footer            nuxt-link :to="`/post/${post.id}`"                           Read More            /nuxt-link          /footer        /div      /div    /div  /div/section/templatescript  import posts from '~/posts.json'  export default {    name: 'posts',    data () {      return { posts }    }  }/script

Importamos los datos de publicación del archivo JSON guardado y lo asignamos al postsvalor en nuestro componente. Luego recorremos todas las publicaciones en la plantilla del componente con la v-fordirectiva y mostramos los atributos de publicación que queremos.

Nota: El ~símbolo es un alias para el /directorio. Puede consultar los documentos aquí para ver los diferentes alias proporcionados por Nuxt.js y a qué directorios se vinculan.

A continuación, agreguemos el postscomponente a la página de inicio:

!-- ./pages/index.vue --templatediv    !-- ... --    posts //div/templatescriptimport Posts from '~/components/Posts.vue'export default {  components: {    Posts  },  // ...}/script

Adición de rutas dinámicas

Ahora agregaremos rutas dinámicas para las publicaciones, de modo que pueda acceder a una publicación con, por ejemplo, esta URL: /post/1.

Para lograr esto, agregamos el postdirectorio al pagesdirectorio y lo estructuramos así:

pages└── post    └── _id        └── index.vue

Esto genera las rutas dinámicas correspondientes para la aplicación de la siguiente manera:

router: {  routes: [    // ...    {      name: 'post-id',      path: '/post/:id',      component: 'pages/post/_id/index.vue'    }  ]}

Actualización de archivo de publicación única:

!-- ./pages/post/_id/index.vue --template  div    div      h2{{ post.title }}/h2      div v-html="post.content"/div      br      h4by strong{{ post.author }}/strong at strong{{ post.published }}/strong/h4    /div  /div/templatescript  // import posts saved JSON data  import posts from '~/posts.json'  export default {    validate ({ params }) {      return /^d+$/.test(params.id)    },    asyncData ({ params }, callback) {      let post = posts.find(post = post.id === parseInt(params.id))      if (post) {        callback(null, { post })      } else {        callback({ statusCode: 404, message: 'Post not found' })      }    },    head () {      return {        title: this.post.title,        meta: [          {            hid: 'description',            name: 'description',            content: this.post.summary          }        ]      }    }  }/script

Nuxt.js agrega algunos métodos personalizados a los componentes de nuestra página para agilizar el proceso de desarrollo. Vea cómo usamos algunos de ellos en la página de publicación única:

  • Valide el parámetro de ruta con el validatemétodo. Nuestro método de validación verifica si el parámetro de ruta pasado es un número. Si regresa false, Nuxt.js cargará automáticamente la página de error 404. Puede leer más aquí.
  • El asyncDatamétodo se utiliza para obtener los datos y representarlos en el lado del servidor antes de enviar una respuesta al navegador. Puede devolver datos a través de varios métodos. En nuestro caso, usamos una función de devolución de llamada para devolver la publicación que tiene el mismo idatributo que el idparámetro de ruta. Puede ver las diversas formas de usar esta función aquí.
  • Como hemos visto antes, usamos el headmétodo para configurar encabezados de página. En este caso, estamos cambiando el título de la página por el título de la publicación y agregando el resumen de la publicación como meta descripción de la página.

Genial, ahora podemos visitar nuestro blog nuevamente para ver que todas las rutas y páginas funcionan correctamente y también ver el código fuente de la página para ver el HTML generado. Tenemos una aplicación de JavaScript hecha funcional por el servidor.

Generación de archivos estáticos

A continuación, podemos generar los archivos HTML estáticos para nuestras páginas.

Sin embargo, tendremos que hacer un pequeño cambio, ya que por defecto Nuxt.js ignora las rutas dinámicas. Para generar archivos estáticos para rutas dinámicas, debemos especificarlos explícitamente en el ./nuxt.config.jsarchivo.

Usaremos una función de devolución de llamada para devolver la lista de nuestras rutas dinámicas:

// ./nuxt.config.jsmodule.exports = {  // ...  generate: {    routes(callback) {      const posts = require('./posts.json')      let routes = posts.map(post = `/post/${post.id}`)      callback(null, routes)    }  }}

Puede consultar aquí la documentación completa sobre el uso de la generatepropiedad.

Para generar todas las rutas, ahora podemos ejecutar este comando:

npm run generate

Nuxt guarda todos los archivos estáticos generados en una distcarpeta.

Implementación en alojamiento Firebase

Como paso final, podemos aprovechar el alojamiento de Firebase para poner en funcionamiento nuestro sitio web estático en un par de minutos. Este paso asume que tienes una cuenta de Google.

Primero, instale Firebase CLI si aún no lo tiene:

npm install -g firebase-tools

Para conectar su máquina local a su cuenta de Firebase y obtener acceso a sus proyectos de Firebase, ejecute el siguiente comando:

firebase login

Debería abrirse una ventana del navegador y pedirle que inicie sesión. Una vez que haya iniciado sesión, visite https://console.firebase.google.com y haga clic en Agregar proyecto. Realice las elecciones pertinentes en el asistente que se abre.

Una vez que se crea el proyecto, vaya a la página de hospedaje del proyecto https://console.firebase.google.com/project/project name/hostingy complete el asistente de inicio.

Luego, en su PC, desde la raíz del directorio de su proyecto, ejecute el siguiente comando:

firebase init

En el asistente que aparece, selecciona “Alojamiento”. Luego seleccione el proyecto que acaba de crear de la lista de opciones. Luego elija el distdirectorio como directorio público. Seleccione para configurar la página como una aplicación de una sola página y finalmente seleccione “No” cuando se le pregunte si desea anular dist/index.html.

Firebase escribirá un par de archivos de configuración en su proyecto y luego publicará el sitio web en https://project name.firebaseapp.com. La aplicación de demostración de este artículo se puede ver en nuxt-ssr-blog.firebaseapp.com.

Si tiene problemas, puede encontrar instrucciones completas en la página de inicio rápido de Firebase.

Conclusión

En este artículo, aprendimos cómo aprovechar Nuxt.js para crear aplicaciones JavaScript renderizadas en servidor con Vue.js. También aprendimos a usar su generatecomando para generar archivos estáticos para nuestras páginas e implementarlos rápidamente a través de un servicio como Firebase Hosting.

El marco Nuxt.js es realmente genial. Incluso se recomienda en el GitBook oficial de Vue.js SSR. Tengo muchas ganas de usarlo en más proyectos SSR y explorar todas sus capacidades.

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll to Top