eslint-plugin-structural-police

1.1.5 • Public • Published

RU | EN

structural-police

eslint plugin для контроля структуры файлов и импортов

Установка

npm i eslint-plugin-structural-police

Быстрый старт

// .eslintrc.[js|yml|json]

{
    "plugins": [
        // ... какие-то твои плагины
        "structural-police"
    ],
    "extends": [
        // ... какие-то твои конфиги плагинов
        
        // один из конфигов
        "plugin:structural-police/recommended"
        // или
        "plugin:structural-police/featureSliced"
    ],
}

Правила плагина


import-order

Настройка

Правило import-order принимает 8 аргументов:

  1. groups:array of object - Массив групп импортов (подробнее в пункте "Группы")
  2. behaviorRelatedComment:string - Вариант поведения комментариев, находящихся непосредственно перед импортов при использовании функции автофикса (флаг --fix). При значении link (default value) все комментарии перемещаются вместе с импортом. При значении remove все комментарии удаляются
  3. blankLineAfterEveryGroup:boolean - Нужно ли после каждой группы импортов вставлять пустую строку (default value: false)
  4. groupNamePrefix:string - Префикс необходимый, чтобы отличать обычные комментарии от названий групп импортов (default value: ' # '). Например: // # GroupName
  5. oldGroupNamePrefix:string - Префикс, необходимый при изменении настройки groupNamePrefix, чтобы удалить названия групп со старым префиксом
  6. withinGroupSort:array of string - Массив строк формирующих регулярные выражения, в порядке которых будут сортироваться пути импортов внутри групп. То есть передав ['^([A-Z]|[a-z])', '^[.]'] внутри группы будут идти сначала импорты начинающиеся с букв, а потом - с точки. При использовании этой настройки все импорты внутри группы будут отсортированы по алфавиту. Если нужно включить только сортировку по алфавиту, то нужно передать массив с одной регуляркой - ['^']
  7. customErrorMessages:object - Объект с колбэками, формирующими тексты ошибок (подробнее в пункте "Кастомные сообщения ошибок")
  8. optimizedFix:boolean - Если true (default value: false), то в начале файла добавляется ошибка аккумулятор, которая содержит фикс функцию, устраняющую все ошибки данного правила за один проход линта. Рекомендуется использовать при запуске с флагом --fix, чтобы не запускать скрипт несколько раз для устранения всех ошибок

Группы

У каждого объекта группы есть 5 параметров:

  • name. Если есть name, то перед этой группой необходим комментарий с названием группы
  • priority отвечает за приоритет разбора импортов по группам. То есть если импорт удовлетворяет условиям двух групп, то он будет размещен в групу с наивысшим приоритетом (default value: 1)
  • blankLineAfter отвечает за наличие пустой строки после группы (default value: false)
  • importPathMatch содержит регулярное выражение или строку для формирования регулярного выражения (без флагов), по которому проверяется импортируемый путь
  • importAbsPathMatch содержит регулярное выражение или строку для формирования регулярного выражения (без флагов), по которому проверяется абсолютный путь до импортируемого файла. То есть находясь в файле src/feature/index.ts и импортируя из ../ui/form.ts, по регулярному выражению importAbsPathMatch будет проверяться путь src/ui/form.ts

Пример

groups: [
   {                  priority: 0, importPathMatch: /^/,         blankLineAfter: true },
   { name: 'actions', priority: 2, importAbsPathMatch: /Action/, blankLineAfter: false },
   { name: 'stores',  priority: 2, importAbsPathMatch: /Store/ },
   { name: 'styles',  priority: 1, importPathMatch: /.css$/,     blankLineAfter: true },
]

Кастомные сообщения ошибок

Если есть желание изменить тексты ошибок выбрасываемых линтом, то можно сделать это, передав в аргумент customErrorMessages объект со своими колбэками. В правиле есть три типа ошибок mustBeAfter, blankLineDetected, blankLineExpected, needAddComment и needRemoveComment, каждый из которых вызывается при разных проблемах:

  1. mustBeAfter вызывается, если нарушен порядок импортов
  2. blankLineDetected вызывается, если обнаружена лишняя пустая строка между импортами
  3. blankLineExpected вызывается, если после группы с blankLineAfter нет пустой строки
  4. needAddComment вызывается, если перед группой с name нет комментария с названием
  5. needRemoveComment вызывается для неправильных названий групп

Ниже приведен объект с дефолтными колбэками, тут же можно посмотреть какие аргументы должны принимать колбэки

const defaultErrorMessages = {
   mustBeAfter: ({ importPath, mustBeAfterImportPath }) =>
      `This import must be after import from "${mustBeAfterImportPath}"`,
      
   blankLineDetected: ({ importPath, groupName }) =>
      `Must not be blank line after import from "${importPath}"`,
      
   blankLineExpected: ({ importPath, groupName }) =>
      `Need blank line after imports group "${groupName}"`,
      
   needAddComment: ({ groupName, newComment }) =>
      `Before imports group "${groupName}" must be comment with groups name "${newComment}"`,
      
   needRemoveComment: () => 
      `Need remove wrong groups name`,
}

