or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-eslint-plugin-prefer-arrow

ESLint plugin that enforces the use of arrow functions over function declarations in JavaScript code

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/eslint-plugin-prefer-arrow@1.2.x

To install, run

npx @tessl/cli install tessl/npm-eslint-plugin-prefer-arrow@1.2.0

index.mddocs/

ESLint Plugin Prefer Arrow

ESLint Plugin Prefer Arrow provides a configurable ESLint rule that enforces the use of arrow functions over traditional function declarations and expressions in JavaScript code. The plugin supports automatic code fixing when configured with the singleReturnOnly option and integrates seamlessly with ESLint's built-in functionality.

Package Information

  • Package Name: eslint-plugin-prefer-arrow
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install --save-dev eslint-plugin-prefer-arrow

Core Imports

// ESLint configuration (CommonJS)
const preferArrowPlugin = require('eslint-plugin-prefer-arrow');

// Or import specific rules
const { rules } = require('eslint-plugin-prefer-arrow');

Basic Usage

Add the plugin to your ESLint configuration file:

// .eslintrc.js
module.exports = {
  plugins: ['prefer-arrow'],
  rules: {
    'prefer-arrow/prefer-arrow-functions': ['warn', {
      disallowPrototype: true,
      singleReturnOnly: false,
      classPropertiesAllowed: false
    }]
  }
};

Autofix with the --fix flag (requires singleReturnOnly: true):

eslint --fix src/

Architecture

ESLint Plugin Prefer Arrow is built around several key components:

  • Plugin Entry Point: Exports rules and default configuration for ESLint integration
  • Rule Implementation: Core AST visitor that analyzes function nodes and reports violations
  • Node Analysis Functions: Helper functions that determine function context and eligibility for conversion
  • Code Transformation Engine: Automatic fixing logic that converts functions to arrow functions
  • Configuration Schema: Type-safe options validation for rule customization

The plugin operates by registering AST visitors for FunctionDeclaration and FunctionExpression nodes, then applying a series of contextual checks to determine if the function should be converted to an arrow function based on the configured options.

Capabilities

Plugin Configuration

The main plugin export provides ESLint with the rule definitions and default configuration.

/**
 * Main plugin export containing rule definitions and default configuration
 */
const plugin = {
  rules: {
    'prefer-arrow-functions': PreferArrowFunctionsRule
  },
  rulesConfig: {
    'prefer-arrow-functions': [2]
  }
};

Prefer Arrow Functions Rule

The core ESLint rule that detects function declarations and expressions that could be converted to arrow functions.

/**
 * ESLint rule implementation for preferring arrow functions
 */
const PreferArrowFunctionsRule = {
  meta: RuleMeta,
  create: (context: ESLintContext) => RuleVisitor
};

interface RuleMeta {
  docs: {
    description: string;
    category: string;
    recommended: boolean;
  };
  fixable: "code";
  schema: RuleOptionsSchema[];
}

interface RuleOptionsSchema {
  type: "object";
  properties: {
    disallowPrototype?: boolean;
    singleReturnOnly?: boolean;
    classPropertiesAllowed?: boolean;
    allowStandaloneDeclarations?: boolean;
  };
  additionalProperties: false;
}

interface RuleVisitor {
  'FunctionDeclaration:exit': (node: ESLintNode) => void;
  'FunctionExpression:exit': (node: ESLintNode) => void;
}

Usage Example:

// In .eslintrc.js
module.exports = {
  plugins: ['prefer-arrow'],
  rules: {
    'prefer-arrow/prefer-arrow-functions': ['error', {
      disallowPrototype: true,
      singleReturnOnly: true,
      classPropertiesAllowed: false,
      allowStandaloneDeclarations: true
    }]
  }
};

Rule Configuration Options

The rule accepts a configuration object with the following optional properties:

interface RuleOptions {
  /**
   * If true, warns about all function usage regardless of context
   * If false, allows functions assigned to object prototypes
   * @default false
   */
  disallowPrototype?: boolean;

  /**
   * If true, only warns about functions that contain only a return statement
   * Enables automatic fixing with eslint --fix
   * @default false
   */
  singleReturnOnly?: boolean;

  /**
   * If true, warns about class methods that could be arrow functions
   * Useful with Babel's transform-class-properties plugin
   * @default false
   */
  classPropertiesAllowed?: boolean;

  /**
   * If true, ignores top-level function declarations
   * Still warns about nested functions
   * @default false
   */
  allowStandaloneDeclarations?: boolean;
}

Configuration Examples:

// Conservative setup - only simple functions with auto-fix
{
  "prefer-arrow/prefer-arrow-functions": ["warn", {
    "singleReturnOnly": true
  }]
}

// Aggressive setup - all functions except prototypes
{
  "prefer-arrow/prefer-arrow-functions": ["error", {
    "disallowPrototype": false,
    "singleReturnOnly": false,
    "classPropertiesAllowed": true,
    "allowStandaloneDeclarations": false
  }]
}

// Balanced setup - ignores top-level declarations
{
  "prefer-arrow/prefer-arrow-functions": ["warn", {
    "disallowPrototype": true,
    "singleReturnOnly": true,
    "allowStandaloneDeclarations": true
  }]
}

Types

/**
 * ESLint rule context object passed to rule create function
 */
interface ESLintContext {
  options: [RuleOptions?];
  report: (descriptor: ReportDescriptor) => void;
  getSourceCode: () => SourceCode;
}

/**
 * ESLint AST node representing function declarations and expressions
 */
