Day11 Challenge: Set Up and Optimize an Angular Project Using Bazel
Objective:
Your goal is to set up a new Angular project using Bazel as the build tool and optimize its build performance for large-scale applications. You’ll configure Bazel, structure the project correctly, and demonstrate performance improvements by running builds in development and production modes.
Step 1: Set Up Bazel in an Angular Project
Create a new Angular project:
Start by creating a new Angular project using Angular CLI if you don’t have one already. If you already have an Angular project, skip to Step 2.ng new bazel-angular-challenge --routing --style=scss cd bazel-angular-challenge
Install Bazel:
Install the required Bazel dependencies and tools to integrate Bazel into your Angular project.Add Bazel to your Angular project:
ng add @angular/bazel
Install necessary Bazel dependencies:
yarn add @bazel/bazel @angular/bazel
This will generate Bazel build files and configurations like
BUILD.bazel
,.bazelrc
, andangular.json
.
Step 2: Create and Configure Bazel Files
Configure
BUILD.bazel
files:
In Bazel, you useBUILD.bazel
files to define build targets. Here, you’ll configure Bazel to build Angular applications.In your project root, open or create a
BUILD.bazel
file.Add configurations for building Angular apps:
load("@npm//@angular/bazel", "ng_module", "ng_package") ng_module( name = "app", srcs = glob(["src/**/*.ts"]), deps = [ "@npm//@angular/core", "@npm//@angular/common", "@npm//@angular/router", ], ) ng_package( name = "app_package", srcs = glob(["src/**/*"]), deps = [":app"], )
This configuration ensures that Bazel can build the Angular application (
ng_module
) and package it (ng_package
).
Bazel Build Configurations:
You’ll also need to modify or add to your.bazelrc
file to customize build parameters for Bazel’s build strategy.Example
.bazelrc
configurations:build --experimental_action_listener=@bazel_tools//tools/jdk:default_java_toolchain build --output_groups=debug build --experimental_convenience_symlinks=ignore
Step 3: Integrating Angular’s Development Server
Set up an Angular development server using Bazel:
In a typical Angular project, you might useng serve
. With Bazel, the process is slightly different.Install the Angular development server dependency for Bazel:
yarn add @angular/bazel-build-angular
Update your
angular.json
to add a build target for Bazel.Example configuration:
"projects": { "bazel-angular-challenge": { "architect": { "build": { "builder": "@angular/bazel:browser", "options": { "outputPath": "dist/", "sourceMap": true } }, "serve": { "builder": "@angular/bazel:devserver", "options": { "browserTarget": "bazel-angular-challenge:build" } } } } }
Run the Angular project:
Now you should be able to build and serve the application using Bazel.To build the application:
bazel build //src:app
To serve the application:
bazel run //src:devserver
This command starts a development server for the Angular app using Bazel.
Step 4: Optimize Angular Build Performance with Bazel
Optimize Build with Incremental Builds:
Bazel’s main selling point is its caching and incremental builds. To fully take advantage of this, start building parts of your app incrementally:Bazel builds only what has changed since the last build, which can speed up the process, especially with large applications.
Test incremental builds by changing files and running the build command multiple times. You should see faster builds for unchanged parts of the application.
Using
--experimental_aggregate_files
:
Bazel offers flags to optimize file aggregations during builds. By enabling--experimental_aggregate_files
, you can speed up file processing in larger Angular applications.Example:
bazel build --experimental_aggregate_files //src:app
Parallel Builds and Caching:
Use the
--jobs
flag to run Bazel with parallel jobs for faster builds:bazel build --jobs=4 //src:app
You can also enable remote caching for Bazel to cache builds across different machines, speeding up builds for large teams or CI/CD pipelines.
Step 5: Bonus - Using Bazel with Angular Libraries
Set up Angular Libraries with Bazel:
You can also use Bazel to build Angular libraries for a modular and scalable architecture.Create a
BUILD.bazel
file for the library:load("@npm//@angular/bazel", "ng_module") ng_module( name = "shared-lib", srcs = glob(["src/lib/**/*.ts"]), deps = [ "@npm//@angular/core", "@npm//@angular/common", ], )
Import the library into your main Angular app using Bazel’s module system, ensuring that it is properly built and optimized.
Step 6: Deploying the Angular App with Bazel
Configure Deployment for Production:
Use Bazel’sng_build
target for production optimization. You can set up a production build by tweaking theangular.json
and.bazelrc
to enable optimizations such as minification and tree shaking.Example:
bazel build --config=production //src:app
This builds a production-ready application using the best optimizations available in Bazel and Angular.
Challenge Results & Expected Outcomes:
Bazel Integration: You’ve successfully set up an Angular project using Bazel and configured it for building and serving Angular applications.
Performance Gains: You’ve optimized the Angular build using Bazel’s caching, parallel execution, and incremental build features, leading to faster build times.
Modularization: You’ve created Angular libraries with Bazel, enabling more maintainable and scalable applications.
Production Optimization: You’ve configured production builds with Bazel for optimized and efficient output.
Bonus Challenge: CI/CD Integration with Bazel
- Integrate Bazel with your continuous integration pipeline (e.g., GitHub Actions, Jenkins, or CircleCI). Use Bazel’s incremental builds and caching features in your CI/CD setup to speed up build and test times for large Angular projects.
This challenge gives you a comprehensive understanding of Bazel’s integration with Angular and how you can leverage it to optimize your development workflow, build performance, and project scalability.