Implementación de un proyecto ReactJS y NextJS en Firebase

Estamos en el mejor momento como desarrolladores, coexistiendo entre una amplia gama de tecnologías, herramientas y tendencias que cada día crecen y crecen. Si les apasiona aprender y aplicar tecnologías en su tiempo libre, hoy es el momento.

Hoy nos enfocaremos en ReactJS y en el rendimiento que podemos ofrecer a nuestras aplicaciones utilizando la escalabilidad de Firebase con Cloud Functions.

Además, utilizaremos el framework NextJS para la renderización desde el servidor, lo que nos ayudará a configurar y resolver fácilmente problemas de SEO pero, lo más importante, es disminuir al menor grado el período de respuesta entre el servidor y el cliente para ofrecer a los usuarios la mejor experiencia.

¡Así que empecemos!

Primero tenemos que instalar Next.js en nuestro entorno de trabajo:

 npm install -g create-next-app

Seguidamente creamos un proyecto llamado “firebase-nextjs”:

create-next-app firebase-nextjs: este comando creará el proyecto, pero también instalará react and react-dom dependencias, que se pueden ver en el archivo package.json

Ejecutamos run yarn dev y nuestro proyecto correrá por defecto en el puerto 3000 (localhost:3000).

NextJS buscará el archivo correspondiente en la carpeta de páginas para cada ruta, por ejemplo: la ruta "/" indica que se buscarán las páginas del archivo /index.js

El framework se basa en React, mantiene una estructura apropiada a él. Podremos observar una carpeta llamada "components", donde se almacenará cada componente que queremos usar para nuestras vistas.

Entonces, si usamos NextJS y React, ¿por qué no agregar Material-UI?

Instalemos localmente Material-UI: npm install @material-ui/core.

Crearemos dos páginas muy simples para observar el comportamiento de estos tres frameworks creados para facilitar la vida.

En la carpeta pages creamos "page1.js" y "page2.js".

Agregamos  el siguiente código  pages/page1.js:
import Card1 from '../components/card1'



const Page1 = () => (

 <div>

   <Card1 />

 </div>

)

Exportar por defecto Page1

En la carpeta components creamos "card1.js" y agregamos cualquiera de los ejemplos en Material-UI en la sección de cards  y lo personalizamos como querramos.

Para ver el contenido de la página page1.js  podemos ir a "http://localhost:3000/page1" o usar el enlace de NextJS para redireccionarnos.

Hacemos lo mismos para "page2" and "card2".

Al llegar a este punto, deberíamos tener una aplicación NextJS corriendo perfectamente con los componentes de React.

En este punto ya estamos listos para ingresar a la parte más interesante de esta publicación. Vamos a estructurar nuestro proyecto siguiendo la guía de James Hegedus.

Por lo tanto, en la raíz de nuestro proyecto creamos una carpeta llamada "src", dentro de esta carpeta encontraremos otra llamada "app", donde estarán almacenados todos los archivos de la aplicación. Deberíamos poder mover todos los archivos de la carpeta "app".

Luego iremos a la consola firebase y crearemos nuestro proyecto.

Se presentará el panel general del proyecto. Como se puede observar , Firebase nos proporciona Autenticación, Base de datos, Almacenamiento, Hosting, Funciones y ML Kit, cada uno de estos aspectos muy interesantes, pero nos centraremos solo en las Funciones.

¿Porqué Funciones? Si no usamos NextJS, y es suficiente que en nuestro código fuente de la aplicación solo veamos algunas etiquetas '<script>' entonces la opción sería Hosting, pero queremos obtener server rendering y la magia de NextJS que es realmente increíble/asombroso.

A continuación, ejecutamos los siguientes comandos en el root de nuestro proyecto:

  • yarn global add firebase-tools

  • firebase login

  • firebase init

Cuando ejecutamos firebase init, se desplegaran una serie de preguntas:

  • ¿Qué caracteristica de Firebase CLI  desea configurar en esta carpeta? | Seleccione “Functions” y “Hosting”.

  • Seleccione el proyecto predeterminado de Firebase project para ese directorio: | Seleccione el proyecto que creó anteriormente en la consola de firebase.

  • ¿Qué lenguaje le gustaría usar para escribir Cloud Functions? | En nuestro caso “Javascript”.

  • ¿Desea utilizar ESLint para detectar posibles errores e implementar el estilo? | Escribimos “N”.

  • ¿Desea instalar dependencias con npm ahora? | No es necesario, escribir “n”.

  • ¿Qué tipo de directorio público desea usar? | Escribe “src/public”, se crearán dos archivos, los cuales fueron generados con la finalidad de mostrarse en primera plana en caso de no encontrar algún otro y que arroje un error. 

  • Configurar como una single-page app (volver a escribir todas las urls a /index.html)? Escariba “N”, en nuestro caso debería ser una aplicación más compleja.

¡Listo!

Encontraremos en el root de nuestro proyecto una carpeta llamada "functions", simplemente muévala dentro de la carpeta "src" .

En nuestro archivo firebase.json eliminamos el código existente y lo actualizamos de la siguiente manera:
{

 "hosting": {

   "public": "src/public",

   "rewrites": [

     {

       "source": "**/**",

       "function": "next"

     }

   ],

   "ignore": [

     "firebase.json",

     "**/.*",

     "**/node_modules/**"

   ]

 },

 "functions": {

   "source": "src/functions"

 }

}

