Создание ESLint-плагина для проверки URL в экземплярах axios

Оглавление

В этой статье мы создадим собственное правило ESLint для Flat Config (новый формат конфигурации ESLint), которое будет проверять, что URL, передаваемый в axios, всегда начинается со слэша (/). Это поможет избежать ошибок, связанных с некорректной адресацией и гарантировать, что все запросы идут на относительные пути внутри одного домена.

Вот как выглядит само правило:

axios-slash.rule.eslint.js
export default {
  meta: {
    type: 'problem',
    docs: {
      description: 'URL passed to axios instance should start with a slash',
      category: 'Best Practices',
    },
    fixable: 'code',
    schema: [],
  },
  create(context) {
    function checkUrl(node, valueNode) {
      if (valueNode.type === 'Literal' && typeof valueNode.value === 'string') {
        if (!valueNode.value.startsWith('/')) {
          context.report({
            node: valueNode,
            message: 'URL passed to axios instance should start with a slash',
            fix(fixer) {
              return fixer.replaceText(valueNode, `'/${valueNode.value}'`);
            },
          });
        }
      }
    }

    return {
      CallExpression(node) {
        // Проверка: является ли вызов методом axios (axios.get, axios.post и т.д.)
        if (node.callee.type === 'MemberExpression' && node.callee.object.name === 'axios') {
          const urlArgument = node.arguments[0];

          // Вариант 1: передан URL напрямую в виде строки
          if (urlArgument.type === 'Literal') {
            checkUrl(node, urlArgument);

          // Вариант 2: передан объект конфигурации, в котором есть свойство "url"
          } else if (urlArgument.type === 'ObjectExpression') {
            const urlProperty = urlArgument.properties.find(
              (prop) => prop.type === 'Property' && prop.key.name === 'url'
            );
            if (urlProperty && urlProperty.value.type === 'Literal') {
              checkUrl(node, urlProperty.value);
            }
          }
        }
      },
    };
  },
};

Что здесь происходит:

  • Правило запускается на CallExpression — это вызовы функций.
  • Проверяется, что вызывается метод axios.
  • Если первым аргументом передаётся строка — она проверяется напрямую.
  • Если передаётся объект, ищется поле url, и оно проверяется.
  • Если URL не начинается с /, ESLint выдаёт ошибку и предлагает автоматическое исправление — добавление / в начало строки.

Пример использования

Чтобы подключить правило в вашем проекте с использованием Flat Config, добавьте его следующим образом:

eslint.config.js
import { defineConfig } from "eslint/config";
import axiosSlashRule from './axios-slash.rule.eslint.js';

export default defineConfig([{
  plugins: {
    'main': {
      rules: {
        'axios-slash-rule': axiosSlashRule,
      },
    },
  },
  rules: {
    'main/axios-slash-rule': 'error',
  }
}];

Теперь ESLint будет выдавать ошибку на следующий код:

axios.get('api/users');

С сообщением:

URL passed to axios instance should start with a slash

И предложит автоматически заменить на:

axios.get('/api/users');