Implementing Angular universal on old project can be really, really painful :
- You use vanilla javascript => it can't compile
- You use a peer dep that uses vanilla javascript => it can't compile, and there is a lot of old deps coded this way
I have to implement it on a old project too, and, like you, I had a lot of compilation errors. So I decided to split my app between two parts, two projects :
- The angular old-dependent part, with complex code/feature
- The static pages that needs to be SEO friendly => and, good news, this is what brings you the most SEO juice
The bad part is that the 2 projects are independent from each others, so you can't use things like localStorage, routerLink etc. But they're connected to the same API, so you can always share data between them
Technically, I did it like this :
- Creating a new
app-universal folder, with the app-universal.module.ts
- Importing what I needed from the initial project (like some helpers/interface/services)
- Building my statics pages, with SEO friendly content
- Implementing Angular universal on the project, thanks to this guide : Angular Universal guide
- Changing the
<base href=""> of the simplified app to <base href="/content">
- Creating 3 projects in my
angular-cli.json:
"apps": [
{
"name": "app",
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "app/main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
...
},
{
"name": "universal",
"root": "src",
"outDir": "dist-universal",
"assets": [
"assets",
"favicon.ico"
],
"index": "app-universal/index.html",
"main": "app-universal/main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app-universal",
"...
},
{
"name": "server",
"platform": "server",
"root": "src",
"outDir": "src/app-universal/dist-universal-server",
"assets": [
"assets",
"favicon.ico"
],
"index": "app-universal/index.html",
"main": "app-universal/main.server.ts",
"test": "test.ts",
"tsconfig": "app-universal/tsconfig.server.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app-universal",
...
}
],
- Adding build command shortcuts on my
package.json :
"scripts": {
"prebuild-server": "ng build --prod --aot --app server && ngc -p src/app-universal/tsconfig.server.json",
"build-server": "ts-node src/server.ts",
...
},
and running npm run build-server to compile your simplified app and render it with universal.
- Using Apache
Location and ReverseProxy on my server to launch my main app on the / path, and my simplified app on /content or /blog or /whatever path :
In the /etc/apache2/site-availables/your-project.conf file (on the <VirtualHost:.80> block, after DocumentRoot for example):
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
<Proxy *>
Require all granted
</Proxy>
<Location /content>
ProxyPass http://127.0.0.1:4000
ProxyPassReverse http://1127.0.0.1:4000
</Location>
And then you can use pm2 to keep your Node.js application up in the background: How To Set Up a Node.js Application for Production on Ubuntu 16.04
And that waq done. I had split my project into two sub-project independent from each-other and run them on the same domain, with all the /content/* url SEO friendly
To help you pass trough current universal errors : Angular with universal does not work