Angular Application Version Check with Nx Executor
"Versioning is like a check-up for your app — if you don’t stay current, you risk delivering outdated content to users.”
Ensuring that users of your Angular application have the latest features, bug fixes, and security patches is critical for a smooth user experience. This post will explain a version-checking solution for Angular applications within an Nx workspace, focusing on keeping the app synchronized with the latest version hosted on the server. We’ll cover each layer of the C4 Model, from Context down to Sequence, to illustrate the technical design. At the end, we’ll discuss how Service Workers and Server-Side Rendering (SSR) could further strengthen this solution.
There are (2) aspects to consider. The build process will need to retrieve and use a specific version for the comparison. The runtime Angular application will need to be able to retrieve the local version information and compare it to what is currently deployed (i.e., production).
Build System
Build Context View
In the Context View, we look at the big picture — who interacts with the system and the primary entities involved. This diagram shows the key actors and their relationships in the version-checking process.In this view, we identify the external systems and users that interact with the version-checking process, providing a high-level overview of the system’s environment and its boundaries.
Key Actors:
- User: The person accessing the Angular application via a browser. They expect the application to be up-to-date and functional.
- Angular Application: The client-side application running in the user’s browser. It needs to check for updates to ensure it has the latest version.
- Cloud Endpoint: The server environment where the application and version information (
version.json) are hosted. - Application Host: Represents the current application instance in production, exposed via the Cloud Endpoint.
Summary of Interactions:
- The User interacts with the Angular Application through their browser.
- The Angular Application interacts with the Cloud Endpoint to retrieve the latest version information, ensuring it has the most recent version of
version.json.
Build Container View
The Container View breaks down the main pieces of the system and how they interact to ensure version consistency. It includes the Angular application, its services, and the versioning files hosted on the cloud.
Main Containers:
- Angular Application: The front-end application that the user accesses.
- Build Script/Workflow: Handles the build process and includes the version-checking logic.
- Distribution Output: The final build output containing application assets, including the
version.jsonfile. - Cloud Endpoint: Hosts the application and the
version.jsonfile, providing an endpoint for the Angular application to check the current version.
Process Overview
- During each build, the Build Script/Workflow generates and packages a
version.jsonfile based on the version inpackage.json. - The
version.jsonfile is added to the Distribution Output and deployed to the Cloud Endpoint. - The Angular Application can request
version.jsonfrom the Cloud Endpoint to validate its version against the server’s latest version.
Build Component View
The Component View drills down into the specific services and logic within the Angular application that handle version checking. It describes how each piece contributes to determining if the app in the user’s browser is the latest version.
Core Components:
- Configuration Service: Retrieves and stores configuration settings, including the current application version.
- Version Check Service: Manages the version-checking process by periodically or on-demand fetching
version.jsonfrom the Cloud Endpoint. It compares the server version to the locally running version. - Notification System: Notifies the user if the application is outdated and suggests reloading to update to the latest version.
Component Interactions:
- The Angular Application initializes the Configuration Service and the Version Check Service on startup.
- The Version Check Service can be configured to perform scheduled checks or triggered on-demand by the user. It retrieves
version.jsonfrom the Cloud Endpoint and compares it to the current version stored by the Configuration Service. - If a version mismatch is detected, the Notification System alerts the user to reload the application.
Build Sequence Diagram
The Sequence Diagram illustrates the step-by-step interactions among the components to manage version checking. It shows how the Angular application, through its services, checks for updates and notifies the user as needed.
- Build-Time Version Determination:
- The Build Script triggers the versioning process using an Nx Executor.
- The Nx Version Executor retrieves the version from
package.jsonand updatesversion.jsonin the application assets. - The application is built, and
version.jsonis included in the Distribution Output, which is then deployed to the Cloud Endpoint.
2. Run-Time Version Check:
- The Version Check Service in the Angular application fetches the
version.jsonfile from the Cloud Endpoint. - It compares the local and server versions. If a mismatch is detected, the user is notified and prompted to reload the app.
Nx Executor for Version Management
To update the executor to create a JSON file in the target project’s assets folder and provide a sample configuration in a project.json file, follow these steps:
Update the Executor to Create a JSON File
- Modify the executor: Update your executor code to write the version information to a JSON file in the target project’s
assetsdirectory.
import { ExecutorContext } from '@nrwl/devkit';
import * as fs from 'fs';
import * as path from 'path';
interface VersionCheckOptions {
project: string;
}
export default async function runExecutor(
options: VersionCheckOptions,
context: ExecutorContext
) {
try {
const workspaceRoot = context.root;
const projectRoot = context.workspace.projects[options.project].root;
const packageJsonPath = path.join(workspaceRoot, 'package.json');
const assetsFolder = path.join(workspaceRoot, projectRoot, 'assets');
if (!fs.existsSync(assetsFolder)) {
fs.mkdirSync(assetsFolder, { recursive: true });
}
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
const versionInfo = { version: packageJson.version };
const outputFilePath = path.join(assetsFolder, 'version-info.json');
fs.writeFileSync(outputFilePath, JSON.stringify(versionInfo, null, 2));
console.log(`Version info written to ${outputFilePath}`);
return { success: true };
} catch (error) {
console.error('Failed to write version info:', error);
return { success: false };
}
}Configure the Executor in executors.json
Ensure your executors.json is correctly set up:
{
"executors": {
"version-check": {
"implementation": "./src/executors/version-check/executor",
"schema": "./src/executors/version-check/schema.json",
"description": "Create a JSON file with version information in the project's assets folder"
}
}
}Create the Executor Schema
Create a schema.json file (at libs/your-plugin-name/src/executors/version-check/) to define the options your executor will receive:
{
"type": "object",
"properties": {
"project": {
"type": "string",
"description": "The name of the project where the JSON file will be created."
}
},
"required": ["project"]
}Sample Configuration in project.json
Here’s how you can configure a target to use this executor in a project.json file:
{
"name": "your-project-name",
"root": "apps/your-project-name",
"sourceRoot": "apps/your-project-name/src",
"projectType": "application",
"targets": {
"check-version": {
"executor": "your-plugin-name:version-check",
"options": {
"project": "your-project-name"
}
}
}
}Run the Executor
You can now execute this target in your Nx workspace or in an automation script (e.g., CI/CD pipeline) to update the version information.
npx nx run your-project-name:check-versionThis setup will create a version-info.json inside the assets folder of the specified project, containing the version information from the root package.json.
System Architecture Overview
Managing application versioning is essential to provide users with the most up-to-date content. This information will guide you through a version-checking system for Angular applications in an Nx workspace, designed to keep the application in sync with the latest version on the server. We’ll explore each layer of the C4 Model: Context, Container, Component, and Sequence, and discuss future improvements with Service Workers and Server-Side Rendering (SSR).
System Context View
The Context View provides an overview of the system and its key interactions with users and external systems. Here’s the big picture of how version management works in our setup.
Key Actors:
- User: The end-user accessing the Angular application via their browser.
- Angular Application: A single-page web application that runs in the user’s browser.
- Version Check System: Responsible for determining if the application version in the browser matches the version hosted on the server.
- Application Host: The server hosting the current version of the application, including version information in
version.json.
Summary of Interactions:
- The User interacts with the Angular Application, which checks with the Application Host to verify that the application version is up to date.
- The Version Check System retrieves the version from a locally stored
version.jsonfile and compares it with the hosted version to ensure consistency.
System Container View
In the Container View, we break down the main parts of the version-checking system and how they communicate with each other. This level outlines the key services involved in version management.
Main Containers:
- Angular Application: The application itself, which runs in the browser and initiates the version check.
- Configuration Service: A service within the Angular app responsible for managing configuration settings, including version details.
- Version Check Service: Checks the application’s version status against the hosted version on a scheduled or on-demand basis.
- Version Information: Stores the current version information of the application as a JSON asset (
version.json). - Cloud Endpoint: The server where the Angular application and the version information are hosted, making them accessible to the Version Check System.
Process Overview:
- The Angular Application interacts with the Configuration Service to retrieve initial version details and periodically calls the Version Check Service to fetch the latest version information from the Cloud Endpoint.
- The Version Information file, located on the Cloud Endpoint, provides the reference version. If a mismatch is detected, the system can prompt the user to reload.
System Component View
The Component View provides a deeper look at the specific services and components that drive version checking within the Angular application. This view focuses on the internal structure and logic of the version-checking process.
Core Components:
- Angular Application: Initializes the Configuration Service and Version Check Service, which are essential to managing and verifying the version.
- Configuration Service: Sets and retrieves configuration settings, storing the current version of the application.
- Version Check Service: A dedicated service for checking the application version. It includes:
- Timer/Schedule: Manages when version checks occur, either at fixed intervals or upon user request.
- Notification System: Notifies the user if a version update is available and prompts a reload.
- Logging: Tracks version check activity for diagnostics and troubleshooting.
Component Interactions:
- The Angular Application initializes the Configuration Service and the Version Check Service when it starts up.
- The Version Check Service can be triggered on a schedule or on-demand to fetch the
version.jsonfrom the Cloud Endpoint. If the version in theversion.jsonfile on the server differs from the local version, the Notification System alerts the user to reload.
System Sequence Diagram
The Sequence Diagram shows the step-by-step interactions of the version-checking system components, from initialization to version verification.
- Application Initialization:
- The Angular Application loads configuration settings through the Configuration Service, which includes the current version information stored locally.
2. Scheduled or On-Demand Version Check:
- The Version Check Service is initialized and retrieves current version settings.
- The service checks the hosted version information file (
version.json) at the Cloud Endpoint to see if a newer version is available.
3. Version Comparison and Notification:
- If a version mismatch is detected, the Version Check Service triggers the Notification System to prompt the user for a reload.
- Depending on the check (scheduled or on-demand), the system will continue to monitor for updates and notify users as needed.
Merits of the Solution
This version-checking solution offers several key benefits:
- Automation: Custom Nx executors automate the retrieval and updating of version information, reducing human error and ensuring consistency.
- User Notification: By regularly checking for updates, the application can notify users if a new version is available, enhancing the user experience.
- Configurable Checks: The solution supports both scheduled and on-demand checks, allowing flexibility in how frequently the application verifies its version.
- Simple Deployment: The use of
version.jsonis a lightweight approach that integrates well with standard web hosting, requiring minimal server-side configuration.
Proposed Future Path: Service Workers and SSR
While the current setup is effective, it has limitations. Service Workers and Server-Side Rendering (SSR) could enhance this solution’s reliability and user experience.
Service Workers
Service Workers run in the background and can intercept network requests, making them ideal for handling caching and background updates.
Get Matt Vaughn’s stories in your inbox
Join Medium for free to get updates from this writer.
Advantages:
- Automatic Background Updates: Service Workers can detect updates without user interaction, fetching the latest assets in the background.
- Enhanced Caching: Service Workers enable more efficient caching and offline capabilities, improving load times and availability.
- Smooth User Experience: Service Workers can reload the app seamlessly after an update, creating a frictionless experience for users.
Implementation:
- Angular has built-in support for Service Workers through
@angular/service-worker. Configuring a Service Worker to cache assets and periodically checkversion.jsoncan automate update handling.
Server-Side Rendering (SSR)
SSR renders the initial page on the server, reducing time-to-interactive and ensuring users receive the latest version upon first load.
Advantages:
- Improved Performance: SSR decreases load time by delivering pre-rendered HTML, especially beneficial for new users or slow network connections.
- SEO Boost: Pre-rendered pages improve visibility and indexing by search engines.
- Fresh Content on First Load: SSR ensures that users always get the latest version on the first load, preventing cached content issues.
Implementation
- Angular Universal can be used to set up SSR for an Angular application.
- Combining SSR with Service Workers offers both fast initial loads and background updates.
Conclusion
This version-checking system offers a robust foundation to ensure users always have the latest version of your Angular application. By leveraging a clear separation of concerns with the Configuration Service, Version Check Service, and Notification System, it provides an effective and maintainable solution. The current setup supports both build-time and run-time checks, maximizing flexibility. Looking ahead, integrating Service Workers and Server-Side Rendering (SSR) can further enhance the system, offering smoother, automated updates, greater reliability, and improved performance.
These advancements pave the way for an industrial-strength version management approach, minimizing outdated application issues and optimizing user experience.










