Если вы рассматриваете запросы на исправление или создаете программное обеспечение в команде, пользовательские правила eslint могут сэкономить вам много времени. Вот как это делается.
Слаженность команды > личные предпочтения
Спагетти-код. Каждый из нас хотя бы раз в своей карьере слышал это слово. Код, который настолько запутан, что из него невозможно извлечь какой-то смысл. Даже если выясняется, что это мы его написали.
Сложность программирования — не единственная проблема, с которой сталкиваются команды разработчиков. Поймите, разработка — ремесло, и это очень личное. Со временем у каждого из нас вырабатываются свои личные предпочтения, как мы называем переменные, делаем отступы в коде или где ставим скобки. И как только вы начинаете работать с кем-то еще, эти предпочтения могут стать причиной множества проблем и заставить вас потерять много драгоценного времени.
Если каждый разработчик в команде будет фиксировать код, написанный в соответствии со своими предпочтениями, то в итоге вы получите беспорядок, который трудно поддерживать. Пересмотр кода и исправление чего-либо в коде, написанном кем-то другим, отнимает все больше и больше времени. Документирование приложения превращается в кошмар. И так вся кодовая база превращается в кошмар, к которому никто не хочет прикасаться.
Некоторые команды придумывают руководства по кодированию, что является отличным первым шагом к обеспечению согласованности. Однако если это документ, который необходимо выполнять вручную, он быстро окажется на полке, покрытый паутиной. Рекомендации по кодированию — это замечательно, но вы должны иметь возможность применять их автоматически. Давайте будем реалистами, никто не будет просматривать всю вашу кодовую базу после рефакторинга, чтобы убедиться, что все соответствует. Особенно, если у вас сжатые сроки.
Если вы создаете приложения на JavaScript/TypeScript, eslint — отличный способ обеспечить соблюдение стилей кодирования. По мере набора текста вы получаете мгновенные уведомления о том, что не так и как это исправить. Существует множество предустановленных правил, которые можно использовать в качестве отправной точки. Тем не менее, вы действительно выиграете, если внедрите в eslint специальные рекомендации вашей команды.
Согласованность кода на практике: CLI для Microsoft 365
Я являюсь одним из мейнтейнеров CLI для Microsoft 365 — инструмента командной строки с открытым исходным кодом, который помогает управлять проектами Microsoft 365 и SharePoint Framework на любой платформе. Он встроен в TypeScript и работает на Node.js.
Мы работаем над CLI для Microsoft 365 уже 3,5 года. С помощью еженедельных бета-релизов было отгружено достаточно много кода. Почти 6 500 файлов. При этом у нас накопился некоторый технический долг, который постепенно устраняется с каждым крупным релизом. Все для того, чтобы обеспечить стабильную работу для наших пользователей.
CLI для Microsoft 365 — это проект с открытым исходным кодом, и у нас есть несколько замечательных участников. Все они из разных организаций, команд и имеют разные предпочтения в кодировании. Но наша задача — следить за тем, чтобы все изменения, которые они вносят, были синхронизированы с нашей кодовой базой. С течением времени некоторые из участников приходят и уходят. Мы — мейнтейнеры — остаемся в проекте и поддерживаем его. Часто нам или другим необходимо вернуться к чужому коду и что-то изменить. А поскольку это проект с открытым исходным кодом, над которым многие работают в свободное время, нужно сделать это быстро.
Изначально мы начали с контрольного списка для проверки PR. И до сих пор им пользуемся. Он содержит наиболее важные вещи, которые нужно проверять для каждого PR. Но он не охватывает всего. И если PR — это огромный рефакторинг, то считается, что все вроде бы хорошо, если он создан и тесты пройдены. Реалии жизни. Чтобы исправить это, мы решили использовать eslint.
Решение использовать eslint мы приняли по двум основным причинам. Хотелось повысить согласованность кода с помощью форматирования и именования, а также автоматизировать проверку кода по нашему контрольному PR списку. Для решения первой задачи мы использовали стандартные правила, поставляемые с eslint, настроенные под наши нужды. Для второй мы создали собственные правила. Вот как это сделать.
Создание пользовательского правила для eslint
eslint — это линтер, который использует правила для проверки определенных аспектов вашего кода. Он идеально подходит для обеспечения обратной связи в реальном времени для кода, который вы пишете, и проверки его соответствия вашим рекомендациям по кодированию. Вы также можете включить его в CI/CD-канал, чтобы убедиться, что все PR соответствуют вашим рекомендациям.
Основы пользовательских правил описаны на сайте eslint. Вот некоторые вещи, которые я узнал, создавая их для CLI Microsoft 365.
Проверьте имя класса команд CLI для Microsoft 365
Чтобы проверить, можно ли использовать eslint в CLI для Microsoft 365, мы провели одну из первых проверок, которые выполняются в процессе ревью PR: убедитесь, что имя класса команды соответствует соглашению об именовании ServiceCommandNameCommand
, например, AadAppAddCommand
. Файлы команд в CLI для Microsoft 365 организованы в папки, и мы определяем правильное имя класса для каждой команды на основе расположения ее файлов.
Настройка плагина eslint с пользовательскими правилами
eslint поддерживает пользовательские правила с помощью плагинов. Плагин eslint - это пакет npm. И это первая проблема, которую нам нужно было решить. Мы не видели смысла в поддержке отдельного пакета npm с набором правил, специфичных для CLI Microsoft 365, который никто больше не будет использовать. К счастью, оказалось, что вполне удобно создать его в подпапке и из нее в корневом проекте установить npm-пакет.
Поскольку со временем мы, вероятно, будем добавлять больше правил, то решили организовать их так, чтобы каждое было расположено в отдельном файле.
Следуя требованиям eslint, каждое правило затем экспортируется в переменную rules в файле index.js.
module.exports.rules = {
'correct-command-class-name': require('./rules/correct-command-class-name'),
'correct-command-name': require('./rules/correct-command-name')
};
index.js указывается как основная точка входа пакета плагина в package.json:
{
"name": "eslint-plugin-cli-microsoft365",
"version": "1.0.0",
"main": "lib/index.js"
}
Последнее, что осталось сделать для подключения правила к eslint, это добавить его в коллекцию rules в .eslintrc.js корневого проекта:
module.exports = {
// [...] trimmed for brevity
"plugins": [
"@typescript-eslint",
"cli-microsoft365"
]
"rules": {
"cli-microsoft365/correct-command-class-name": "error"
// [...] trimmed for brevity
}
// [...] trimmed for brevity
}
Это была самая сложная часть - настроить все и увидеть, как пользовательское правило применяется в процессе линтинга. Как только это было сделано, я перешел к созданию самого правила.
Определение селектора правила
При создании правил eslint вам нужно указать им, какой узел в файле кода они должны исследовать. Это можно сделать, указав селектор.
Для правила, которое проверяет имя класса команды, я использовал ClassDeclaration
. Для другого правила, которое проверяет имя const, содержащего фактическое имя команды, понадобился более сложный селектор: MethodDefinition[key.name = "name"] MemberExpression > Identifier[name != "commands"]
. Использование селекторов не является тривиальным и требует понимания того, как код переводится в абстрактные синтаксические деревья. AST Explorer - это отличный ресурс, позволяющий увидеть, как ваш код переводится в AST с помощью eslint.
Выбор правильного селектора важен, поскольку он позволит вам минимизировать объем кода, необходимого для исследования узла. Также необходимо помнить, что селектор будет применен ко всему файлу. Если eslint найдет несколько совпадений, он будет выполнять правило для каждого совпадения.
Сделайте ваше правило поддающимся исправлению
При создании пользовательских правил eslint следует сделать их автоматически исправляемыми. Когда мы ввели правило именования классов команд в CLI, то обнаружили, что десятки команд используют несогласованные имена. Вместо того чтобы исправлять их вручную одну за другой, мы воспользовались eslint, который исправил эти имена за нас!
Чтобы сообщить eslint о том, что ваше правило можно исправить, в метаданных правила установите свойство fixable
в code.
module.exports = {
meta: {
type: 'problem',
docs: {
description: 'Incorrect command class name',
suggestion: true
},
fixable: 'code'
// [...] trimmed for brevity
}
// [...] trimmed for brevity
}
Затем в коде правила, когда вы обнаружили, что оно нарушено, сообщите о фактическом узле, который следует исправить. Это может быть непросто!
При проверке имени класса команды я использовал селектор ClassDeclaration
, который дает мне доступ к узлу объявления класса с такой информацией, как имя класса, родительский класс, является ли класс абстрактным и так далее. Но если бы я сообщил об этом узле просто как о месте, которое нужно исправить, eslint заменил бы весь блок класса только правильным именем класса! Поэтому вместо этого при сообщении об узле сбоя мне нужно указать node.id, который является узлом, содержащим имя класса.
if (actualClassName !== expectedClassName) {
context.report({
node: node.id,
messageId: 'invalidName',
data: {
actualClassName,
expectedClassName
},
fix: fixer => fixer.replaceText(node.id, expectedClassName)
});
}
Резюме
Если вы работаете над проектом вместе с другими разработчиками, сохранение согласованности кодовой базы поможет вам работать быстрее. Чем больше ваша организация и многочисленнее команда разработчиков, тем важнее обеспечить согласованность кода. Если вы создаете приложения на JavaScript или TypeScript, стандартный набор правил eslint — отличное начало. Добавление пользовательских правил, соответствующих рекомендациям вашей команды, действительно поможет вам автоматизировать проверку кода, сэкономить время и обеспечить согласованность кода.
Материал подготовлен в рамках курса «JavaScript Developer. Basic». Всех желающих приглашаем на открытый практический урок «Тесты и TDD в работе javascript разработчика». Мы разберем на примере, как писать тесты и следовать подходу TDD. >> РЕГИСТРАЦИЯ