Creando una aplicación Angular Universal con Angular CLI

Puede obtener una versión más actualizada enhttps://leanpub.com/angular-universal

AngularInDepth se está alejando de Medium. Los artículos más recientes están alojados en la nueva plataforma inDepth.dev . ¡Gracias por ser parte del movimiento en profundidad!

Angular CLI acaba de presentar con la versión 1.3.0-rc.0 la capacidad de crear su aplicación para la plataforma del servidor , utilizando node . A continuación te damos algunos primeros consejos para utilizarlo.

Si es nuevo en Angular universal, puede leer mis artículos anteriores como introducción
:https://medium.com/@feloy/angular-v4-universal-demystified-f06a576d6ca2
—https://medium.com/@feloy/building-a-static-website-with-angular-universal-a1acc49e26e5
—https://medium.com/@feloy/building-a-dynamic-website-with-angular-universal-f8dd7bffb667

Puedes encontrar todo el código fuente de este artículo en el repositorio de github:https://github.com/feloy/ng-cli-universal

Tendrás que instalar la versión 1.3.0-RC.0 y crear un nuevo proyecto:

$ npm uninstall -g @angular/cli
$ npm cache clean
$ npm install -g @angular/[email protected]
$ ng new ng-cli-universal

Con compilación JIT

Primero, .angular-cli.jsonhay que modificar el archivo para adaptar la configuración de la app: no usar más los polyfills (el nodo no los necesita) e indicar la serverplataforma:

"apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [
        "styles.scss"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      },
      "platform": "server"
    }
  ],

$ npm install --save @angular/platform-server

// src/main.ts
import { enableProdMode } from '@angular/core';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
  enableProdMode();
}
export { AppModule } from './app/app.module';

// src/tsconfig.app.json
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "es2015",
    "types": []
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ],
  "angularCompilerOptions": {
    "entryModule": "app/app.module#AppModule"
  }
}

// src/app/app.module.ts
import { ServerModule } from '@angular/platform-server';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ 
      appId: 'ng-cli-universal' 
    }), 
    ServerModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

$ ng build

// ./index.js
require('zone.js/dist/zone-node');
require('reflect-metadata');
const fs = require('fs');
const { AppModule } = require('./dist/main.bundle');
const { renderModule } = require('@angular/platform-server');
renderModule(AppModule, {
    url: '/',
    document: '<app-root></app-root>'
}).then(html => {
    fs.writeFileSync('dist/index.html', html);
});

$ node index.js

Con compilación AOT

También podemos construir nuestra aplicación con AOT:

$ ng build -aot

// ./index.js
require('zone.js/dist/zone-node');
require('reflect-metadata');
const fs = require('fs');
const { AppModuleNgFactory } = require('./dist/main.bundle');
const { renderModuleFactory } = require('@angular/platform-server');
renderModuleFactory(AppModuleNgFactory, {
    url: '/',
    document: '<app-root></app-root>'
}).then(html => {
    fs.writeFileSync('dist/index.html', html);
});

Con los pasos anteriores (con compilación JIT y AOT), obtenemos una aplicación que representa páginas HTML desde el lado del servidor. Cuando carga las páginas HTML renderizadas desde el navegador, solo obtiene páginas web estáticas. Veamos cómo crear también la aplicación del navegador y realizar la transición del servidor a la aplicación del navegador.

El código que sigue se basa en una nueva aplicación creada con Angular CLI. Puede revertir los cambios que hemos realizado antes o borrar y ng new ng-cli-universalvolver a crear la aplicación desde cero.

Necesitaremos instalar el @angular/platform-serverpaquete nuevamente:

$ npm install --save @angular/platform-server

// .angular-cli.json
"apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [
        "styles.css"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    },
    {
      "name": "ssr",
      "root": "src",
      "outDir": "dist-ssr",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "main": "main-ssr.ts",
      "tsconfig": "tsconfig.app-ssr.json",
      "prefix": "app",
      "styles": [
        "styles.css"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      },
      "platform": "server"
    }
  ],

También tenga en cuenta que estamos utilizando archivos específicos main-ssr.tsy src/tsconfig.app-ssr.jsonque src/app/app.server.module.tsdebemos crear antes:

