or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

angular-wrappers.mdbest-practices.mddeprecated-features.mddevelopment-conventions.mderror-prevention.mdindex.mdnaming-conventions.md
tile.json

development-conventions.mddocs/

Development Convention Rules

Rules that establish consistent code organization, dependency injection patterns, and development practices for maintainable AngularJS applications.

Capabilities

Dependency Injection (DI)

Requires consistent dependency injection syntax across the application.

/**
 * Require a consistent DI syntax
 * Enforces one of several DI patterns for consistency
 */
const di = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/di.md" };
    schema: [{
      type: "string",
      enum: ["function", "array", "$inject"]
    }];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Examples:

// Configuration: ["error", "array"]
// ✓ GOOD - Array notation
angular.module('myApp').controller('MyController', ['$scope', '$http', function($scope, $http) {
  // controller logic
}]);

// Configuration: ["error", "$inject"] 
// ✓ GOOD - $inject property
function MyController($scope, $http) {
  // controller logic
}
MyController.$inject = ['$scope', '$http'];
angular.module('myApp').controller('MyController', MyController);

// Configuration: ["error", "function"]
// ✓ GOOD - Function parameter names (not minification-safe)
angular.module('myApp').controller('MyController', function($scope, $http) {
  // controller logic
});

DI Order

Requires dependency injection parameters to be sorted alphabetically.

/**
 * Require DI parameters to be sorted alphabetically
 * Improves code readability and consistency
 */
const diOrder = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/di-order.md" };
    schema: [];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Example:

// ✗ BAD - Dependencies not in alphabetical order
angular.module('myApp').controller('MyController', ['$scope', '$http', '$location', function($scope, $http, $location) {}]);

// ✓ GOOD - Dependencies sorted alphabetically
angular.module('myApp').controller('MyController', ['$http', '$location', '$scope', function($http, $location, $scope) {}]);

Dumb Inject

Requires unittest inject functions to only consist of assignments from injected values.

/**
 * Unittest inject functions should only consist of assignments from injected values to describe block variables
 * Keeps test setup clean and focused
 */
const dumbInject = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/dumb-inject.md" };
    schema: [];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Example:

// ✗ BAD - Complex logic in inject
describe('MyController', function() {
  var $scope, $http;
  
  beforeEach(inject(function(_$rootScope_, _$http_) {
    $scope = _$rootScope_.$new();
    $http = _$http_;
    $scope.items = []; // Additional logic
    $http.get('/api/data'); // Service calls
  }));
});

// ✓ GOOD - Simple assignments only
describe('MyController', function() {
  var $scope, $http;
  
  beforeEach(inject(function(_$rootScope_, _$http_) {
    $scope = _$rootScope_.$new();
    $http = _$http_;
  }));
});

Function Type

Requires and specifies a consistent function style for components.

/**
 * Require and specify a consistent function style for components ('named' or 'anonymous')
 * Enforces consistent function declaration patterns
 * Linked to John Papa's Angular Style Guide y024
 */
const functionType = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/function-type.md" };
    schema: [{
      type: "string",
      enum: ["named", "anonymous"]
    }];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Example:

// Configuration: ["error", "named"]
// ✓ GOOD - Named functions
function UserController($scope) {
  // controller logic
}
angular.module('myApp').controller('UserController', UserController);

// Configuration: ["error", "anonymous"]  
// ✓ GOOD - Anonymous functions
angular.module('myApp').controller('UserController', function($scope) {
  // controller logic
});

Module Dependency Order

Requires a consistent order of module dependencies.

/**
 * Require a consistent order of module dependencies
 * Enforces alphabetical ordering of module dependencies
 */
const moduleDependencyOrder = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/module-dependency-order.md" };
    schema: [{
      type: "object",
      properties: {
        grouped: { type: "boolean" },
        prefix: { type: "string" }
      }
    }];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Example:

// ✗ BAD - Dependencies not ordered
angular.module('myApp', ['ui.router', 'ngAnimate', 'myApp.users', 'myApp.admin']);

