Ok, i'm sorry i miss read your question :).
First of all, Apache is no more required to serve your application. This is because node.js will serve it for you.
So if apache service is no required on your server, you should disable it for security questions and probably to avoid port conflict between apps.
Server rendering will required to modify your angular app. Let's start.
1) Go to your angular project and install those package:
npm i -S @angular/platform-server @angular/animations express
2) Open src/app/app.module.ts and modify the commented line below with your app name.
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'your-angular-app-name' }), // You just have to change this line
FormsModule,
HttpModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
3) Now, we'll set the server in your app. For this, create the file app/src/app.server.module.ts and at the following code.
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
ServerModule, // Load the servermodule
AppModule // Load the modules of AppModule
],
bootstrap: [AppComponent]
})
export class AppServerModule { }
4) Create the file src/server.ts and add the following code. This is the node server.
import 'reflect-metadata';
import 'zone.js/dist/zone-node';
import { platformServer, renderModuleFactory } from '@angular/platform-server';
import { enableProdMode } from '@angular/core';
import { AppServerModuleNgFactory } from '../dist/ngfactory/src/app/app.server.module.ngfactory';
import * as express from 'express';
import { readFileSync } from 'fs';
import { join } from 'path';
const PORT = 4000;
enableProdMode();
const app = express();
let template = readFileSync(join(__dirname, '..', 'dist', 'index.html')).toString();
app.engine('html', (_, options, callback) => {
const opts = { document: template, url: options.req.url };
renderModuleFactory(AppServerModuleNgFactory, opts)
.then(html => callback(null, html));
});
app.set('view engine', 'html');
app.set('views', 'src');
app.get('*.*', express.static(join(__dirname, '..', 'dist')));
app.get('*', (req, res) => {
res.render('index', { req });
});
app.listen(PORT, () => {
console.log(`Listening on http://localhost:${PORT}...`);
});
5) Open src/tsconfig.app.json and add the file server.ts to the exclude json variable.
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "es2015",
"baseUrl": "",
"types": []
},
"exclude": [
"server.ts", # Just here !
"test.ts",
"**/*.spec.ts"
]
}
6) Open tsconfig.json locate at the root of your project and add the angularCompilerOptions like this:
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"baseUrl": "src",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2016",
"dom"
]
},
"angularCompilerOptions": {
"genDir": "./dist/ngfactory",
"entryModule": "./src/app/app.module#AppModule"
}
}
7) Now, modify your package.json to make your life easier.
{
"scripts": {
"prestart": "ng build --prod && ngc",
"start": "ts-node src/server.ts",
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
}
8) Now you can test your app with:
npm start
I hope this will help you.
NOTE:
If your project already exist, you'll probably have some problems with some modules like Angular Material because node.js doesn't know, window object, documents object.
So, you'll have to:
Create app.common.module.ts, whose the other module loading file will inherit. And gather common module (client+server).
Finally put the modules which annoying us in the app.module.ts .
Cdly.