En el package.json de la carpeta functions agregamos las siguiente dependencias (después de varias pruebas, considero que son las versiones que presentan menos errores):
"@material-ui/core": "^1.4.3",

   "classnames": "^2.2.6",

   "firebase-admin": "~6.0.0",

   "firebase-functions": "^2.0.0",

   "next": "^6.1.1",

   "prop-types": "^15.6.2",

   "react": "^16.4.2",

   "react-dom": "^16.4.2"

En el caso de las dependencias "classnames"  y "prop-types",  son necesarios para este ejemplo que estamos desarrollando, y también como un consejo, que cada dependencia que requerimos para nuestro proyecto debe ir en este archivo, así como src/app/package.json , por lo tanto, también agrega las dependencias a src/app/package.json.

Para garantizar que NextJS se ejecute correctamente en Cloud Functions, eliminamos los contenidos de functions/index.js by:
const functions = require("firebase-functions")

const next = require("next")



var dev = process.env.NODE_ENV !== "production"

var app = next({ dev, conf: { distDir: "next" } })

var handle = app.getRequestHandler()



exports.next = functions.https.onRequest((req, res) => {

 console.log("File: " + req.originalUrl) // log the page.js file that is being requested

 return app.prepare().then(() => handle(req, res))

})

Ahora procedemos a instalar  las dependencias en las functions y en la app, dentro de src/functions y src/app ejecuta yarnnpm install dependiendo del administrador que uses.

Se crea .gitignore dentro de la carpeta de funciones y solo agregamos "next".

Necesitamos que nuestros componentes de material-ui se muestren correctamente, gracias a NextJS solo deberíamos agregar lo siguiente a src/app/next.config.js:
const path = require('path')

const glob = require('glob')



module.exports = {

 distDir: "../functions/next",

 webpack: (config, { dev }) => {

   config.module.rules.push(

     {

       test: /\.(ico|gif|png|jpg|jpeg|svg|webp)$/,

       use: [

         {

           loader: 'emit-file-loader',

           options: {

             name: 'dist/[path][name].[ext]'

           }

         },

         {

           loader: 'file-loader',

           options: {

             name: 'dist/[path][name].[ext]'

           }

         }

       ]

     },

     {

       test: /\.(css|scss)/,

       loader: 'emit-file-loader',

       options: {

         name: 'dist/[path][name].[ext]'

       }

     },

     {

       test: /\.css$/,

       use: ['babel-loader', 'raw-loader', 'postcss-loader']

     },

     {

       test: /\.s(a|c)ss$/,

       use: ['babel-loader', 'raw-loader', 'postcss-loader',

         { loader: 'sass-loader',

           options: {

             includePaths: ['styles', 'node_modules']

               .map((d) => path.join(__dirname, d))

               .map((g) => glob.sync(g))

               .reduce((a, c) => a.concat(c), [])

           }

         }

       ]

     }

   )

   return config

 }

}

Actualicemos nuestro package.json que se encuentra en el root del proyecto con los scripts que manejaremos en la aplicación:
{

 "name": "firebase-nextjs",

 "version": "1.0.0",

 "license": "MIT",

 "scripts": {

   "install": "yarn build-all",

   "next": "yarn build-firebase && cd \"src/app\" && yarn && yarn dev",

   "preserve": "yarn build-all",

   "serve": "firebase serve",

   "predeploy": "yarn build-all",

   "deploy": "firebase deploy",

   "build-all": "yarn build-next && yarn build-firebase",

   "build-next": "cd \"src/app\" && yarn && yarn build",

   "build-firebase": "cd \"src/functions\" && yarn"

 }

}

Ahora, en el root del proyecto se ejecuta yarn init y luego se generan las siguientes opciones:

yarn next: Ejecutamos el proyecto localmente por el puerto 3000 que se encuentra predeterminado.

yarn build-all && firebase deploy --only functions: construimos nuestro proyecto y lo implementamos en firebase.

Con los pasos descritos anteriores, la aplicación debería ejecutarse correctamente. El proyecto de prueba se encontrará disponible en github, de modo que ya se puede puede comparar con la finalidad de obtener una mejor guía y comprensión del código.

Conclusión

Esta es una contribución que se basa en la propia experiencia, por lo que estamos dispuestos a responder todas las  inquietudes que se puedan generar sobre la tecnología y el proyecto.

Nos encanta estar al día con los frameworks y herramientas emergentes, así que pueden esperar más contenido valioso como este en nuestros próximos artículos.

¡Disfrútalo!

Support:

Recursos utilizados:

  • NextJS: 6.1.1

  • React: 16.4.2

  • Firebase functions: 2.0.0

  • Material-UI: v1.5.0

Referencias:


Acerca de 4Geeks: 4Geeks es una empresa global que en desarrolla y crece (Growth Hacking) productos digitales, y todo en medio, enfocada en aumentar 10X el ROI (Retorno de Inversión) para startups, pequeñas y medianas empresas alrededor del mundo. 4Geeks sirve industrias como E-Commerce & Retail, Startups, HealthTech, Marketing, Banking & FinTech y Real Estate. Con oficinas principales en Estados Unidos, y centros de operación en México y Costa Rica. Pura Vida!

Escucha Quebrando El Cero, un podcast dirigido por Allan Porras, para empresarios comprometidos en crecer.

Comentarios

Entradas más populares de este blog

Si Tu Negocio Está Estancado, Debes Leer Esto

Como Crecer un Producto SaaS con Bajo Presupuesto

5 Casos de Exitos de las Apps mas Utilizadas en el Mundo