import-permission-schema

Настройка

Правило import-permission-schema принимает 5 аргументов:

  1. schema:object - Схема валидации импортов (подробнее в пункте "Схема")
  2. inheritance:boolean - Наследование правил. Если у дочернего узла нет собственных правил, то будут применены правила ближайшего родителя
  3. entryPoints:array of string - Массив путей до валидируемых файлов
  4. everywhereAllowed:array of string - Массив путей до файлов, импорт которых всегда доступен
  5. customErrorMessages:object - Объект с колбэками, формирующими тексты ошибок (подробнее в пункте "Кастомные сообщения ошибок")

Схема

Схема описывает структуру проекта, по которой линтер будет проверять корректность расположения файлов и возможность осуществления импортов.

В схеме могут использоваться 3 ключех слова:

  1. __rules__ - В данном объекте линтер будет искать правила для конкретного узла схемы
  2. __any__ - Разрешает любую структуру дочерниих файлов. Если __any__ установлен true, то линтер прекращает поиск правил глубже по схеме и применяет ко всем вложенным файлам уже найденые правила, если такие были
  3. __var__<variable_name> - При помощи такой конструкции можно обобщить несколько разноименных директорий с одинаковой внутренней структурой, чтобы исключить дублирование в схеме. Например в директории apps у нас лежит три приложения app-a, app-b и app-c. Если у первых двух одинаковая структура, то схему можно составить следующим образом:
apps: {
    'app-c': {
        // Какая-то схема
    },
    __var__similar_apps: {
        // Какая-то другая схема
    },
},

В данном случае проверка будет происходить следующим образом:

Поиск правил для файла apps/app-c/index.ts: Зашли в apps, зашли в app-c, нашли правила для index.ts

Поиск правил для файла apps/app-a/index.ts: Зашли в apps, не нашли объект app-a, поэтому зашли в первый попавшийся __var__<variable_name>, если такой есть

Кастомные сообщения ошибок

Если есть желание изменить тексты ошибок выбрасываемых линтом, то можно сделать это, передав в аргумент customErrorMessages объект со своими колбэками. В правиле есть три типа ошибок importDisallow, missingFile и missingRules, каждый из которых вызывается при разных проблемах:

  1. importDisallow вызывается, если в файле найден импорт из запрещенного правилами (схемой) источника
  2. missingFile вызывается, если проверяемый файл не описан в схеме
  3. missingRules вызывается для проверяемого файла в схеме не найдены правила

Ниже приведен объект с дефолтными колбэками, тут же можно посмотреть какие аргументы должны принимать колбэки

const defaultErrorMessages = {
   importDisallow: ({ filePath, importPath, absoluteImportPath }) =>
      `Not allowed to import from "${absoluteImportPath}"`,
   
   missingFile: ({ schemaPath, missingNode }) =>
      `The file is not described in the schema. In "${schemaPath}" expected a node "${missingNode}"`,
   
   missingRules: ({ schemaPath }) =>
      `There is no set of rules in the "${schemaPath}"`,
}

Правила

Правила можно передать в любой узел схемы под ключем __rules__. Правила содержат 3 необязательных ключа:

  1. defaultAllowed:boolean - Импорт со всех адресов разрешен, если true. Запрещен, если false (default value: true)
  2. allowed:array of string - Массив разрешенных адресов для исключения из defaultAllowed = true
  3. disallowed:array of string - Массив запрещенных адресов для исключения из defaultAllowed = false

!!! Важно !!!

  1. На одном уровне вложенности может быть только одно ключевое слово __var__<variable_name>
  2. __var__ переменные не должны повторяться
  3. Если в узле отсутствуют правила и аргумент inheritance выставлен на false (отключено наследование правил), то это приведет к ошибке

!!! Интересно !!!

Переменные, указанные при составлении дерева файлов можно использовать в написании правил.

apps: {
    __var__similar_apps: {
        featuers: {},
        shared: {},
    },
},

В нашей схеме есть переменная <similar_apps>, полученная при указании ключевого слова __var__ вместо названий приложений app-a, app-b. И мы хотим разрешить импорт из shared в featuers, но только в рамках одного приложения (то есть в app-b/featuers нельзя сделать импорт модуля из app-a/shared). Настроить такие ограничения можно разместив следующие правила в объекте features

__rules__: {
    defaultAllowed: false,
    allowed: [
        'apps/__var__similar_apps/shared',
    ],
},

Логика проверки путей работает таким образом, что она вместо __var__ переменных подставит узлы, из пути проверяемого файла. То есть находясь в файле apps/app-a/featuers/index.ts переменная __var__similar_apps, используемая в правилах будет заменена на app-a, а находясь в apps/app-b/featuers/index.ts - на app-b. Проще говоря, переменная __var__<variable_name> - это текущая директория для каждого файла


no-default-export

Правило no-default-export запрещает использование дефолтных экспортов

Package Sidebar

Install

npm i eslint-plugin-structural-police

Weekly Downloads

2

Version

1.1.5

License

MIT

Unpacked Size

86.4 kB

Total Files

17

Last publish

Collaborators

  • tontoncher