ESLint rules for your angular project with checks for best-practices, conventions or potential errors.
This repository will give access to new rules for the ESLint tool. You should use it only if you are developing an AngularJS application.
Since the 0.0.4 release, some rules defined in John Papa's Guideline have been implemented. In the description below, you will have a link to the corresponding part of the guideline, in order to have more information.
- Usage with shareable config
- Usage without shareable config
- Defaults
- Rules
- Need your help
- How to create a new rule
- Default ESLint configuration file
- Who uses it?
- Team
Usage with shareable config
Users may use the shareable eslint-config-angular to quickly setup eslint-plugin-angular. It also marks Angular as a global variable and defines required ESLint rules to use this plugin.
-
Install
eslintas a dev-dependency:npm install --save-dev eslint
-
Install
eslint-plugin-angularas a dev-dependency:npm install --save-dev eslint-plugin-angular
-
Install
eslint-config-angularas a dev-dependency:npm install --save-dev eslint-config-angular
-
Use the shareable config by adding it to your
.eslintrc:extends: angular
-
Install
eslintas a dev-dependency:npm install --save-dev eslint
-
Install
eslint-plugin-angularas a dev-dependency:npm install --save-dev eslint-plugin-angular
-
Enable the plugin by adding it to your
.eslintrc:plugins: - angular
-
You can also configure these rules in your
.eslintrc. All rules defined in this plugin have to be prefixed by 'angular/'plugins: - angular rules: - angular/controller_name: 0
{
"plugins": [
"angular/angular"
],
"rules": {
"angular/angularelement": 1,
"angular/component-limit": [0, 1],
"angular/controller-as": 2,
"angular/controller-as-route": 2,
"angular/controller-as-vm": [2, "vm"],
"angular/controller-name": [2, "/[A-Z].*Controller$/"],
"angular/deferred": 0,
"angular/definedundefined": 2,
"angular/di": [2, "function"],
"angular/di-order": 0,
"angular/di-unused": 0,
"angular/directive-name": 0,
"angular/directive-restrict": 0,
"angular/document-service": 2,
"angular/dumb-inject": 0,
"angular/empty-controller": 0,
"angular/file-name": 0,
"angular/filter-name": 0,
"angular/foreach": 0,
"angular/function-type": 0,
"angular/interval-service": 2,
"angular/json-functions": 2,
"angular/log": 2,
"angular/module-dependency-order": [0, {"grouped": false, "prefix": null}],
"angular/module-getter": 2,
"angular/module-name": 0,
"angular/module-setter": 2,
"angular/no-angular-mock": 0,
"angular/no-controller": 0,
"angular/no-cookiestore": 2,
"angular/no-digest": 0,
"angular/no-directive-replace": 0,
"angular/no-http-callback": -1,
"angular/no-inline-template": [0, {"allowSimple": true}],
"angular/no-jquery-angularelement": 2,
"angular/no-private-call": 2,
"angular/no-run-logic": 0,
"angular/no-services": [2, ["$http", "$resource", "Restangular", "$q"]],
"angular/no-service-method": 2,
"angular/on-watch": 2,
"angular/one-dependency-per-line": 0,
"angular/prefer-component": 0,
"angular/rest-service": 0,
"angular/service-name": 0,
"angular/timeout-service": 2,
"angular/typecheck-array": 2,
"angular/typecheck-date": 2,
"angular/typecheck-function": 2,
"angular/typecheck-number": 2,
"angular/typecheck-object": 2,
"angular/typecheck-regexp": 2,
"angular/typecheck-string": 2,
"angular/watchers-execution": [0, "$digest"],
"angular/window-service": 2
}
}Rules in eslint-plugin-angular are divided into several categories to help you better understand their value.
The following rules detect patterns that can lead to errors.
- module-getter - disallow to reference modules with variables and require to use the getter syntax instead
angular.module('myModule')(y022) - module-setter - disallow to assign modules to variables (linked to module-getter (y021)
- no-private-call - disallow use of internal angular properties prefixed with $$
These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns..
- component-limit - limit the number of angular components per file (y001)
- controller-as - disallow assignments to
$scopein controllers (y031) - controller-as-route - require the use of controllerAs in routes or states (y031)
- controller-as-vm - require and specify a capture variable for
thisin controllers (y032) - deferred - use
$q(function(resolve, reject){})instead of$q.deferred - di-unused - disallow unused DI parameters
- directive-restrict - disallow any other directive restrict than 'A' or 'E' (y074)
- empty-controller - disallow empty controllers
- no-controller - disallow use of controllers (according to the component first pattern)
- no-inline-template - disallow the use of inline templates
- no-run-logic - keep run functions clean and simple (y171)
- no-services - disallow DI of specified services for other angular components (
$httpfor controllers, filters and directives) - on-watch - require
$onand$watchderegistration callbacks to be saved in a variable - prefer-component -
These rules prevent you from using deprecated angular features.
- no-cookiestore - use
$cookiesinstead of$cookieStore - no-directive-replace - disallow the deprecated directive replace property
- no-http-callback - disallow the
$httpmethodssuccess()anderror()
These rules help you to specify several naming conventions.
- controller-name - require and specify a prefix for all controller names (y123, y124)
- directive-name - require and specify a prefix for all directive names (y073, y126)
- file-name - require and specify a consistent component name pattern (y120, y121)
- filter-name - require and specify a prefix for all filter names
- module-name - require and specify a prefix for all module names (y127)
- service-name - require and specify a prefix for all service names (y125)
Angular often provide multi ways to to something. These rules help you to define convention for your project.
- di - require a consistent DI syntax
- di-order - require DI parameters to be sorted alphabetically
- dumb-inject - unittest
injectfunctions should only consist of assignments from injected values to describe block variables - function-type - require and specify a consistent function style for components ('named' or 'anonymous') (y024)
- module-dependency-order - require a consistent order of module dependencies
- no-service-method - use
factory()instead ofservice()(y040) - one-dependency-per-line - require all DI parameters to be located in their own line
- rest-service - disallow different rest service and specify one of '$http', '$resource', 'Restangular'
- watchers-execution - require and specify consistent use
$scope.digest()or$scope.apply()
These rules help you to enforce the usage of angular wrappers.
- angularelement - use
angular.elementinstead of$orjQuery - definedundefined - use
angular.isDefinedandangular.isUndefinedinstead of other undefined checks - document-service - use
$documentinstead ofdocument(y180) - foreach - use
angular.forEachinstead of nativeArray.prototype.forEach - interval-service - use
$intervalinstead ofsetInterval(y181) - json-functions - use
angular.fromJsonand 'angular.toJson' instead ofJSON.parseandJSON.stringify - log - use the
$logservice instead of theconsolemethods - no-angular-mock - require to use
angular.mockmethods directly - no-jquery-angularelement - disallow to wrap
angular.elementobjects withjQueryor$ - timeout-service - use
$timeoutinstead ofsetTimeout(y181) - typecheck-array - use
angular.isArrayinstead oftypeofcomparisons - typecheck-date - use
angular.isDateinstead oftypeofcomparisons - typecheck-function - use
angular.isFunctioninstead oftypeofcomparisons - typecheck-number - use
angular.isNumberinstead oftypeofcomparisons - typecheck-object - use
angular.isObjectinstead oftypeofcomparisons - typecheck-string - use
angular.isStringinstead oftypeofcomparisons - window-service - use
$windowinstead ofwindow(y180)
These rules will be removed in version 1.0.0
- no-digest - use
$apply()instead of$digest()(replaced by watchers-execution) - typecheck-regexp - use
angular.isRegexpinstead of other comparisons (no native angular method)
It is an opensource project. Any help will be very useful. You can :
- Create issue
- Send Pull Request
- Write Documentation
- Add new Features
- Add new Rules
- Improve the quality
- Reply to issues
All development happens on the development branch. This means all pull requests should be made to the development branch.
If it is time to release, @Gillespie59 will bump the version in package.json, create a Git tag and merge the development branch into master. @Gillespie59 will then publish the new release to the npm registry.
We appreciate contributions and the following notes will help you before you open a Pull Request.
Have a look at the existing issues. There may exist similar issues with useful information.
There are some useful references for creating new rules. Specificly useful are:
- The Context Object - This is the most basic understanding needed for adding or modifying a rule.
- Options Schemas - This is the preferred way for validating configuration options.
- Scope - This is the scope object returned by
context.getScope().
rules/<your-rule>.js- JavaScript file with the new rule
- The filename
<your-rule>is exactly the usage name in eslint configsangular/<your-rule> - Have a look at the
angularRulewrapper and theutils(both inrules/utils/) - they probably make things easier for you - Add a documentation comment to generate a markdown documentation with the
gulp docstask
test/<your-rule>.js- Write some tests and execute them with
gulp test - Have a look at the coverage reports
coverage/lcov-report/index.html
- Write some tests and execute them with
examples/<your-rule>.js- Add some examples for the documentation
- Run the
gulp docstask to test the examples and update the markdown documentation
docs/<your-rule>.md- Generated by the
gulp docstask
- Generated by the
index.js- Add your rule
rulesConfiguration.addRule('<your-rule>', [0, {someConfig: 'someValue'}])
- Add your rule
- Check that the
gulptask is working - Commit generated changes in
README.mdanddocs/<your-rule>.md - Open your PR to the
developmentbranch NOTmaster
We can use a property, defined in the ESLint configuration file, in order to know which version is used : Angular 1 or Angular 2. based on this property, you can create rules for each version.
plugins:
- angular
rules:
angular/controller-name:
- 2
- '/[A-Z].*Controller$/'
globals:
angular: true
settings:
angular: 2And in your rule, you can access to this property thanks to the context object :
//If Angular 2 is used, we disabled the rule
if(context.settings.angular === 2){
return {};
}
return {
'CallExpression': function(node) {
}
};Here is the basic configuration for the rules defined in the ESLint plugin, in order to be compatible with the guideline provided by @johnpapa :
{
"rules": {
"no-use-before-define": 0
}
}| Emmanuel Demey | Tilman Potthof | Remco Haszing |