In the following post I will show an example where I use Bazel to build an Angular application and a nodejs api.

The application used for this demo is a modified version of Alex Eagle’s Bazel demo.

You can find the modified version here.

The application consists of two parts: An Angular application and a node express api.

Angular Application

I modified the original Angular application to make an http request to fetch a headline from the api.

The main component can be found below:

@Component({ selector: 'hello-world-app', template: ` <h1>{{headline | async}}</h1> <div>{{name}}</div> <input type="text" [value]="name" (input)="name = $"/> `, styleUrls: ['./hello-world-styles.css'] }) export class HelloWorldComponent implements OnInit { name = "Hello"; headline: Observable<string>; constructor(private http: Http) {} ngOnInit() { this.headline = this.http.get('http://localhost:9000/hello-world') .map(res => res.json()); } }

The application and Bazel build process is otherwise unchanged from the original setup.


The api is super simple as seen below:

import * as express from 'express'; import {HelloWorldService} from './hello-world.service'; const app = express(); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); const helloWorldService = new HelloWorldService(); app.get('/hello-world', (req, res) => res.json(helloWorldService.getMessage())) app.listen(9000, () => console.log('Example app listening on port 9000!'))

The api is written in Typescript.

Transpiling Typescript to JavaScript in Bazel can be done by adding the ts_library Bazel rule.

Next I am using the nodejs_binary rule to run the api after it’s transpiled.

The full BUILD.bazel file can be found below:

load("@build_bazel_rules_nodejs//:defs.bzl", "rollup_bundle", "nodejs_binary") load("@build_bazel_rules_typescript//:defs.bzl", "ts_library") ts_library( name = "ts_server", srcs = glob(["*.ts"]), ) nodejs_binary( name = "api", data = ["//src/api:ts_server"], entry_point = "../server.js", )

I now have two Bazel rules to build and run.

In order to run both at the same time I trigger parallel Bazel run commands by using concurrently.

I use an npm script task to wrap the two iBazel commands:

concurrently \"ibazel run //src:devserver\" \"ibazel run //src:api\"

To run the project all you need is npm run start.

When you execute the command, both apps will start.

Since I am using iBazel the applications will refresh whenever any of the source files are modified.