ESLint | Shareable config настройка и что это такое?
Приветствую! В ходе своей профессиональной деятельности, каждый фронтенд-разработчик сталкивается с неотъемлемой частью разработки - инструментом ESLint. ESLint представляет собой мощный статический анализатор кода, призванный обнаруживать и устранять проблемы в вашем JavaScript коде.
Сегодня мы поговорим, о настройке shareable config. Мы рассмотрим, как это может помочь продуктовым командам или фрилансеру разработчику, а далее перейдем к настройке этой конфигурации.
Shareable Config: Когда это надо?
Представьте себе ситуацию, в которой у вас имеется несколько кроссфункциональных команд, занимающихся разработкой различных продуктов компании, но при этом использующих cхожий технологический стек. В таком контексте возникает необходимость в единых стандартах и подходах к написанию кода, чтобы обеспечить единый стиль разработки. В данном случае на помощь приходит инструмент ESLint.
После того как были согласованы наборы правил, назначены ответственные за их реализацию и настройку, начинается этап реализации в проектах. Однако, при возникновении необходимости внести изменения в конфигурацию ESLint, многократное редактирование всех проектов может быть трудозатратным и неэффективным. Именно в таких ситуациях на помощь приходит создание Shareable config для ESLint и его последующая публикация в репозитории пакетов, таких как npm или других пакетных реестрах
Преимущества создания и использования Shareable config:
Единое правило: Создавая Shareable config, вы устанавливаете единый набор правил для всех проектов. Это обеспечивает согласованный стиль кода и снижает вероятность возникновения ошибок, связанных с разнообразными конфигурациями.
Централизованное управление: Если вам необходимо внести изменения в правила ESLint, вы можете внести их в Shareable config, и эти изменения автоматически применятся ко всем проектам, использующим эту конфигурацию. Это значительно упрощает управление и поддержку кодовой базы.
Снижение затрат: Вместо того чтобы править конфигурации в каждом проекте, вы вносите изменения только в Shareable config и публикуете его. Это экономит время и уменьшает затраты на обслуживание.
Публичная доступность: Публикация Shareable config в пакетном реестре позволяет другим командам и разработчикам использовать вашу конфигурацию. Это способствует распространению фронтенд стандартов и позволяет другим внедрять их в свои проекты.
Инициализация конфигурации проекта
Давайте создадим папку eslint-config-test
и создадим модуль с ограниченной областью действия. Используем команду npm init --scope=@test
и пройдемся по шагам установки.
В итоге мы получим файл, на основе этого:
{
"name": "@test/eslint-config-test",
"version": "1.0.0",
"description": "ESLint Shareable Config",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"eslint",
"share",
"config"
],
"author": "Kim Valentin",
"license": "ISC"
}
Здесь важно отметить @test
- scope npm модуля, более подробно в документации
Сюда по степени необходимости можно добавить еще несколько опциональных свойств: "files", "repositry","bugs", "dependencies", "devDependencies", "peerDependencies" и другие. О каждом более подробно можно узнать в документации
Я добавил пару пакетов для работы конфига (их не нужно будет ставить в основном проекте, кроме peerDependencies):
"dependencies": {
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"@vue/eslint-config-typescript": "^12.0.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-vue": "^9.17.0"
},
"devDependencies": {
"eslint": "^8.50.0",
"typescript": "~5.2.2"
},
"peerDependencies": {
"eslint": ">= 8.50.0",
"typescript": ">= 5.0.0"
}
Создание модуля конфигурация
Здесь все достаточно просто мы создаем модуль для будущего использования с расширением .js
. Например, у меня вышел такой модуль:
module.exports = {
root: true,
env: {
es6: true,
browser: true,
node: true,
},
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:vue/vue3-recommended',
'@vue/eslint-config-typescript',
'airbnb-base',
],
parserOptions: {
parser: require.resolve('@typescript-eslint/parser'),
extraFileExtensions: ['.vue'],
ecmaVersion: 'latest',
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
globals: {
JSX: true,
},
plugins: ['@typescript-eslint'],
rules: {
semi: ['error', 'never'],
'no-param-reassign': 'off',
'no-void': 'off',
'no-nested-ternary': 'off',
'max-classes-per-file': 'off',
'linebreak-style': 0, // ignore linebreak-style
'no-plusplus': 'off',
'max-len': ['error', {
code: 255,
ignoreComments: true,
}],
'vue/block-order': ['error', {
'order': [ [ 'script', 'template' ], 'style' ]
}],
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error', { ignoreTypeReferences: true }],
'no-underscore-dangle': 'off',
'no-shadow': 0,
'@typescript-eslint/no-shadow': 0,
'new-cap': ['error', { newIsCap: false }],
'import/first': 'off',
'import/named': 'error',
'import/namespace': 'error',
'import/default': 'error',
'import/export': 'error',
'import/extensions': 'off',
'import/no-unresolved': 'off',
'import/no-extraneous-dependencies': 'off',
'import/prefer-default-export': 'off',
// 'prefer-promise-reject-errors': 'off',
quotes: ['warn', 'single', { avoidEscape: true }],
// this rule, if on, would require explicit return type on the `render` function
'@typescript-eslint/explicit-function-return-type': 'off',
// in plain CommonJS modules, you can't use `import foo = require('foo')` to pass this rule, so it has to be disabled
'@typescript-eslint/no-var-requires': 'off',
// The core 'no-unused-vars' rules (in the eslint:recommended ruleset)
// does not work with type definitions
'no-unused-vars': 'off',
// allow debugger during development only
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'@typescript-eslint/member-delimiter-style': ['error', {
multiline: {
delimiter: 'none',
requireLast: true,
},
singleline: {
delimiter: 'comma',
requireLast: false,
},
multilineDetection: 'brackets',
}],
'@typescript-eslint/no-explicit-any': 'warn',
},
}
Публикация пакета
Пару шагов и мы создали с вами наш конфиг. Далее мы можем опубликовать пакет в npm или package registry Gitlab. Настроить CI и использовать.
P.S. Если вы решили использовать package registry Gitlab, у вас будет несколько вариантов, либо настроить publishConfig в package.json
и ssh ключ в CI. Либо использовать такую конструкцию:
"devDependencies": {
"@test/eslint-config-test": "git+ssh://user@host/path/eslint-config-test#branch"
}
Использование пакета
Необходимо на проекте установить нужные зависимости (peerDependencies). Далее можно создать файл .eslintrc.cjs
если еще у вас его не было. И там использовать ваш пакет.
module.exports = {
extends: [
'@test/eslint-config-test',
],
}
Вы также можете указать дополнительные правила, которые перезапишут ваш конфиг, и будут применяться локально к текущему проекту.
Заключение
Пора подводить итоги, если вы раньше таскали ваш файл настроек и перекидывали с одного проекта на другой, то данная статья вам поможет. Всего немного вашего времени, и вы сделаете дополнительную автоматизацию, которая позволит модифицировать ваши правила для написания кода в едином месте.
Если вам интересно больше технического контента, немного лайва из жизни молодого тимлида, добро пожаловать в мой телеграмм канал