// src/main-ssr.ts
export { AppServerModule } from './app/app.server.module';
// src/app/app.server.module.ts
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppComponent } from './app.component';
import { AppModule } from './app.module';
@NgModule({
  imports: [
          AppModule,
          ServerModule
  ],
  bootstrap: [
          AppComponent
  ]
})
export class AppServerModule {}
// src/tsconfig.app-ssr.json
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "commonjs",
    "types": []
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ],
  "angularCompilerOptions": {
    "entryModule": "app/app.server.module#AppServerModule"
  }
}

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ 
      appId: 'ng-cli-universal' 
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

$ ng build -aot 
$ ng build -aot -app ssr

require('zone.js/dist/zone-node');
require('reflect-metadata');
const fs = require('fs');
const { AppModuleNgFactory } = require('./dist-ssr/main.bundle');
const { renderModuleFactory } = require('@angular/platform-server');
renderModuleFactory(AppModuleNgFactory, {
    url: '/',
    document: fs.readFileSync('dist/index.html', 'utf8')
}).then(html => {
    fs.writeFileSync('dist-ssr/index.html', html);
});

En este punto, nuestro index.jsarchivo solo puede representar (del lado del servidor) la página de inicio de nuestra aplicación. Podríamos adaptar el script para poder representar cualquier página de nuestra aplicación. Puedes echar un vistazo ahttps://medium.com/@feloy/building-a-dynamic-website-with-angular-universal-f8dd7bffb667para obtener algunos ejemplos de scripts que obtienen como argumento la URL a representar.

¡Feliz Universal!

Suggested posts

Mis recursos de codificación más utilizados

Mis recursos de codificación más utilizados

Esta semana, recibí un correo electrónico de un miembro de la lista de correo electrónico diaria. Querían saber: ¿Qué recursos visita diariamente, semanalmente y mensualmente? ¡Gran pregunta! Estoy feliz de intentar compartir algunas ideas sobre mi flujo de trabajo y los principales recursos que uso.

Serie de bibliotecas lit — 1: Una inmersión profunda en la biblioteca lit-html

Serie de bibliotecas lit — 1: Una inmersión profunda en la biblioteca lit-html

El propósito de esta serie de blogs es profundizar en la biblioteca Lit y ​​obtener una comprensión integral de sus características únicas y cómo se diferencia de otras bibliotecas y marcos en el mercado. La serie se divide en tres partes, que abarcan temas como 1.

Related posts

¿Es el arte alguna vez apolítico?

¿Es el arte alguna vez apolítico?

Ayer cerramos la puerta del Festival de la Canción de Eurovisión de este año con una gran final brillante y caótica en la que la cantante sueca Loreen se llevó a casa el trofeo, convirtiéndose en la primera mujer en ganar dos veces y devolviendo la corona a Suecia 50 años después de que ABBA ganara la competencia. con “Waterloo”. Se convirtieron en uno de los actos más grandes en el canon de la música pop.

Conversaciones peligrosas

Conversaciones peligrosas

Si queremos seguir prosperando en este planeta, vamos a tener que tener conversaciones peligrosas. Aquellas que desafían lo que hemos hecho, lo que estamos haciendo y lo que actualmente vamos a seguir haciendo (o planeamos hacer).

La mentira del vaquero

Cómo las megacorporaciones vendieron a los estadounidenses una falsedad fornida

La mentira del vaquero

Es una mañana brillantemente dorada en las ondulantes colinas del oeste, mientras los primeros rayos del sol iluminan la hierba escarchada de las llanuras. Una manada de ganado Angus plácido, negro azabache y enorme, se recorta contra el amanecer mientras avanzan por un sendero trillado hacia un lugar que todos conocen bien; la barra de desayuno

El primer libro para niños sobre drogarse

El primer libro para niños sobre drogarse

(Advertencia: esto es una sátira, con la intención de ser alegremente subversivo; definitivamente no es para niños) Has visto a tu mamá y papá esconderse en la cocina y fumar esos cigarrillos malolientes. ellos te dicen