Mastering Angular Environments and Path Aliases with Signals: A Calculator Example
Mastering Angular Environments and Path Aliases with Signals: A Calculator Example In modern Angular development, using environments, path aliases, and Signals properly can elevate your architecture to enterprise-grade clarity and flexibility. In this article, we’ll walk through: ✅ Using Angular’s environment configuration with fileReplacements ✅ Configuring path aliases like @environments ✅ Creating a Signal-based service ✅ Building a working calculator component ✅ Professional Angular 19 standards in practice Step 1: Environment File Setup We define multiple environment files under src/environments/: src/ app/calculator calculator.component.ts environments/ environment.ts environment.development.ts environment.production.ts environment.ts (default reference) export const environment = { production: false, apiUrl: 'http://localhost:4200' }; environment.production.ts export const environment = { production: true, apiUrl: 'https://api.myapp.com' }; Step 2: Configure File Replacements In angular.json, add: "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.development.ts" } ] Step 3: Create a Path Alias @environments Update your tsconfig.json: "baseUrl": ".", "paths": { "@environments/*": ["src/environments/*"] } Now you can import your environment file like a pro: import { environment } from '@environments/environment'; Step 4: Create the Signal-Powered Calculator Service import { Injectable, signal } from '@angular/core'; import { environment } from '@environments/environment'; @Injectable({ providedIn: 'root' }) export class CalculatorService { private result = signal(0); get value() { return this.result; } add(x: number, y: number) { const sum = x + y; this.log(`Adding: ${x} + ${y} = ${sum}`); this.result.set(sum); } subtract(x: number, y: number) { const diff = x - y; this.log(`Subtracting: ${x} - ${y} = ${diff}`); this.result.set(diff); } private log(message: string) { if (!environment.production) { console.log(`[DEV LOG] ${message}`); } } } Step 5: Create a Standalone Calculator Component import { Component } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { CalculatorService } from '../calculator.service'; @Component({ imports: [FormsModule], standalone: true, template: `Calculator Add Substract Result: {{ calculator.value() }} ` }) export class CalculatorComponent { x = 0; y = 0; substract() { this.calculator.subtract(this.x, this.y); } add() { this.calculator.add(this.x, this.y); } constructor(public calculator: CalculatorService){} } Summary Feature Purpose environment.ts Control behavior per environment Path aliases Clean imports like @environments signal() Reactive state without subscriptions fileReplacements Seamless dev/prod switching Final Thoughts When combined, Signals + Environments + Path Aliases make Angular feel like an elegant framework again. This pattern isn’t just scalable — it’s a pleasure to maintain. Happy building, and may your configs always compile the right file! ⚡

Mastering Angular Environments and Path Aliases with Signals: A Calculator Example
In modern Angular development, using environments, path aliases, and Signals properly can elevate your architecture to enterprise-grade clarity and flexibility.
In this article, we’ll walk through:
- ✅ Using Angular’s environment configuration with
fileReplacements
- ✅ Configuring path aliases like
@environments
- ✅ Creating a Signal-based service
- ✅ Building a working calculator component
- ✅ Professional Angular 19 standards in practice
Step 1: Environment File Setup
We define multiple environment files under src/environments/
:
src/
app/calculator
calculator.component.ts
environments/
environment.ts
environment.development.ts
environment.production.ts
environment.ts
(default reference)
export const environment = {
production: false,
apiUrl: 'http://localhost:4200'
};
environment.production.ts
export const environment = {
production: true,
apiUrl: 'https://api.myapp.com'
};
Step 2: Configure File Replacements
In angular.json
, add:
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts"
}
]
Step 3: Create a Path Alias @environments
Update your tsconfig.json
:
"baseUrl": ".",
"paths": {
"@environments/*": ["src/environments/*"]
}
Now you can import your environment file like a pro:
import { environment } from '@environments/environment';
Step 4: Create the Signal-Powered Calculator Service
import { Injectable, signal } from '@angular/core';
import { environment } from '@environments/environment';
@Injectable({ providedIn: 'root' })
export class CalculatorService {
private result = signal(0);
get value() {
return this.result;
}
add(x: number, y: number) {
const sum = x + y;
this.log(`Adding: ${x} + ${y} = ${sum}`);
this.result.set(sum);
}
subtract(x: number, y: number) {
const diff = x - y;
this.log(`Subtracting: ${x} - ${y} = ${diff}`);
this.result.set(diff);
}
private log(message: string) {
if (!environment.production) {
console.log(`[DEV LOG] ${message}`);
}
}
}
Step 5: Create a Standalone Calculator Component
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CalculatorService } from '../calculator.service';
@Component({
imports: [FormsModule],
standalone: true,
template: `Calculator
Result: {{ calculator.value() }}
`
})
export class CalculatorComponent {
x = 0;
y = 0;
substract() {
this.calculator.subtract(this.x, this.y);
}
add() {
this.calculator.add(this.x, this.y);
}
constructor(public calculator: CalculatorService){}
}
Summary
Feature | Purpose |
---|---|
environment.ts |
Control behavior per environment |
Path aliases | Clean imports like @environments
|
signal() |
Reactive state without subscriptions |
fileReplacements |
Seamless dev/prod switching |
Final Thoughts
When combined, Signals + Environments + Path Aliases make Angular feel like an elegant framework again. This pattern isn’t just scalable — it’s a pleasure to maintain.
Happy building, and may your configs always compile the right file! ⚡