How to combine Angular4 and Slim Framework applications into one application for production


This tutorial helps to get any anular4 application into the production with the PHP or any other kind of server side technology, in this one we use the slimframework but the concept remains the same with other server side technologies.

Assumptions:

This tutorial assumes that you are already familiar with Angular2 or Angular4 and also Slim framework. Also that you are able to build application in Angular4, which works as user interface. And in slim framework which works as REST API for Angular frontend.

if not, not to worry, for purpose of this tutorial we are following very basic code structure. you can follow up the getting start guides for Angular and the first application guide for slim framework.

Tools Needed:

  • Text Editor or IDE of your choice.
  • Command terminal for command execution.

Scenario:

Let's say we are developing a REST based Single page application for which we are working on angular4 and slim framework. Now we know that we are running slim on php server and angular on node server and both are on different ports. Looks good when we are developing on a single machine, but what about production environment ? Do we need php based server, or node based server? or both ?

No need to worry, Angular4 is awesome and it has already taken care of such scenario, it lets us compile the TypeScript code into JavaScript and use it as integrated web module within any kind of application.

Directory Structure:

Angular:

Angular4 Directory structure

When you run the angular app with npm start or ng serve command it should be running and should be accessible on the browser on the dedicated port, because I am using a brand new application I see following screen.

running angular4 app

open a terminal and move to the root directory of your Angular project and type following command to prepare the production version of code:


user@machine:/path-to-angular-root/$ ng build --prod

The output will be long one but I have displayed last part only it should look something like this:


Time: 10113ms
chunk    {0} polyfills.fdc74e8f101f8a37cfda.bundle.js (polyfills) 160 kB {4} [initial] [rendered]
chunk    {1} main.400d851a99dcb4e3952c.bundle.js (main) 7.86 kB {3} [initial] [rendered]
chunk    {2} styles.d41d8cd98f00b204e980.bundle.css (styles) 69 bytes {4} [initial] [rendered]
chunk    {3} vendor.e9b7451dfc3e88609ded.bundle.js (vendor) 1.14 MB [initial] [rendered]
chunk    {4} inline.cee5b2ecbc0966619ca1.bundle.js (inline) 0 bytes [entry] [rendered]

Now you should see the directory called "dist" and inside will be all complied dependencies you need with your application. If you go inside this you should see some files like this:

Angular Distribution directory contains

Now in the "dist" directory open the index.html and find tag and replace with tag as shown in the code below, this will tell angular to look for base in relative path instead of root path.


<base href="/">

and replace with


<base href="./">

if you try to access this directly from some kind of serving web server like "apache" it will still be working as in first step. So the first part is now ready.

working angular directly

Slim:

Slim Directory Structure

Setting up the slim application is easy and we are not going into details, so you should be able to run the slim application Alright. So let's skip to the part where we make angular run with the slim. Now you need to copy the "dist" directory from angular root to slim. I have placed it in such way that I am able to refer it from my route. In my index I have added the view like this:

Angular4 directories inside slim framework


$container['view'] = new \Slim\Views\PhpRenderer("../templates/");

$app->get('/', function (Request $request, Response $response) {
	$response = $this->view->render($response,"index.html");
	return $response;
});

also I have updated the index.html file to reflect the path of resources, just append "dist/" before the resources as you can see in the code below:


<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Demoapp</title>
  <base href="./">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="dist/styles.d41d8cd98f00b204e980.bundle.css" rel="stylesheet"/></head>
<body>
  <app-root>Loading...</app-root>
<script type="text/javascript" src="dist/inline.aad7bb9500f7ce109675.bundle.js"></script>
<script type="text/javascript" src="dist/polyfills.fdc74e8f101f8a37cfda.bundle.js"></script>
<script type="text/javascript" src="dist/vendor.e9b7451dfc3e88609ded.bundle.js"></script>
<script type="text/javascript" src="dist/main.56d465fe59792add34e8.bundle.js"></script></body>
</html>

I have copied "dist" directory inside "src/public" directory in my slim application and "src/templates" contains the index.html file. Now I just run the application and it will be able to take up angular at the '/' path as shown in the image below.

Angular4 running with Slim