There are so many ways we can package and ship the Angular app to production. There are serverless and traditional architectures. In traditional architecture, we have different ways: Nodejs, Java, Python, etc.

In this post, we are going to discuss how we can package the Angular app with nodejs backend. Finally, we will deploy this packaged application on AWS Elastic Beanstalk.

Example Project

This is a simple project which demonstrates developing and running Angular application with NodeJS. We have a simple app in which we can add users, count, and display them at the side, and retrieve them whenever you want.

Image for post

Here is the related article: How To Develop and Build Angular App With NodeJS .

1. Manual Implementation

In this manual implementation, we build the Angular app and place the appropriate code into one folder and run or deploy the application. As a first step, we need to build the Angular app and all the static assets and built files are placed into the dist folder.

// change to my-app directory
cd my-app

// build the app
npm run build

All the built and static assets are placed under this folder dist/angular-nodejs-example

Image for post
built/static assets

Once you built the application, all you need to do is create a separate folder and place the nodejs related stuff in that folder. Let’s create a folder called angular-nodejs and put server.js, package.json, and dist folder inside it.

Image for post
angular-nodejs

Run the application

Let’s run the app by importing the whole folder angular-nodejs into VSCode editor and install the dependencies for the server.

// install dependencies
npm install

// run the app
npm start (node server.js)
Image for post
server listening on 8081

The app is running on the server port 8081.

Image for post
nodejs serving the assets on 8081

Disadvantages

All the below steps should be done manually and these are time-consuming tasks.

  • We have to build Angular code manually
  • We have to place all the built files into a separate folder
  • We need to install node dependencies before we run the app

2. With Webpack

In the above implementation, once we put everything in the folder we need to install dependencies for the nodejs server to run the app. This is an additional step we need to do before running the app.

We can skip this step with the webpack. When we build the Angular code, the Angular CLI uses a webpack internally to build and bundle the entire code into few files. We can use the same for the nodejs server as well.

First, we need to install a webpack globally and in the project as well.

// install webpack
npm install webpack -g
npm install webpack --save

We need to have a webpack.config.js in the root folder since a webpack looks for this file. Here is the file. We have an entry file and output file and it is placed in the root folder.

const path = require('path');

module.exports = {
  entry: './server.js',
  mode: 'production',
  target: 'node',
  output: {
    path: path.resolve(__dirname, '.'),
    filename: 'server.bundle.js'
  }
};

Let’s build and bundle it. All you need to do is to run this command webpack and the webpack looks for this file called webpack.config.js andbuild the entire server code and put it into one file called server.bundle.js. Here is the modified package.json file.

{
  "name": "angular-nodejs-example",
  "version": "1.0.0",
  "description": "node server",
  "main": "index.js",
  "scripts": {
    "start": "node server.bundle.js",
    "build": "webpack",
    "dev": "nodemon ./server.js localhost 3080",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/bbachi/angular-nodejs-example.git"
  },
  "author": "Bhargav Bachina",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/bbachi/angular-nodejs-example/issues"
  },
  "homepage": "https://github.com/bbachi/angular-nodejs-example#readme",
  "dependencies": {
    "express": "^4.17.1",
    "webpack": "^4.42.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.2"
  }
}

If the filename is different than webpack.config.js you need to pass that filename with the webpack command webpack <filename>. Once you build the server code all you need is server.bundle.js file. You don’t even need any packages, package.json, etc.

Image for post
angular-nodejs

With this, we can skip the step npm install (installing dependencies) and you can just run node server.bundle.js and you can see the app running on port 8081.

Disadvantages

The only thing we have solved is to skipping node dependencies installation. There are still things we are doing here manually.

  • We have to build Angular code manually
  • We have to place all the built files into a separate folder

3. Packaging With Gulp

In the above sections, we have seen manual steps and these steps have to be eliminated. We can achieve complete automation with the gulp. All the following steps can be made automated with the gulp.

  • Clean the directory if exists
  • Create a directory if not exists to put all the production build
  • Build Angular code with ng build
  • Place the Angular code into production directory
  • Build the server code with the webpack
  • Place the server code into production directory
  • Finally, zip all the code.

Let’s install all the required gulp packages to accomplish the above points.

// install gulp globally
npm install gulp -g
// install as dev dependency
npm install gulp gulp-zip fancy-log del webpack-stream --save-dev
// gulp              - core library
// gulp-zip          - zipping the code
// fancy-log         - logging
// del               - deleting files/folders
// webpack-stream    - Build with webpack

