@aspectjs/common
v0.5.3
Published
Aspectjs - commonly needed factories & utils
Downloads
5,238
Readme
AspectJS
📜 Abstract
Inspired by the AspectJ java framework, AspectJS leverages ES Decorators to bring Aspect Oriented Programming to Javascript and Typescript.
🎉 Demo:
Demo on stackedit.
💡 Why?
ECMAScript Decorators are fantastic: they allow developers to hide boilerplate code behind a simple @
sign, keeping the code clean, easy to read, and easy to write. Widely used in popular projects such as Angular, Nest.js or TypeORM, decorators have one major drawback: they come with their own built-in behavior, making interoperability between tools difficult, and preventing them from being repurposed for other uses.
AspectJS takes a different approach, by introducing two important concepts: Annotations and Aspects.
- An Annotation is essentially an empty decorator that marks a target (class, property, method or parameter) as a candidate for further enhancements.
- Aspects can be selectively enabled to introduce new behaviors into the annotated elements.
const A = function( target: Function) {
// behaviorA
}
const B = function( target: Function) {
// behaviorB
}
@A()
@B()
class MyClass {}
const af = new AnnotationFactory('my.org')
const A = af.create('A');
const B = af.create('B');
@A()
@B()
class MyClass {}
@Aspect()
class AB_Aspect {
// behavior A
// behavior B
}
getWeaver().enable(new AB_Aspect())
🚀 Getting started:
Install the packages
npm i @aspectjs/core @aspectjs/common
Create an annotation:
// toasted.annotation.ts import { AnnotationFactory, AnnotationKind } from '@aspectjs/common'; const ANNOTATION_FACTORY = new AnnotationFactory('demo'); const Toasted = ANNOTATION_FACTORY.create( AnnotationKind.METHOD, 'Toasted', function Toasted() {}, );
Use that annotation on a class, a property, a method or a parameter:
// main.ts class Main { @Toasted() run() { console.log('run'); } }
Declare an aspect triggered by the annotation:
// toasted.aspect.ts import { Around, AroundContext, Aspect, JoinPoint, on } from '@aspectjs/core'; @Aspect() class ToastedAspect { @Around(on.methods.withAnnotations(Toasted)) toast(ctxt: AroundContext, jp: JoinPoint, jpArgs: unknown[]) { const result = jp(...jpArgs); const text = `${ctxt.target.label} completed successfully`; showToast(text); return result; } }
Enable the aspect
// aop.ts import { getWeaver } from '@aspectjs/core'; getWeaver().enable(new ToastedAspect());
🔗 Documentation
For more advanced usage, please read the documentation: https://aspectjs.gitlab.io/.
MIT Licensed