A powerful Angular library that enables version-aware component rendering for seamless feature management based on application versions. Perfect for progressive feature rollouts, maintaining backward compatibility, and A/B testing.
- 🚀 Version-Aware Components - Render different components based on your application's version
- 🧠Smart Feature Selection - Automatically selects the most appropriate component for the current version
- ⚙️ Multiple Version Strategies - Support for semantic versioning (1.1.0) and date-based versioning
- 🎯 Declarative API - Simple decorator-based approach for clear and maintainable code
- đź’‰ Dependency Injection Integration - Fully compatible with Angular's DI system
- 🔄 Dynamic Component Loading - Efficiently load and render the right component at runtime
- 🔍 Transparent Caching - Optimized performance through internal caching mechanisms
- 📦 Standalone Component Support - Fully compatible with Angular's standalone components
npm install ngx-version-view --save
First, provide the version management service with your app's version:
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideVersionView, VersionStrategyType } from 'ngx-version-view';
import { BehaviorSubject } from 'rxjs';
// Create a version stream - in a real app, this might come from an API
const versionStream = new BehaviorSubject<string>('1.0.0');
export const appConfig: ApplicationConfig = {
providers: [
// ... other providers
provideVersionView({
type: VersionStrategyType.SEMANTIC, // or VersionStrategyType.DATE
version: versionStream,
}),
],
};
For simpler cases, you can use the shorthand version:
provideVersionViewSimple(versionStream, true); // true = use semantic versioning
Create components for different versions and decorate them with version metadata:
// basic-feature.component.ts
import { Component, Input } from '@angular/core';
import { VersionFeature } from 'ngx-version-view';
@Component({
selector: 'app-basic-feature',
standalone: true,
template: `<div class="basic">Basic Feature UI - v1.0</div>`,
})
@VersionFeature({
key: 'userDashboard',
minVersion: '1.0.0',
maxVersion: '2.0.0',
})
export class BasicFeatureComponent {
@Input() userId: string = '';
}
// advanced-feature.component.ts
import { Component, Input } from '@angular/core';
import { VersionFeature } from 'ngx-version-view';
@Component({
selector: 'app-advanced-feature',
standalone: true,
template: `<div class="advanced">Advanced Feature UI - v2.0+</div>`,
})
@VersionFeature({
key: 'userDashboard',
minVersion: '2.0.0',
})
export class AdvancedFeatureComponent {
@Input() userId: string = '';
}
Register your version-specific components with the service:
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { ViewService } from 'ngx-version-view';
import { BasicFeatureComponent } from './basic-feature.component';
import { AdvancedFeatureComponent } from './advanced-feature.component';
@Component({
// ...
})
export class AppComponent implements OnInit {
constructor(private viewService: ViewService) {}
ngOnInit() {
// Register features manually (alternative to using decorators)
this.viewService.registerFeatures([
{
key: 'userDashboard',
minVersion: '1.0.0',
maxVersion: '2.0.0',
component: BasicFeatureComponent,
},
{
key: 'userDashboard',
minVersion: '2.0.0',
component: AdvancedFeatureComponent,
},
]);
}
}
<ngx-view-component
key="userDashboard"
[data]="{ userId: currentUser.id }"
>
<!-- Fallback content if no matching version is found -->
<p>This feature is not available in your current version</p>
</ngx-view-component>
For applications that use dates as version numbers:
import { provideVersionView, VersionStrategyType, DateFormat } from 'ngx-version-view';
import { BehaviorSubject } from 'rxjs';
const versionStream = new BehaviorSubject<string>('2023-10-15');
provideVersionView({
type: VersionStrategyType.DATE,
dateFormat: DateFormat.YYYY_MM_DD_DASH, // Or other supported formats
version: versionStream,
});
The library supports multiple date formats:
export enum DateFormat {
DD_MM_YYYY_DOT = 'dd.MM.yyyy', // 15.10.2023
MM_DD_YYYY_DOT = 'MM.dd.yyyy', // 10.15.2023
YYYY_MM_DD_DOT = 'yyyy.MM.dd', // 2023.10.15
YYYY_MM_DD_DASH = 'yyyy-MM-dd', // 2023-10-15
MM_DD_YYYY_DASH = 'MM-dd-yyyy', // 10-15-2023
DD_MM_YYYY_DASH = 'dd-MM-yyyy', // 15-10-2023
}
You can also get components programmatically:
import { Component, OnInit } from '@angular/core';
import { ViewService } from 'ngx-version-view';
@Component({
selector: 'app-dynamic-wrapper',
template: `
<ng-container *ngComponentOutlet="featureComponent; inputs: inputData"></ng-container>
`,
})
export class DynamicWrapperComponent implements OnInit {
featureComponent: any;
inputData = { userId: 'user-123' };
constructor(private viewService: ViewService) {}
ngOnInit() {
this.featureComponent = this.viewService.getFeatureComponent('userDashboard');
}
}
Access the current application version anywhere in your app:
import { Component } from '@angular/core';
import { ViewService } from 'ngx-version-view';
@Component({
selector: 'app-version-display',
template: `<div>Running on version: {{ currentVersion() }}</div>`,
})
export class VersionDisplayComponent {
currentVersion = this.viewService.currentVersion;
constructor(private viewService: ViewService) {}
}
You can dynamically update the application version:
import { Component } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Component({
// ...
})
export class AdminComponent {
constructor(@Inject(VERSION_STREAM) private versionStream: BehaviorSubject<string>) {}
updateAppVersion(newVersion: string) {
this.versionStream.next(newVersion);
// All version-aware components will automatically update
}
}
Component | Description |
---|---|
VersionFeatureComponent |
The component that renders version-appropriate UI based on feature key |
Service | Description |
---|---|
ViewService |
Core service for registering and retrieving version-based components |
Decorator | Description |
---|---|
@VersionFeature() |
Marks a component with version metadata |
Function | Description |
---|---|
provideVersionView() |
Configures the library with full options |
provideVersionViewSimple() |
Simplified configuration function |
Interface | Description |
---|---|
VersionConfig |
Configuration options for version strategies |
FeatureConfig |
Configuration for a version-specific feature |
VersionFeatureOptions |
Options for the @VersionFeature decorator |
VersionStrategy |
Interface for implementing custom version comparison strategies |
Strategy | Description |
---|---|
SemanticVersionStrategy |
Handles semantic versioning (e.g., 1.2.3) |
DateVersionStrategy |
Handles date-based versioning with configurable formats |
@VersionFeature({
key: 'paymentMethod',
minVersion: '1.0.0',
maxVersion: '1.5.0',
})
export class BasicPaymentComponent {}
@VersionFeature({
key: 'paymentMethod',
minVersion: '1.5.0',
maxVersion: '2.0.0',
})
export class EnhancedPaymentComponent {}
@VersionFeature({
key: 'paymentMethod',
minVersion: '2.0.0',
})
export class AdvancedPaymentComponent {}
// Enable a feature only in specific versions
@VersionFeature({
key: 'experimentalFeature',
minVersion: '1.5.0',
maxVersion: '1.6.0', // Only available in this version range as a test
})
export class ExperimentalFeatureComponent {}
// Variant A (for 50% of version 2.x users)
@VersionFeature({
key: 'checkoutFlow',
minVersion: '2.0.0',
maxVersion: '3.0.0',
})
export class CheckoutVariantAComponent {}
// Variant B (for 50% of version 2.x users)
@VersionFeature({
key: 'checkoutFlow',
minVersion: '2.0.0',
maxVersion: '3.0.0',
})
export class CheckoutVariantBComponent {}
// In your service that manages which variant to show
constructor(private viewService: ViewService) {
const variant = Math.random() > 0.5 ? CheckoutVariantAComponent : CheckoutVariantBComponent;
this.viewService.registerFeature({
key: 'checkoutFlow',
minVersion: '2.0.0',
maxVersion: '3.0.0',
component: variant
});
}
- Organize by Feature Keys: Use consistent feature keys across your application
- Version Boundaries: Define clear min/max version boundaries
- Fallback Content: Always provide fallback content in the
ngx-view-component
- Testing: Test each version-specific component independently
- Documentation: Document version compatibility for each feature
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'feat: add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Kiet Le - zenkiet