Installation

Angular Universal will eventually be compatible with many different types of back end technologies (i.e. Java, PHP, etc.), but for right now it only works with a JavaScript back end (i.e. node.js) and .NET (via ASP.NET core).

Please note that while the instructions below detail how to install and use Angular Universal from scratch, there are two other viable ways to get started:

  1. The Angular Universal Starter
  2. The Angular Universal CLI (coming soon)

Prerequisites

Before getting started, make sure you have the following installed:

  • Node 4 or higher
  • Git (only required if using starter repo)

NodeJS & Express integration

Angular Universal can be integrated with any server side framework of even just plain JavaScript. This guide focuses on the most popular node.js server-side framework, Express. You should be able to easily adapt this to Hapi or other variations of node.js based servers, however, we will publish more guides soon.

  • mkdir universalapp create a new directory for your app (replace universalapp with the name of your app)
  • cd universalapp
  • npm init Just accept defaults when prompted
  • Copy the following files from the Universal Starter into your app root directory:
  • Copy the scripts, dependencies and devDependencies from the Universal Starter package.json into your local package.json file
  • npm install
  • Create a new file src/server.ts. You can use the starter repo server.ts for reference, but there are really just two key parts to be aware of:

// polyfills have to be first
import 'angular2-universal-polyfills';
import { createEngine, ExpressEngineConfig } from 'angular2-express-engine';
import { MainModule } from './app.node.module';  // will change depending on your app

// 1. set up Angular Universal to be the rendering engine for Express
app.engine('.html', createEngine({}));

// 2. get the top level NgModule for the app and pass in important values to Angular Universal 
app.get('/*', (req, res) => {

  // Our Universal - express configuration object
  const expressConfig : ExpressEngineConfig = {
    req,
    res,
    ngModule: MainModule,
    preboot: false,
    baseUrl: '/',
    requestUrl: req.originalUrl,
    originUrl: 'http://localhost:3000'
  };

  // NOTE: everything passed in here will be set as properties to the top level Zone
  // access these values in your code like this: Zone.current.get('req');
  // this is temporary; we will have a non-Zone way of getting these soon
  res.render('index', expressConfig);
});
  • Create your top level NgModule on the server side in the src/app.node.module.ts file (like this)
    • Note that in the starter repo app.node.module.ts and app.browser.module.ts are exactly the same, but in your app they will almost certainly be different as you specify node-only or browser-only providers in the imports section as appropriate for each specific platform.
    • Also note that this is where you set your root App component and top level routes. You should try to make it so that you use the same exact component for the server or browser. Most of the differences will be in the NgModule provider imports that you need to specify.
  • The webpack.config that you copied over uses /src/client.ts at the entry point into the client side app.
    • Note how client.ts uses the following code to have Angular Universal cooridinate the browser side bootstrap process:
// important for this to be first in your client.ts file so polyfills can be properly applied
import 'angular2-universal-polyfills';
import { platformUniversalDynamic } from 'angular2-universal';
import { MainModule } from './app.browser.module';  // this will change depending on your app

const platformRef = platformUniversalDynamic();

// bootstrap returns promise if you want to do something after complete
platformRef.bootstrapModule(MainModule);

This replaces the normal Angular bootstrap() that you would normally use for client-only Angular apps. Note that the MainModule you pass in here can and should be different (see app.browser.module.ts in starter repo) than the MainModule you reference from the server side start (i.e. src/server.ts). This is due to the fact that your imports for each side may be slightly different. In many cases, as you build out your Universal app, you will have some browser-only or node-only dependencies and that is when app.node.module.ts and app.browser.module.ts would be different.

Final note is that in your imports for your Universal app on both the browser and node NgModule, you need to add UniversalModule:

import { UniversalModule } from 'angular2-universal';
@NgModule({
  imports: [
    UniversalModule // includes stuff like the universal HttpModule; must be first import
    // other imports here
  ]
})
export class MainModule {

}

results matching ""

    No results matching ""