ANGUL    R OUTSIDE THE BROWSER

SERIOUSLY?

ANGULAR

OUTSIDE THE

BROWSER!!

ANGULAR FOR

A BETTER TITLE

THE HEADLESS WEB*

UNIVERSAL

INTRODUCING

Wassim Chegham

Developer Advocate

@manekinekko

YOUR TURN

SERVER

RENDERING

SINGLE PAGE

APPLICATIONS

 SEARCH

 ENGINE

 0PTIM.

SOCIAL LINK

PREVIEWING

AND THE

WEB APP

GAP

SERVER

RESPONSE

ASSET DOWNLOADS

CLIENT INIT

CLIENT DATA

PAINTING

0"

3" ~ 20"

THE WEB APP GAP

IMPROVING

RAIL*

THE "L" IN

HOW DID

FRAMEWORKS

FIX THAT GAP?

SERVER

RESPONSE

ASSET DOWNLOADS

CLIENT INIT

CLIENT DATA

PAINTING

SERVER RENDERED PAGE

CLIENT TAKES OVER

USER VIEWS THE PAGE

AND NOW

HOW DOES

IT  WORK?

APPLICATION LAYER

VIEW COMPILER LAYER

RENDERING LAYER

BROWSER

WEB WORKER...

SERVER (NODE)

WHAT ABOUT

APP STATE?

RECORD EVENTS

ASSET DOWNLOADS

CLIENT INIT

CLIENT DATA

PAINTING

SERVER

CLIENT

REPLAY EVENTS

SERVER

RENDERING

PREBOOT.JS

PREBOOT.JS IS RECORDING EVENTS...

UNIVERSAL APP

ARCHITECTURE*

*THIS IS OUR PROPOSAL

(app.component.ts)

server.ts

browser.ts

server

.module.ts

browser

.module.ts

Application layer

index.html

import { Component } from '@angular/core';
import { Meta, Title } from "@angular/platform-browser";

@Component({
  selector: 'app-home',
  template: `<h3>Home View</h3>`
})
export class AppComponent {
  constructor(meta: Meta, title: Title) {
    title.setTitle('Current Title Page');
    meta.addTags([
      {name: 'author', content: 'Wassim Chegham'},
      {name: 'keywords', 
       content: 'angular,universal,iot,omega2+'},
      {name: 'description', 
       content: 'Angular Universal running on Omega2+'}
    ]);
  }
}

app.component.ts

@NgModule({
  imports: [
    BrowserModule.withServerTransition({appid: 'universal-app'}),
    AppCommonModule,
  ],
  providers: [
    {provide: AppService, useClass: ClientAppService},
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppBrowserModule {}

browser.module.ts

import { platformBrowser } from '@angular/platform-browser';
import {
  AppModule
} from './app/browser.module';
import {
  AppModuleNgFactory
} from './ngfactory/browser.module.ngfactory';

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

browser.ts

@NgModule({
  imports: [
    AppBrowserModule,
    ServerModule,
  ],
  providers: [
    {provide: AppService, useClass: ServerAppService},
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

server.module.ts

import {
  AppServerModuleNgFactory
} from '../src.ngfactory/src/app/server.module.ngfactory';

import * as express from 'express';
import { ngExpressEngine } from './app/core/express-engine';

const app = express();

app.engine('html', ngExpressEngine({
  baseUrl: 'http://localhost:4200',
  bootstrap: [AppServerModuleNgFactory]
}));
app.set('view engine', 'html');

app.get('/', (req, res) => { res.render('index', {req}); });

app.listen(8000,() => console.log('listening...') );

server.ts

const fs = require('fs');
const path = require('path');
import {renderModuleFactory} from '@angular/platform-server';

const templateCache  = new Map();

export function ngExpressEngine(setupOptions){
  return async function(filePath, options, callback){
    if(!templateCache.has(filePath)){
      let file = fs.readFileSync(filePath);
      templateCache.set(filePath, file.toString());
    }
    const html = await renderModuleFactory(setupOptions.bootstrap[0], {
      document: templateCache.get(filePath),
      url: options.req.url
    });
    callback(null, html);
  }
}

express-engine.ts

ONE

MORE

THING

DO NOT EVER NEVER TOUCH

THE DOM

PLEASE

import {Directive, ElementRef, Renderer} from '@angular/core';

@Directive({
  selector: '[x-large]'
})
export class XLarge {
  constructor(element: ElementRef, renderer: Renderer) {

    renderer.setElementStyle(
        element.nativeElement, 'fontSize', 'x-large'
    );

  }
}

RENDERER

USE ANGULAR'S

>4s

~500ms

WAIT! THERE

IS MORE

NODE.js STARTER

CLI ADDON

COMING SOON

# preview CLI
$ npm i universal-cli

# add server-side support
# and SSR on the fly
$ ng new awesome-app --universal

# generate static site
$ ng new awesome-app --universal-prerender

# generate a static version
$ ng build

# generate static docs
$ ng docs

MOOOOORE

BACKENDS

JAVA

PHP

GO

.NET

BETTER

INTEGRATION

WITH ANGULAR

HTTP•TESTING•ZONES•SEMVER...

WE LOVE

 

 

 

CONTRIBUTIONS

click here

TH    NK

@manekinekko