Getting started with Angular universal


There are many blogs that offers tutorial on angular universal. However, most of it has some issues. You can clone entire sample from here. Build and run instruction are given as well.

To get it working from scratch, my app is called webapp


ng new webapp --routing

cd webapp

ng g universal --client-project webapp

# New Render Engine
npm install @nguniversal/express-engine

# If using lazy loading
npm install @nguniversal/module-map-ngfactory-loader

npm install --save-dev express webpack ts-loader

# If using Firebase

npm install --save-dev ws xmlhttprequest



src/app/app.module.ts


import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'serverApp' }),
AppRoutingModule, BrowserTransferStateModule
],
providers: [],
//bootstrap: [AppComponent]
})
export class AppModule { }

src/app/app.server.module.ts



import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule} from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
imports: [
ModuleMapLoaderModule, ServerModule, AppModule,
ServerTransferStateModule,
],
bootstrap: [AppComponent],
})
export class AppServerModule {}



Create server.ts in webapp root (not webapp/src folder) and ensure you change your APP_NAME, if you're not using webapp


// These are important and needed before anything else
import 'zone.js/dist/zone-node';
import 'reflect-metadata';

// DOM libs required for Firebase
(global as any).WebSocket = require('ws');
(global as any).XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;

import { enableProdMode } from '@angular/core';

import * as express from 'express';
import { ngExpressEngine } from '@nguniversal/express-engine';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

import { join } from 'path';

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist');
const APP_NAME = 'webapp';

const {
AppServerModuleNgFactory,
LAZY_MODULE_MAP
} = require(`./dist/${APP_NAME}-server/main`);

enableProdMode();

const app = express();

// Set the engine
app.engine(
'html',
ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [provideModuleMap(LAZY_MODULE_MAP)]
})
);

app.set('view engine', 'html');

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

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, APP_NAME));

// Static Assets
app.get('*.*', express.static(join(DIST_FOLDER, APP_NAME)));

// Point all routes to Universal
app.get('*', (req, res) => {
res.render('index', { req });
});

// Start Express Server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});




Create webpack.server.config.js again on webapp (root - not in webapp/src) and gain, please change your APP_NAME to your application name if you're not using webapp. Phew feel like a grandfather for reminding this again.

const path = require('path');
const webpack = require('webpack');

const APP_NAME = 'webapp';

module.exports = {
entry: { server: './server.ts' },
resolve: { extensions: ['.js', '.ts'] },
mode: 'none',
target: 'node',
externals: [/(node_modules|main\..*\.js)/],
output: {
path: path.join(__dirname, `dist/${APP_NAME}`),
filename: '[name].js'
},
module: {
rules: [
{ test: /\.ts$/, loader: 'ts-loader' },
{
test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
parser: { system: true }
}
]
},
plugins: [
new webpack.ContextReplacementPlugin(
/(.+)?angular(\\|\/)core(.+)?/,
path.join(__dirname, 'src'), // location of your src
{} // a map of your routes
),
new webpack.ContextReplacementPlugin(
/(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, 'src'),
{}
)
]
};




edit your package.json and add in the followings. Remember to change your app name (Line 1 and 2)


"build:ssr": "ng build --prod && ng run webapp:server && npm run webpack:server",
"serve:ssr": "node dist/webapp/server.js",
"webpack:server": "webpack --config webpack.server.config.js"




Now to build and run your a

npm run build:ssr && npm run serve:ssr


Next, browse to http://localhost:4000






Comments

Popular posts from this blog

PySpark - Working with JDBC Sqlite database