Hey, y’all — DeepSource JavaScript analyzer now supports AngularJS ( v1.* ) and Angular (latest) frameworks.
Angular
JS-0571: Invalid lifecycle method in class
Some lifecycle methods can only be used in certain class types.
The not preferred way:
@Injectable()
class Test {
ngAfterContentChecked() { console.log('AfterContentChecked'); }
}
The preferred way:
@Injectable()
class Test {
ngOnDestroy() { console.log('OnDestroy'); }
}
JS-0572: @Attribute
decorator should not be used
It is a good practice to specify this attribute name directly by naming correctly the corresponding parameter, in order to avoid duplicates code.
The not preferred way:
class Test {
constructor(@Attribute() foo: any) {}
}
The preferred way:
class Test {
constructor(@Optional() foo: any, @Optional() bar: any) {}
}
JS-0573: Prevent explicit calls to lifecycle methods
Explicit calls to lifecycle methods could be confusing. It is Angular’s responsibility to invoke them.
The not preferred way:
@Pipe({
name: 'test'
})
class Test {
test() {
this.ngOnInit();
}
}
The preferred way:
@Component({
selector: 'test'
})
class Test {
test() {
super.ngAfterContentChecked();
}
}
JS-0575: Found impure pipes
Impure pipes should be avoided because they are invoked on each change-detection cycle. Impure pipes can’t leverage caching, instance re-use and simple tests.
The not preferred way:
@Pipe({
name: 'test',
pure: false
})
class Test {}
The preferred way:
@Pipe({
name: 'test',
pure: true
})
class Test {}
AngularJS
JS-0516: Disallow use of internal angular properties prefixed with $$
All scope’s properties/methods starting with $$
are used internally by AngularJS. You should not use them directly. Exception can be allowed with this option: {allow:['$$watchers']}
The not-preferred way:
$scope.$$watchers.forEach(function (watcher) {
// ...
});
The preferred way:
$scope.$apply();
JS-0518: Prefer the use of controllerAs
in routes or states
The not-preferred way:
$routeProvider.when('/myroute', {
controller: 'MyController'
}) // error: Route "/myroute" should use controllerAs syntax
The preferred way:
$routeProvider.when('/myroute', {
controller: 'MyController',
controllerAs: 'vm'
});
JS-0520: Assignments to $scope
in controllers
The not-preferred way:
// error: You should not set properties on $scope in controllers.
// Use controllerAs syntax and add data to "this"
angular.module("myModule").controller("SomeController", function($scope) {
$scope.value = 42;
});
The preferred way:
angular.module("myModule").controller("SomeController", function($scope) {
// this for values
this.value = 42;
// $scope is fine for watchers
$scope.$watch(angular.bind(this, function () {
return this.value
}), function () {
// ...
});
});
JS-0526: Use of inline templates is discouraged
The not-preferred way:
angular.module('myModule').directive('helloWorld', function () {
return {
template: '<div>Hello World! <button>Say hello!</button></div>'
};
}); // error: Inline template is too complex. Use an external template instead
The preferred way:
angular.module('myModule').directive('helloWorld', function () {
return {
templateUrl: 'template/helloWorld.html'
};
});
How to enable the plugins?
To enable these plugins on your repository, add the following snippet to your .deepsource.toml
:
version = 1
[[analyzers]]
name = "javascript"
enabled = true
[analyzers.meta]
plugins = ["angularjs"]
and
version = 1
[[analyzers]]
name = "javascript"
enabled = true
[analyzers.meta]
plugins = ["angular"]