Javier Batres
Luis Abdel Rangel Castro
¿Cómo configurar Universal en Angular?
La configuración de Angular Universal permite que las aplicaciones se ejecuten en el servidor utilizando Node.js y Express para proporcionar un SSR (Server Side Rendering). Esto mejora el tiempo de carga y el SEO de las aplicaciones. Aquí te explicamos cómo hacerlo con comandos simples y cómo solucionar posibles problemas que puedan surgir durante el proceso.
¿Nececito documentación oficial?
Antes de realizar cualquier configuración, es altamente recomendable consultar la documentación oficial de Angular para entender completamente los pasos requeridos y las funcionalidades disponibles. Esta documentación va a guiarte a lo largo del proceso y asegurarte de hacerlo correctamente sin olvidar pasos cruciales.
¿Cómo instalar Angular Universal?
Instalar Angular Universal: Angular facilita la configuración mediante un comando que automatiza la mayoría del proceso. Este comando toma en cuenta la estructura y lineamientos de Angular para generar un servidor Node.js en Express que servirá los archivos de la aplicación.
ng add @nguniversal/express-engine
Al ejecutar este comando, asegúrate de reemplazar <nombre-proyecto> con el nombre real de tu proyecto en Angular.
Parar el servidor de desarrollo: Antes de proceder, asegúrate de que tu servidor de desarrollo esté detenido para evitar conflictos.
Ejecutar el comando en la terminal: Usa el nombre de tu proyecto que está configurado en Angular para ejecutar el comando:
ng add @nguniversal/express-engine --clientProject <nombre-proyecto>
¿Qué modificaciones realiza Angular?
Al ejecutar el comando, Angular realiza varias modificaciones automáticas:
angular.json.En Visual Studio Code, puedes visualizar fácilmente qué archivos fueron creados o modificados tras la ejecución del comando.
¿Cómo resolver errores comunes?
A veces, pueden surgir errores al intentar ejecutar el proyecto con Universal, como pruebas unitarias que fallan o referencias a elementos que solo existen en el navegador. Si sucede que el build falla, lo más probable es que se trate de un tema con las pruebas unitarias o dependencias del lado del cliente.
Errores con pruebas unitarias: Si las pruebas unitarias fallan, puedes comentar temporalmente el código relacionado con ellas para continuar el desarrollo, aunque se sugiere buscar una solución a fondo posteriormente.
Referencias del navegador en el servidor: Errores como referencias directas a window, document o elementos exclusivos del navegador necesitan ser manejados apropiadamente. Angular Universal proporciona clases para determinar dinámicamente el entorno de ejecución y adaptar el código en consecuencia.
¿Cómo saber cuándo estamos en un entorno de navegador o servidor?
Angular ofrece clases que permiten "interceptar" distintos momentos de la ejecución del código para adaptarlo según el entorno:
IS_PLATFORM_BROWSER: Esta función ayuda a determinar si el código se está ejecutando en el navegador.
import { isPlatformBrowser } from '@angular/common'; import { PLATFORM_ID } from '@angular/core'; constructor(@Inject(PLATFORM_ID) private platformId: Object) { if (isPlatformBrowser(this.platformId)) { // Ejecutar lógica específica para el navegador } }
IS_PLATFORM_SERVER: Esta función permite saber si el código está siendo ejecutado en el servidor.
Aprender y aplicar estas técnicas es crucial para gestionar aplicaciones robustas que utilicen Angular Universal efectivamente, asegurando un correcto SSR y una interacción fluida entre el servidor y el cliente.
Javier Batres
Luis Abdel Rangel Castro
Leandro Nicolás Matilla
Carlos Eduardo Jaramillo Franco
Luis Emmanuel Rodas Camposeco
Bryan Alejandro Sánchez Ramírez
Javier Batres
Teddy Everson Sipra Morgado
Luis Abdel Rangel Castro
Diego Ferrer
Rodrigo Rodriguez
Irving Juárez
Rodrigo Rodriguez
Giovanny Contreras Muñoz
Erik Elyager
Victor Alfredo Matzar Say
Oscar Morera García
Ivan Alexander Flores Linares
Erik Elyager
Manuel Andrade
Nicolas Molina
ProfesorJosé Guillermo
Cristian Refugio Covarrubias Patiño
El comando cambio en Angular9
ng add @nguniversal/express-engine
npm run dev:ssr
El comando para instalar Angular Universal es el siguiente:
ng add @nguniversal/express-engine
En el examen al seleccionar esa opción dice que está mal.
Hola, si alguno está siguiendo el tutorial con angular 8 le fallará cuando intentan compilarlo porque todavía no hay soporte de express-engine para angular 8. Si quieren de igual manera hacerlo, deben desactivar el "enableIvy" en "angularCompilerOptions" en los archivos tsconfig.app.json y en tsconfig.json! saludos
cuando estoy implementando angular universal al ejecutar el proyecto con el comando que indica en la documentacion me indica que "DON'T USE IT FOR PRODUCTION", y me surge la siguiente pregunta.
¿Sigo usando el comando "ng build --prod" para generar la version de produccion o existe algun otro comando?
¿Angular Universal unicamente funciona en desarrollo?
Que dolor de cabeza es pasar una app a SSR. Lo importante es que eso vaya dentro de la planeación del proyecto para prevenir la mayor cantidad de errores posible. Ya después con el tiempo le agarras la onda a lo que debes de cuidar.
No se que hice o si tiene que ver con el hecho de ser la versión 9 pero no me da error lo del Swiper...
Lo mas probable es que la librerìa Swiper, no se compatible con el nuevo compilador IVY, la soluciòn ese desactiviar ese compilador o en todo caso buscar una librerìa que se compatible con angular 9
Igual en la version 10
EN UN CSR para prod usariamos un AWS S3 por ejemplo para servir la web estatica. Pero con SSR deberiamos pensar en una instancia EC2 por ejemplo verdad? para levantar el runner de node?
Hago el build y veo que ahora en la carpeta "dist" genera dos carpetas "browser" y "server" , en esta ultima hay un archivo main.js
La duda es ¿Donde debe ir el archivo main en el servidor de produccion?
¿Como verifico si se esta haciendo el server side rendering?
La carpeta "dist" es de distribution y esa es la que Babel optimiza para que se mande a produccion.
Gracias Irvingjuarez
como configurar Nginx con angular universal ?
Tal vez este artículo te puede servir.
Tengo este error:
D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:264277 proxyRequestMethods(Index, '_index', IDBIndex, [ ^ ReferenceError: IDBIndex is not defined at Module.2139 (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:264277:38) at __webpack_require__ (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:264813:42) at Module.37152 (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:250619:61) at __webpack_require__ (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:264813:42) at Module.9717 (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:252396:81) at __webpack_require__ (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:264813:42) at Module.90852 (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:264173:81) at __webpack_require__ (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:264813:42) at Module.63413 (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:2454:80) at __webpack_require__ (D:\Documentos\CursosPlatzi\Angular8\platzi-store\dist\platzi-store\server\main.js:264813:42) A server error has occurred. node exited with 1 code. connect ECONNREFUSED 127.0.0.1:52604
Ya he buscado en algunos issues de Github, pero no lo he podido solucionar aún, si encuentran alguna solucion, porfavor comenten.
Estoy teniendo el siguiente error al momento de correrlo ++npm run dev:ssr++
C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:1008 name: window.location.pathname, ^
**ReferenceError: window is not defined at routingInstrumentation (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:1008:19) at BrowserTracing.HEiX.BrowserTracing.setupOnce (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:80075:9) at setupIntegration (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:3305:17) at C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:3320:9 at Array.forEach (<anonymous>) at Object.setupIntegrations (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:3318:37) at BrowserClient.baEJ.BaseClient.setupIntegrations (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:114924:48) at Hub.5EJM.Hub.bindClient (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:54891:20) at Object.initAndBind (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:175954:9) at Object.init (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:91413:12) at Object.init (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:206453:15) at Module.ZAI4 (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:112280:54) at webpack_require (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:26:30) at Module.24aS (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:43459:69) at webpack_require (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:26:30) at Module.K011 (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:85263:80) at webpack_require (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:26:30) at Module.uj+Y (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:215423:74) at webpack_require (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:26:30) at Object.0 (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:3048:18) at webpack_require (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:26:30) at C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:117:18 at Object.<anonymous> (C:\Users\Oscar\Documents\TFS_HANGARTEC\platzi-store\dist\platzi-store\server\main.js:120:10) at Module._compile (internal/modules/cjs/loader.js:1076:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10) at Module.load (internal/modules/cjs/loader.js:941:32) at Function.Module._load (internal/modules/cjs/loader.js:782:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) at internal/main/run_main_module.js:17:47
A server error has occurred. node exited with 1 code. connect ECONNREFUSED 127.0.0.1:57734**
Cual puede ser la causa de este problema?
Me podrias ayudar? cuando corro mi pagina con el servidor me lanza este error!! ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'assets/js/popper.min.js.map'
Parece ser un problema con tus rutas, mira aquí como las debes tener definidas.
Como puedo usar SSR en mi servidor de cpanel??? Falto este tema en este módulo.
Hola, para esto necesitas NodeJs corriendo en tu servidor.
Un Cpanel es muy limitado, ya que viene con la formula LAMP (Linux, Apache, Mysql y PHP) por defecto y es complejo cambiarlo, debes hablar con tu proveedor.
Te recomiendo mejor un instancia en donde tu tengas total control y puedas instalar node y lo que sea.
Te recomiendo DO (Digital Ocean) para iniciar tiene maquinas desde 5 USD.
Heroku también es un excelente opción si quieres iniciar mucho más rápido.
Vean en ++$ ng version++ que las versiones de (grupo 1):
Sean iguales entre sí, así como de (grupo 2):
En mi caso, el primer grupo marcaba ++0.1102.14++ y el segundo marcaba ++11.2.14++. Esto es importante recalcarlo porque si vienen de versiones muy viejas de Angular como yo, que en mi caso fui migrando desde ng7, muchos de estos paquetes no se actualizarán por igual y esto les puede dar dolores de cabeza al instalar Angular Universal por incompatibilidad del schematic y el devkit.
También recuerden modificar el comando que el profesor muestra para su versión de Angular. En mi caso utilicé:
$ ng add @nguniversal/express-engine@11.2.1 --clientProject
Por último, siempre revisen que la versión de Node sea compatible con la versión de Angular, además de tener NPM siempre en su última versión. Si usan NVM para portar diferentes versiones de Node en sus proyectos, es algo que deben de considerar por igual. En mi caso, tenía rato sin tocar Angular y tenía Node en versión superior a Angular, lo cual me producía errores.
hay que revisar la documentación con esto porque a la fecha, ha cambiado.