interface ESLintNode {
  type: 'FunctionDeclaration' | 'FunctionExpression';
  id?: { name: string };
  params: Parameter[];
  body: BlockStatement;
  generator: boolean;
  async: boolean;
  parent: ESLintNode;
  range: [number, number];
}

/**
 * Function parameter in AST
 */
interface Parameter {
  type: string;
  name?: string;
  range: [number, number];
}

/**
 * Block statement containing function body
 */
interface BlockStatement {
  type: 'BlockStatement';
  body: Statement[];
  range: [number, number];
}

/**
 * Generic AST statement
 */
interface Statement {
  type: string;
  range: [number, number];
}

/**
 * ESLint source code object
 */
interface SourceCode {
  getText: () => string;
  getTokens: (node: ESLintNode) => Token[];
  getTokenAfter: (token: Token) => Token;
}

/**
 * ESLint token
 */
interface Token {
  type: string;
  value: string;
  start?: number;
  end?: number;
  range: [number, number];
}

/**
 * Report descriptor for ESLint violations
 */
interface ReportDescriptor {
  node: ESLintNode;
  message: string;
  fix?: (fixer: RuleFixer) => FixCommand | FixCommand[];
}

/**
 * ESLint rule fixer for automatic code fixes
 */
interface RuleFixer {
  replaceText: (node: ESLintNode, text: string) => FixCommand;
  replaceTextRange: (range: [number, number], text: string) => FixCommand;
}

/**
 * Fix command returned by fixer methods
 */
interface FixCommand {
  range: [number, number];
  text: string;
}

Node Analysis Functions

The rule includes several helper functions that analyze function nodes to determine conversion eligibility.

/**
 * Determines if a function is assigned to an object prototype
 * @param node - Function node to analyze
 * @returns True if function is a prototype method
 */
function isPrototypeAssignment(node: ESLintNode): boolean;

/**
 * Checks if a function is a constructor method
 * @param node - Function node to analyze
 * @returns True if function is a constructor
 */
function isConstructor(node: ESLintNode): boolean;

/**
 * Analyzes if function body or parameters contain 'this' references
 * @param node - AST node to search
 * @returns True if 'this' is referenced
 */
function containsThis(node: ESLintNode): boolean;

/**
 * Checks if function is a named function declaration
 * @param node - Function node to analyze
 * @returns True if function has a name
 */
function isNamed(node: ESLintNode): boolean;

/**
 * Determines if function body contains only a return statement
 * @param node - Function node to analyze
 * @returns True if function only returns a value
 */
function functionOnlyContainsReturnStatement(node: ESLintNode): boolean;

/**
 * Checks if function is a named default export
 * @param node - Function node to analyze
 * @returns True if function is exported as default with a name
 */
function isNamedDefaultExport(node: ESLintNode): boolean;

/**
 * Determines if function is a class method
 * @param node - Function node to analyze
 * @returns True if function is defined within a class
 */
function isClassMethod(node: ESLintNode): boolean;

/**
 * Checks if function is a generator function
 * @param node - Function node to analyze
 * @returns True if function uses generator syntax
 */
function isGeneratorFunction(node: ESLintNode): boolean;

/**
 * Determines if function is a getter or setter method
 * @param node - Function node to analyze
 * @returns True if function is a property accessor
 */
function isGetterOrSetter(node: ESLintNode): boolean;

/**
 * Checks if function is a CommonJS module export
 * @param node - Function node to analyze
 * @returns True if function is assigned to module.exports or exports
 */
function isModuleExport(node: ESLintNode): boolean;

/**
 * Determines if function is a top-level standalone declaration
 * @param node - Function node to analyze
 * @returns True if function is declared at program or export level
 */
function isStandaloneDeclaration(node: ESLintNode): boolean;

Code Transformation Functions

Functions responsible for converting function syntax to arrow function syntax during auto-fixing.

/**
 * Converts function expressions to arrow function syntax
 * @param src - ESLint source code object
 * @param node - Function expression node to convert
 * @returns Transformed arrow function code
 */
function fixFunctionExpression(src: SourceCode, node: ESLintNode): string;

/**
 * Converts function declarations to arrow function variable assignments
 * @param src - ESLint source code object
 * @param node - Function declaration node to convert
 * @returns Transformed arrow function variable declaration
 */
function fixFunctionDeclaration(src: SourceCode, node: ESLintNode): string;

/**
 * Replaces tokens in source code with new text
 * @param origSource - Original source code string
 * @param tokens - Array of tokens to process
 * @param replacements - Map of token positions to replacement text
 * @returns Modified source code string
 */
function replaceTokens(
  origSource: string,
  tokens: Token[],
  replacements: { [position: number]: [string, boolean?, boolean?] }
): string;

/**
 * Creates a token matching function for finding specific tokens
 * @param type - Token type to match
 * @param value - Optional token value to match
 * @returns Function that tests if a token matches criteria
 */
function tokenMatcher(type: string, value?: string): (token: Token) => boolean;

Error Messages

The rule produces different error messages based on the detected pattern:

  • Named functions: "Use const or class constructors instead of named functions"
  • Anonymous functions: "Prefer using arrow functions over plain functions"
  • Single return functions: "Prefer using arrow functions over plain functions which only return a value"

Installation and Setup

Install as a development dependency:

npm install --save-dev eslint-plugin-prefer-arrow

Add to your ESLint configuration:

// .eslintrc.js
module.exports = {
  plugins: ['prefer-arrow'],
  rules: {
    'prefer-arrow/prefer-arrow-functions': 'warn'
  }
};

For automatic fixing, enable singleReturnOnly and use the --fix flag:

eslint --fix src/