when you run the command gulp it looks for the gulpfile.js file and executes all the tasks mentioned in that file. We can execute these tasks one by one or in parallel with the help of these modules series, parallel. Here is the file gulpfile.js.

const { src, dest, series, parallel } = require('gulp');
const del = require('del');
const fs   = require('fs');
const zip = require('gulp-zip');
const log = require('fancy-log');
const webpack_stream = require('webpack-stream');
const webpack_config = require('./webpack.config.js');
var exec = require('child_process').exec;

const paths = {
  prod_build: 'prod-build',
  server_file_name: 'server.bundle.js',
  angular_src: 'my-app/dist/**/*',
  angular_dist: 'prod-build/my-app/dist',
  zipped_file_name: 'angular-nodejs.zip'
};

function clean()  {
  log('removing the old files in the directory')
  return del('prod-build/**', {force:true});
}

function createProdBuildFolder() {

  const dir = paths.prod_build;
  log(`Creating the folder if not exist  ${dir}`)
  if(!fs.existsSync(dir)) {
    fs.mkdirSync(dir);
    log('?  folder created:', dir);
  }

  return Promise.resolve('the value is ignored');
}

function buildAngularCodeTask(cb) {
  log('building Angular code into the directory')
  return exec('cd my-app && npm run build', function (err, stdout, stderr) {
    log(stdout);
    log(stderr);
    cb(err);
  })
}

function copyAngularCodeTask() {
  log('copying Angular code into the directory')
  return src(`${paths.angular_src}`)
        .pipe(dest(`${paths.angular_dist}`));
}

function copyNodeJSCodeTask() {
  log('building and copying server code into the directory')
  return webpack_stream(webpack_config)
        .pipe(dest(`${paths.prod_build}`))
}

function zippingTask() {
  log('zipping the code ')
  return src(`${paths.prod_build}/**`)
      .pipe(zip(`${paths.zipped_file_name}`))
      .pipe(dest(`${paths.prod_build}`))
}

exports.default = series(
  clean,
  createProdBuildFolder,
  buildAngularCodeTask,
  parallel(copyAngularCodeTask, copyNodeJSCodeTask),
  zippingTask
);

You can actually see some tasks are run one by one and others are in parallel. For example, copying Angular code and building server code (line 67) can be run in parallel because there is no dependency between these. With the gulpfile.js in place, all you need to do is issue this command gulp .

Image for post
building with gulp

4. With Docker

We have seen different implementations so far. All these implementations include putting all the related files together and package it. We used different tools and bundlers to do that. But with Docker, we place all the files in the Docker file system and create a Docker image out of it.

Here is the complete post of how we can package with Docker: How to Dockerize Angular App With NodeJS Backend

Deploying on AWS Elastic Beanstalk

Packing your application is done now it’s time to deploy that on the servers. You can deploy this package on different platforms or server architectures but, covering all those is out of scope for this post. Let us see one example of deployment of this application. Just follow the below post if you want to learn how to deploy this packaged app on AWS Elastic Beanstalk:

AWS — How to Deploy Angular With NodeJS App On Elastic Beanstalk

Summary

  • In traditional architectures, there are so many ways we can package and ship the Angular app to production.
  • If you are new to the Angular app with nodejs backend, please follow this link to get familiar with it.
  • With the manual implementation, we have to build the Angular code, place the appropriate file and zipping the code manually.
  • We can automate all these tasks with the help of gulp.
  • Angular CLI uses a webpack internally to build the Angular code. We can use the same with the NodeJS code as well. In this way, we can skip installing all the dependencies.
  • Docker is another way to package your application but you need to run those Docker images on some container platforms such as Docker, EKS, ECS, etc.
  • Always use multi-stage builds while building your Docker images so that you can avoid unnecessary files packaged into your build.
  • Always automate the tasks with some kind of tools such as gulp or grunt.
  • Elastic Beanstalk from AWS is an easier and quicker way to deploy your packaged app and test it out.

Conclusion

Always automate packaging your app. In that way, you can save lots of time and be more productive.

reference:

https://medium.com/

By Shabazz

Software Engineer, MCSD, Web developer & Angular specialist

Leave a Reply

Your email address will not be published. Required fields are marked *