Red Green Repeat Adventures of a Spec Driven Junkie

Setting up Angular in Virtualbox

I am on a project that uses angular 2/4/5 as its front-end. Setting up a Virtualbox environment for this has been a bit trickier than I expected so here is the way to setup angular in Virtualbox for development.

By the end of this article, you will:

  • have scripts to build a Virtualbox for angular development
  • be able to run the application and run the automated tests
  • be able to run the automated tests in a headless manner

Motivation

My main reasons for setting up angular in Virtualbox:

  • sandbox development so it’s easily replicable on other systems
  • avoid changing anything of my host system
  • have the development environment match the production environment

There are other reasons as well, but these are the most pertinent for me.

Requirements

  • a computer
  • Virtualbox / vagrant installed
  • an internet connection (system build may require >500MB)

Reference Files

Configuration files discussed in this article can be found here:

https://github.com/a-leung/installing-angular-in-virtualbox

Virtualbox Configuration

As angular is a single page application framework, having direct access to ports the Virtualbox is essential for a single page app. This allows loading of the app to the browser and also testing of the app.

Mapping Ports

Virtualbox can map ports to local ports and are accesible just by opening: localhost:port from a browser.

The configuration in the Vagrantfile is:

config.vm.network "forwarded_port", guest: <guest_port_number, host: <host_port_number>

The guest port number is the port the application uses inside the Virtualbox. The host port number is the port number you can access the application using format: localhost:host_port_number.

Application Port

The default port used by angular for serving the app is 4200, so I will map that to the same on the host port:

config.vm.network "forwarded_port", guest: 4200, host: 4200

If there is another application using 4200 on the guest system (say another angular app), changing the host port number to 4201 will avoid port conflicts.

Testing Port

The default port used by angular for testing is 9876, so I will map that to the same on the host port:

config.vm.network "forwarded_port", guest: 9876, host: 9876

If there is another application using 9876 on the guest system (say another angular app), changing the host port number to 9877 will avoid port conflicts.

Install Web Browser

This is optional, but I like to have the Virtualbox to also run the tests instead of connecting a browser to the test port.

Installing Chrome on Ubuntu will require about 500MB.

In the Vagrantfile, add this to the shell provisioning section:

wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
echo 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list
apt-get update
apt-get install google-chrome-stable

Installing Angular

There are two ways to install node, npm, and angular/cli: through the shell provisioner, or through an external script.

Either way is fine. The big difference is which system user is installing the programs. With the shell provisioner, the root user is installing, with an external script, it is the vagrant user.

Install as root

nAdd the following lines to the shell provisioner section of the Vagrantfile:

curl -sL https://deb.nodesource.com/setup_8.x | bash -
apt-get update

apt-get install -y nodejs
npm install npm --global

npm install --unsafe-perm -g @angular/cli

This will install node, npm, and angular/cli. The major issue with his is angular/cli may require npm option: --unsafe-perm for the installation to fully succeed.

This thread highlights some of the issue. Most revolve around npm compiling native packages on the system and using the nobody user… which root cannot assume the role. There are errors unless we configure npm to ignore permissions.

The approach also allows all the installation to occur from one file.

Install as Vagrant User

Installing as vagrant user will require using an external file to load. In an external file, include the following contents:

#!/usr/bin/env bash

# nvm install
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash

# load nvm
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

# use nvm to install current node
nvm install node

# newer version of npm
npm install npm

# install angular
npm install -g @angular/cli

# create test project to grab remaining dependencies
ng new test-app

This file takes a slightly different approach:

  • installation of nvm to manage node versioning, which is great for projects with different versions of node.
  • creation of a new test-app at the end of installation. Angular still has dependencies online when creating a new project. This guarantees new projects are creatable offline.

Running project

With the Virtualbox provisioned, this is the normal workflow:

  • logging into the Virtualbox
  • create or find the project
  • serving the project to the browser
  • running the project’s automated tests

Logging in

Connect through ssh into the Virtualbox by opening a terminal and running:

$ vagrant ssh

From here on, all the commands will be from inside the Virtualbox.

Create a new Application:

Create a new project in the shared vagrant folder:

$ cd /vagrant
$ ng new test-app

On the host system, look for a folder named test-app in the same directory as the Vagrantfile. This application is the same application created by angular inside the Virtualbox.

Running the Application

In the Virtualbox, find the application and run it. In this case, the commands create application named: test-app.

$ cd /vagrant
$ cd test-app
$ ng serve --host 0.0.0.0

Open a browser and enter address: localhost:4200 (or the port specified by the host_port_number for guest port 4200.)

Application in
Browser

Normally, running an angular app just requires running: ng serve. In this case, there is a need to set host address to 0.0.0.0 because the angular application is listening to localhost, which won’t accept connections outside of the Virtualbox.

Testing the Application

Run tests with commands:

$ cd /vagrant
$ cd test-app
$ ng test --host 0.0.0.0

Open a browser and enter address: localhost:9876 (or the port specified by the host_port_number for guest port 9876.) Now the browser will run all the tests.

You will see this on the command line:

Testing with
Browser

Opening a browser to localhost:9876, will show:

Browser Testing

Testing the Application Headlessly

I like to run tests headless, which means the tests run without a browser.

To run tests without a browser, install Chrome, and the commands to test headless for the test-app are:

% cd /vagrant
$ cd test-app
$ ng test --browser ChromeHeadless

Now, to run tests, a browser connection is not required. The system is using Chrome in a headless manner to run the tests.

Testing Headless

Conclusion

I have presented a configuration for running angular in Virtualbox. Serving the app, running automated tests, configuring the Virtualbox system.

Having angular in its own environment allows the system to be portable, configured to match production, and avoid messing with the host system configuration.