Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Codelyzer is a static analysis tool for Angular projects that helps developers follow best practices and coding standards. It integrates with TSLint to provide a set of rules specific to Angular applications.
Template Accessibility
Codelyzer can check for accessibility issues in Angular templates, such as ensuring that interactive elements are accessible to screen readers.
<button (click)="doSomething()">Click me</button>
Component Class Style
Codelyzer enforces consistent coding styles in Angular component classes, such as proper use of dependency injection and class member ordering.
class MyComponent { constructor(private myService: MyService) {} }
Template Syntax
Codelyzer checks for correct usage of Angular template syntax, ensuring that structural directives like *ngIf and *ngFor are used properly.
<div *ngIf="isVisible">Content</div>
Lifecycle Hooks
Codelyzer ensures that Angular lifecycle hooks are implemented correctly and follow best practices.
class MyComponent implements OnInit { ngOnInit() { console.log('Initialized'); } }
ESLint plugin for AngularJS applications. It provides a set of rules for AngularJS, similar to how Codelyzer provides rules for Angular. However, it is focused on AngularJS (1.x) rather than Angular (2+).
A set of ESLint rules, configurations, and tools to lint Angular applications. It is similar to Codelyzer but uses ESLint instead of TSLint, which is beneficial as TSLint is deprecated.
TSLint is a static analysis tool for TypeScript code. While it is not specific to Angular, it can be extended with custom rules like those provided by Codelyzer. Note that TSLint is deprecated in favor of ESLint.
A set of tslint rules for static code analysis of Angular TypeScript projects.
You can run the static code analyzer over web apps, NativeScript, Ionic, etc.
Vote for your favorite feature here. For more details about the feature request process see this document
Angular CLI has support for codelyzer. In order to validate your code with CLI and the custom Angular specific rules just use:
ng new codelyzer
ng lint
Note that by default all components are aligned with the style guide so you won't see any errors in the console.
Another project which has out of the box integration with codelyzer is angular-seed. In order to run the linter you should:
# Skip if you've already cloned Angular Seed
git clone https://github.com/mgechev/angular-seed
# Skip if you've already installed all the dependencies of Angular Seed
cd angular-seed && npm i
# Run all the tslint and codelyzer rules
npm run lint
Note that by default all components are aligned with the style guide so you won't see any errors in the console.
You can use the tslint-angular
preset. All you need is:
npm i tslint-angular
After that create a tslint.json
file with the following configuration:
{
"extends": ["tslint-angular"]
}
Run the linter with:
./node_modules/.bin/tslint -c tslint.json
TSLint will now complain that there are rules which require type checking. In order to fix this, use thw -p
config option:
./node_modules/.bin/tslint -p tsconfig.json -c tslint.json
You can easily use codelyzer with your custom setup:
npm i codelyzer tslint @angular/compiler @angular/core
A. Using codelyzer package in PATH
Create the following tslint.json
file like:
{
"extends": ["codelyzer"],
"rules": {
"angular-whitespace": [true, "check-interpolation", "check-semicolon"],
"banana-in-box": true,
"templates-no-negated-async": true,
"directive-selector": [true, "attribute", "sg", "camelCase"],
"component-selector": [true, "element", "sg", "kebab-case"],
"max-inline-declarations": true,
"no-life-cycle-call": true,
"prefer-output-readonly": true,
"no-conflicting-life-cycle-hooks": true,
"enforce-component-selector": true,
"no-queries-parameter": true,
"prefer-inline-decorator": true,
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
"use-view-encapsulation": true,
"no-attribute-parameter-decorator": true,
"no-output-named-after-standard-event": true,
"no-input-rename": true,
"no-output-rename": true,
"no-output-on-prefix": true,
"no-forward-ref": true,
"no-unused-css": true,
"use-life-cycle-interface": true,
"contextual-life-cycle": true,
"trackBy-function": true,
"use-pipe-transform-interface": true,
"component-class-suffix": true,
"directive-class-suffix": true,
"pipe-impure": true,
"i18n": [true, "check-id", "check-text"],
"template-cyclomatic-complexity": [true, 5],
"template-conditional-complexity": [true, 4]
}
}
To run TSLint with this setup you can use one of the following alternatives:
Install codelyzer globally npm install -g codelyzer
Run TSLint from a package.json script by adding a script like tslint .
to your package.json, similar to:
"scripts": {
...
"lint": "tslint .",
...
},
Then run npm run lint
B. Using codelyzer from node_modules directory
Now create the following tslint.json
file where your node_modules
directory is:
{
"rulesDirectory": ["node_modules/codelyzer"],
"rules": {
"angular-whitespace": [true, "check-interpolation", "check-semicolon"],
"banana-in-box": true,
"templates-no-negated-async": true,
"directive-selector": [true, "attribute", "sg", "camelCase"],
"component-selector": [true, "element", "sg", "kebab-case"],
"max-inline-declarations": true,
"no-life-cycle-call": true,
"prefer-output-readonly": true,
"no-conflicting-life-cycle-hooks": true,
"enforce-component-selector": true,
"no-queries-parameter": true,
"prefer-inline-decorator": true,
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
"use-view-encapsulation": true,
"no-attribute-parameter-decorator": true,
"no-output-named-after-standard-event": true,
"no-input-rename": true,
"no-output-rename": true,
"no-output-on-prefix": true,
"no-forward-ref": true,
"no-unused-css": true,
"use-life-cycle-interface": true,
"contextual-life-cycle": true,
"trackBy-function": true,
"use-pipe-transform-interface": true,
"component-class-suffix": true,
"directive-class-suffix": true,
"pipe-impure": true,
"i18n": [true, "check-id", "check-text"],
"template-cyclomatic-complexity": [true, 5],
"template-conditional-complexity": [true, 4]
}
}
Next you can create a component file in the same directory with name component.ts
and the following content:
import { Component } from '@angular/core';
@Component({
selector: 'codelyzer',
template: `
<h1>Hello {{ name }}!</h1>
`
})
class Codelyzer {
name: string = 'World';
ngOnInit() {
console.log('Initialized');
}
}
As last step you can execute all the rules against your code with tslint:
./node_modules/.bin/tslint -c tslint.json component.ts
You should see the following output:
component.ts[4, 13]: The selector of the component "Codelyzer" should have prefix "sg" (https://goo.gl/cix8BY)
component.ts[12, 3]: Implement lifecycle hook interface OnInit for method ngOnInit in class Codelyzer (https://goo.gl/w1Nwk3)
component.ts[9, 7]: The name of the class Codelyzer should end with the suffix Component (https://goo.gl/5X1TE7)
Note that you need to have tslint plugin install on your editor.
Codelyzer should work out of the box with Atom but for VSCode you will have to open Code > Preferences > User Settings
, and enter the following config:
{
"tslint.rulesDirectory": "./node_modules/codelyzer",
"typescript.tsdk": "node_modules/typescript/lib"
}
Now you should have the following result:
Enjoy!
You can find it here.
Below you can find a recommended configuration which is based on the Angular Style Guide.
{
// The rule have the following arguments:
// [ENABLED, "attribute" | "element", "selectorPrefix" | ["listOfPrefixes"], "camelCase" | "kebab-case"]
"directive-selector": [true, "attribute", ["dir-prefix1", "dir-prefix2"], "camelCase"],
"component-selector": [true, "element", ["cmp-prefix1", "cmp-prefix2"], "kebab-case"],
"angular-whitespace": [true, "check-interpolation", "check-semicolon"],
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
"no-attribute-parameter-decorator": true,
"no-input-rename": true,
"no-output-on-prefix": true,
"no-output-rename": true,
"no-forward-ref": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"no-output-named-after-standard-event": true,
"max-inline-declarations": true,
"no-life-cycle-call": true,
"prefer-output-readonly": true,
"no-conflicting-life-cycle-hooks": true,
"enforce-component-selector": true,
"no-queries-parameter": true,
"prefer-inline-decorator": true,
// [ENABLED, "SUFFIX"]
// Where "SUFFIX" is your custom suffix, for instance "Page" for Ionic 2 components.
"component-class-suffix": [true, "Component"],
"directive-class-suffix": [true, "Directive"]
}
Rule | Status |
---|---|
banana-in-box | Stable |
contextual-life-cycle | Stable |
decorator-not-allowed | Stable |
pipe-impure | Stable |
templates-no-negated-async | Stable |
no-attribute-parameter-decorator | Stable |
no-forward-ref | Stable |
no-input-prefix | Stable |
no-input-rename | Stable |
no-output-on-prefix | Stable |
no-output-rename | Stable |
use-life-cycle-interface | Stable |
use-pipe-decorator | Stable |
use-pipe-transform-interface | Stable |
use-view-encapsulation | Stable |
component-class-suffix | Stable |
component-selector | Stable |
directive-class-suffix | Stable |
directive-selector | Stable |
use-host-property-decorator | Stable |
use-input-property-decorator | Stable |
use-output-property-decorator | Stable |
trackBy-function | Stable |
import-destructuring-spacing | Stable |
no-output-named-after-standard-event | Stable |
max-inline-declarations | Stable |
prefer-output-readonly | Stable |
enforce-component-selector | Stable |
no-life-cycle-call | Stable |
no-template-call-expression | Stable |
no-queries-parameter | Stable |
prefer-inline-decorator | Stable |
no-conflicting-life-cycle-hooks | Experimental |
i18n | Experimental |
no-unused-css | Experimental |
angular-whitespace | Experimental |
template-cyclomatic-complexity | Experimental |
template-conditional-complexity | Experimental |
pipe-naming | Deprecated |
Lint rules can be disabled by adding a marker in TypeScript files. More information here.
To disable rules that validate templates or styles you'd need to add a marker in the TypeScript file referencing them.
import { Component } from '@angular/core';
/* tslint:disable:trackBy-function */
@Component({
selector: 'codelyzer',
templateUrl: './codelyzer.component.html'
})
class Codelyzer {}
Codelyzer supports any template and style language by custom hooks. If you're using Sass for instance, you can allow codelyzer to analyze your styles by creating a file .codelyzer.js
in the root of your project (where the node_modules
directory is). In the configuration file can implement custom pre-processing and template resolution logic:
// Demo of transforming Sass styles
var sass = require('node-sass');
module.exports = {
// Definition of custom interpolation strings
interpolation: ['{{', '}}'],
// You can transform the urls of your external styles and templates
resolveUrl(url, decorator) {
return url;
},
// Transformation of the templates. This hooks is quite useful
// if you're using any other templating language, for instance
// jade, markdown, haml, etc.
//
// NOTE that this method WILL NOT throw an error in case of invalid template.
//
transformTemplate(code, url, decorator) {
return { code: code, url: url };
},
// Transformation of styles. This hook is useful is you're using
// any other style language, for instance Sass, Less, etc.
//
// NOTE that this method WILL NOT throw an error in case of invalid style.
//
transformStyle(code, url, decorator) {
var result = { code: code, url: url };
if (url && /\.scss$/.test(url)) {
var transformed = sass.renderSync({ data: code, sourceMap: true, outFile: '/dev/null' });
result.source = code;
result.code = transformed.css.toString();
result.map = transformed.map.toString();
}
return result;
},
// Custom predefined directives in case you get error for
// missing property and you are using a template reference
predefinedDirectives: [{ selector: 'form', exportAs: 'ngForm' }],
// None = 0b000, Error = 0b001, Info = 0b011, Debug = 0b111
logLevel: 0b111
};
mgechev | wKoza | preslavsh | rafaelss95 | rokerkony | GregOnNet |
alan-agius4 | kevinphelps | eppsilon | ghsyeung | csvn | Kobzol |
lazarljubenovic | sagittarius-rev | connor4312 | Foxandxss | gbilodeau | NagRock |
Hotell | Martin-Wegner | comfroels | plantain-00 | nexus-uw | piyukore06 |
alexkpek | alisd23 | sneas | Gillespie59 | eromano | Manduro |
karol-depka | leosvelperez | muhammadghazali | PapsOu | loktionov129 | rwlogel |
robzenn92 | rtfpessoa | scttcper | lacolaco | tmair | cexbrayat |
clydin | reduckted | someblue |
MIT
FAQs
Linting for Angular applications, following angular.io/styleguide.
The npm package codelyzer receives a total of 417,216 weekly downloads. As such, codelyzer popularity was classified as popular.
We found that codelyzer demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.