Menu

Angular Universal + Firebase

angularuniversalexpress - June 21, 2018 por Carlos Rojas | Edita este Post.
Angular CLI6.0.xAngular6.x

Angular Universal es la tecnologia de SSR de la plataforma Angular. Vamos a ver como combinarla con Firebase.

¿ Por que necesitamos Firebase ?

Como vimos anteriormente el SSR corre en el lado de un servidor, entonces, utilizando Firebase Functions y Firebase Hosting vamos a habilitar nuestro SSR en los servidores de Google sin necesidad de preocuparnos del mantenimiento de un Servidor.

¿ Que es Firebase Functions ?

Firebase Functions es el servicio para realizar computing directamente en Firebase. Es decir si tienes que realizar una tarea que comunmente la hacia el backend como actualizar un numero de registros cada que ocurra una acción ahora lo puedes hacer utilizando Firebase y Javascript.

¿ Que es Firebase Hosting ?

Firebase Hosting es el servicio que nos permite publicar nuestras paginas en HTML, CSS y JS en Internet.

¿ Cuales son los pasos ?

Bueno lo primero es crear un proyecto en Firebase, lo puedes hacer aquí.

Lo segundo es que he creado un repo con un proyecto en Angular y con Universal Ready siguiendo la documentación oficial y desplegando todo en la carpeta /functions para facilidad.

  • Entonces, una vez clonado nuestro repositorio debemos instalar las dependencias con:
$npm install

y generar los archivos que va a utilizar el ssr.

$ng build --prod
$ng run universalApp:server

Esto genera algunas carpetas browser y server en nuestro directorio functions

Estos archivos son los que vamos a enviar a Firebase.

  • Ahora vamos a conector nuestro proyecto con Firebase desde nuestra terminal.
$firebase login
  • Inicializamos ahora un nuevo proyecto desde la terminal.
$firebase init

Empezaremos el asistente de firebase.

Debemos elegir hostingy functionsque son las que vamos a utilizar.

Asociamos el proyecto con el que creamos previamente en Firebase.

Seleccionamos Javascript en este paso.

y terminamos la configuracion de Functions, luego nos preguntara por Hosting y podemos utilizar esta configuración.

  • Una vez configurado todos debemos agregar las dependencias que vamos a utilizar en el archivo functions/package.json
{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "serve": "firebase serve --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "dependencies": {
    "@angular/animations": "6.0.2",
    "@angular/common": "6.0.2",
    "@angular/compiler": "6.0.2",
    "@angular/core": "6.0.2",
    "@angular/forms": "6.0.2",
    "@angular/http": "6.0.2",
    "@angular/platform-browser": "6.0.2",
    "@angular/platform-browser-dynamic": "6.0.2",
    "@angular/platform-server": "6.0.2",
    "express": "~4.16.3",
    "firebase-admin": "~5.12.1",
    "firebase-functions": "~1.0.2",
    "rxjs": "~6.1.0",
    "zone.js": "~0.8.26"
  },
  "private": true
}

y debemos instalar los paquetes en nuestra maquina con:

$npm --prefix functions install

y vamos a agregar un archivo index.js que va a ejecutar nuestras cosas en el servidor.

require('zone.js/dist/zone-node');

const functions = require('firebase-functions');
const express = require('express');
const path = require('path');
const { enableProdMode } = require('@angular/core');
const { renderModuleFactory } = require('@angular/platform-server');

const { AppServerModuleNgFactory } = require('./dist/server/main');

enableProdMode();

const index = require('fs')
  .readFileSync(path.resolve(__dirname, './dist/browser/index.html'), 'utf8')
  .toString();

let app = express();

app.get('**', function(req, res) {
  renderModuleFactory(AppServerModuleNgFactory, {
    url: req.path,
    document: index
  }).then(html => res.status(200).send(html));
});

exports.ssr = functions.https.onRequest(app);
  • Ahora vamos a modificar un poco el archivo firebase.json
"public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source" : "**/*.@(css|js)",
        "destination": "/index2.html"
      },
      {
        "source": "**",
        "function": "ssr"
      }
    ]

Algo interesante aquí es que usamos el archivo index2.html, esto se debe a que firebase no ejecuta Functions si detecta el index.html.

Ahora ejecutamos estos ultimos comandos para dejar todo listo en la carpeta public y enviamos a Firebase.

$cp -a functions/dist/browser/. public/
$mv public/index.html public/index2.html
$firebase deploy

Esto es todo, puedes ver el resultado aquí

Bueno esto es todo por el dia de hoy, espero haya sido de utilidad :)

Ver código

¡Compártelo!