Want to take your software engineering career to the next level? Join the mailing list for career tips & advice Click here

codelyzer

Static analysis for Angular projects.

Subscribe to updates I use codelyzer


Statistics on codelyzer

Number of watchers on Github 1589
Number of open issues 32
Average time to close an issue 6 days
Main language TypeScript
Average time to merge a PR 1 day
Open pull requests 9+
Closed pull requests 14+
Last commit over 2 years ago
Repo Created over 4 years ago
Repo Last Updated over 2 years ago
Size 14.3 MB
Homepage http://codelyzer....
Organization / Authormgechev
Latest Release4.2.1
Contributors2
Page Updated
Do you use codelyzer? Leave a review!
View open issues (32)
View codelyzer activity
View on github
Book a Mock Interview With Me (Silicon Valley Engineering Leader, 100s of interviews conducted)
Software engineers: It's time to get promoted. Starting NOW! Subscribe to my mailing list and I will equip you with tools, tips and actionable advice to grow in your career.
Evaluating codelyzer for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

npm version Downloads Build Status Build status Gitter Chat

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

Preset

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

Custom Installation

You can easily use codelyzer with your custom setup:

npm i codelyzer@~4.2.0 tslint@^5.0.0 @angular/core@~5.2.0 @angular/compiler@~5.2.0

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"],
    "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:

  1. Install codelyzer globally npm install -g codelyzer

  2. 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"],
    "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)

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:

VSCode Codelyzer

Enjoy!

Changelog

You can find it here.

Recommended configuration

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,

  // [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"]
}

Rules Status

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
i18n Experimental
no-unused-css Experimental
angular-whitespace Experimental
template-cyclomatic-complexity Experimental
template-conditional-complexity Experimental
pipe-naming Deprecated

Disable a rule that validates Template or Styles

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 { }

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:

// 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
};

Contributors

mgechev preslavsh wKoza rokerkony GregOnNet alan-agius4
mgechev preslavsh wKoza rokerkony GregOnNet alan-agius4
eppsilon ghsyeung csvn Kobzol lazarljubenovic sagittarius-rev
eppsilon ghsyeung csvn Kobzol lazarljubenovic sagittarius-rev
connor4312 Foxandxss Hotell Martin-Wegner comfroels plantain-00
connor4312 Foxandxss Hotell Martin-Wegner comfroels plantain-00
nexus-uw leosvelperez alisd23 eromano gbilodeau Manduro
nexus-uw leosvelperez alisd23 eromano gbilodeau Manduro
karol-depka kevinphelps Gillespie59 rtfpessoa scttcper lacolaco
karol-depka kevinphelps Gillespie59 rtfpessoa scttcper lacolaco
tmair cexbrayat reduckted
tmair cexbrayat reduckted

License

MIT

codelyzer open issues Ask a question     (View All Issues)
  • almost 4 years Build fails at the end after running tslint from command line
  • almost 4 years The pipe class has the Pipe decorator, so it should implement the PipeTransform interface
  • almost 4 years [Proposal] Visual Studio IDE integration
  • almost 4 years Warn if @Injectable() not included on exported class with no other Decorators
  • almost 4 years Warn if there's @Injectable() on top of another decorator
  • almost 4 years directive-selector-prefix rule clashes (sort of) with no-input-rename
  • almost 4 years ComponentSelectorNameRule crashes if @Component() has no arg
  • almost 4 years Feature request: Enforce value of @Component.changeDetection
  • almost 4 years Ionic 2 Support
  • almost 4 years feature: if class uses lifecycle hooks it must had proper name decorator
  • almost 4 years Do not recompute Angular component metadata
  • almost 4 years no-access-missing-member should verify usage of proper accessor
  • almost 4 years no-access-missing-member rule not considering template references
  • almost 4 years Rise a warning if given class implements PipeTransform but is not decorated with @Pipe
  • almost 4 years component-selector-prefix should match first word of selector instead of prefix
  • almost 4 years Support for external templates
  • almost 4 years no-unused-variable from tslint is not sufficient to angular 2 project
  • almost 4 years Best way for multiple prefix rules
  • almost 4 years Pipe/Directive/Component naming conventions should be more consistent
  • about 4 years request| feat(NgModule): warn users of all the NgModule gotchas
  • about 4 years use-life-cycle-interface support for inheritance
  • about 4 years Feature request: Add rule to prohibit use of document and window
  • over 4 years Develop selector validators compatible with spec
  • over 4 years Use metadata reader
codelyzer open pull requests (View All Pulls)
  • Kebab case should validate on single lower-case word
  • Missing properties fix
  • fix(noAccessMissingMember): set the expression in bounded property
  • fix(noAccessMissingMember): search among all declared members
  • feat(templateWalker): add template references support
  • WIP feat(rule): add complexityRule
  • WIP fix(rule): add i18n test with pural
  • add tests in relation with #452 and #487
  • chore: drop dependencies
codelyzer list of languages used
codelyzer latest release notes

Bug Fixes

  • Improved peerDependencies range.

New Rules

  • template-cyclomatic-complexity which limits the estimated Cyclomatic complexity in your templates. Credits to wKoza.
  • template-conditional-complexity which limits the complexity of boolean expressions inside of your templates. Credits to wKoza.

Features

  • Support for Angular version 6 #524 50fa2d6
  • Cyclomatic complexity rule template-cyclomatic-complexity #514 3221330
  • Limiting template condition complexity (rule template-conditional-complexity) #508 bb86295
  • Complete Rules Status section in README and complete Rules Page #501 1fe9d22

Bug Fixes

  • extends: [codelyzer] is broken #505 7b76dfa
  • Message for 'use-host-property-decorator' includes invalid link to Angular style docs #510 5fc77c9

Features

  • Feature request: no output named after a standard DOM event #473 ae3f07b
  • Support for Angular Compiler 5.2 #496 6a6b3de

Bug Fixes

  • i18n check-text edge cases #442 4c1c8d4
  • Codelyzer hanging for styles attribute in Angular component #446 a31c6d2 and 9c90ac3
  • no-output-on-prefix incorrectly throws error if output property name starts with one #480 9b844cc

Thanks to @gbilodeau for NoOutputNamedAfterStandardEventRule and wKoza for the code reviews!

Other projects in TypeScript