Codelyzer
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.
How to use?
Angular CLI
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.
Angular Seed
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.
Custom Setup
You can easily use codelyzer with your custom setup:
Installation
npm i codelyzer@~3.1.0 tslint@^5.0.0 typescript@^2.1.4 @angular/core@4.2.1 @angular/compiler@4.2.1 rxjs@5.0.1 zone.js@0.8.4
A. Using codelyzer package in PATH
Create the following tslint.json
file like:
{
"extends": [ "codelyzer" ],
"rules":{
"angular-whitespace": [true, "check-interpolation", "check-pipe", "check-semicolon"],
"banana-in-box": true,
"templates-no-negated-async": true,
"directive-selector": [true, "attribute", "sg", "camelCase"],
"component-selector": [true, "element", "sg", "kebab-case"],
"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-input-rename": true,
"no-output-rename": true,
"no-forward-ref": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"pipe-naming": [true, "camelCase", "sg"],
"component-class-suffix": true,
"directive-class-suffix": true,
"templates-use-public": true,
"no-access-missing-member": true,
"invoke-injectable": true,
"template-to-ng-template": true
}
}
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-pipe"],
"banana-in-box": true,
"templates-no-negated-async": true,
"directive-selector": [true, "attribute", "sg", "camelCase"],
"component-selector": [true, "element", "sg", "kebab-case"],
"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-rename": true,
"no-forward-ref": true,
"use-view-encapsulation": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"pipe-naming": [true, "camelCase", "sg"],
"component-class-suffix": true,
"directive-class-suffix": true,
"templates-use-public": true,
"no-access-missing-member": true,
"invoke-injectable": true,
"template-to-ng-template": true
}
}
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 {{ nme }}!</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)
component.ts[6, 18]: The property "nme" that you're trying to access does not exist in the class declaration. Probably you mean: "name".
Editor Configuration
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!
Changelog
You can find it here.
Recommended configuration
Below you can find a recommended configuration which is based on the Angular Style Guide.
{
"directive-selector": [true, "attribute", ["dir-prefix1", "dir-prefix2"], "camelCase"],
"component-selector": [true, "element", ["cmp-prefix1", "cmp-prefix2"], "kebab-case"],
"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-rename": true,
"no-forward-ref": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"component-class-suffix": [true, "Component"],
"directive-class-suffix": [true, "Directive"],
"templates-use-public": true,
"no-access-missing-member": true,
"invoke-injectable": true
}
Advanced configuration
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:
var sass = require('node-sass');
module.exports = {
interpolation: ['{{', '}}'],
resolveUrl(url, decorator) {
return url;
},
transformTemplate(code, url, decorator) {
return { code: code, url: url };
},
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;
},
predefinedDirectives: [
{ selector: 'form', exportAs: 'ngForm' }
],
logLevel: 0b111
};
Contributors
License
MIT