// ✓ GOOD - Dependencies in alphabetical order
angular.module('myApp', ['myApp.admin', 'myApp.users', 'ngAnimate', 'ui.router']);

// With grouping configuration - project modules first, then third-party
angular.module('myApp', ['myApp.admin', 'myApp.users', 'ngAnimate', 'ui.router']);

No Service Method

Enforces using factory() instead of service() for consistency.

/**
 * Use factory() instead of service()
 * Promotes consistent service creation pattern
 * Linked to John Papa's Angular Style Guide y040
 */
const noServiceMethod = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/no-service-method.md" };
    schema: [];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Example:

// ✗ BAD - Using service() method
angular.module('myApp').service('UserService', function($http) {
  this.getUsers = function() {
    return $http.get('/api/users');
  };
});

// ✓ GOOD - Using factory() method
angular.module('myApp').factory('UserService', function($http) {
  return {
    getUsers: function() {
      return $http.get('/api/users');
    }
  };
});

One Dependency Per Line

Requires all dependency injection parameters to be located on their own line.

/**
 * Require all DI parameters to be located in their own line
 * Improves readability when dealing with many dependencies
 */
const oneDependencyPerLine = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/one-dependency-per-line.md" };
    schema: [{
      type: "object",
      properties: {
        matchNames: { type: "boolean" }
      }
    }];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Example:

// ✗ BAD - Multiple dependencies on same line
angular.module('myApp').controller('MyController', ['$scope', '$http', '$location', function($scope, $http, $location) {}]);

// ✓ GOOD - One dependency per line
angular.module('myApp').controller('MyController', [
  '$scope',
  '$http', 
  '$location',
  function($scope, $http, $location) {
    // controller logic
  }
]);

Rest Service

Disallows different REST service patterns and specifies one approach.

/**
 * Disallow different rest service and specify one of '$http', '$resource', 'Restangular'
 * Enforces consistent HTTP client usage across the application
 */
const restService = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/rest-service.md" };
    schema: [{
      type: "string",
      enum: ["$http", "$resource", "Restangular"]
    }];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Example:

// Configuration: ["error", "$http"]
// ✗ BAD - Using $resource when $http is required
angular.module('myApp').factory('UserService', function($resource) {
  return $resource('/api/users/:id');
});

// ✓ GOOD - Using specified $http service
angular.module('myApp').factory('UserService', function($http) {
  return {
    getUsers: function() {
      return $http.get('/api/users');
    }
  };
});

Watchers Execution

Requires and specifies consistent use of $scope.digest() or $scope.apply().

/**
 * Require and specify consistent use $scope.digest() or $scope.apply()
 * Enforces consistent digest cycle triggering patterns
 */
const watchersExecution = {
  meta: {
    docs: { url: "https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/watchers-execution.md" };
    schema: [{
      type: "string",
      enum: ["$digest", "$apply"]
    }];
  };
  create: (context: ESLintContext) => ESLintVisitor;
};

Usage Example:

// Configuration: ["error", "$apply"]
// ✗ BAD - Using $digest when $apply is required
$scope.$digest();

// ✓ GOOD - Using specified $apply method
$scope.$apply();

// Configuration: ["error", "$digest"]
// ✓ GOOD - Using $digest for performance-critical scenarios
$scope.$digest();

Configuration Patterns

Development convention rules often support flexible configuration to match team preferences:

interface ConventionRuleConfig {
  /** Specific pattern to enforce */
  pattern?: "array" | "function" | "$inject" | "named" | "anonymous";
  /** Enable special handling modes */
  grouped?: boolean;
  matchNames?: boolean;
  /** Specify service types */
  serviceType?: "$http" | "$resource" | "Restangular";
  /** Prefix patterns */
  prefix?: string;
}

Configuration Examples:

// DI syntax preference
"angular/di": ["error", "array"]

// Function style preference  
"angular/function-type": ["error", "named"]

// REST service standardization
"angular/rest-service": ["error", "$http"]

// Enhanced dependency line formatting
"angular/one-dependency-per-line": ["error", { "matchNames": true }]

These rules help establish consistent development patterns that make code more maintainable, readable, and easier for teams to collaborate on.