Статья·  

Обновленная интеграция Nuxt ESLint

Мы переработали наши интеграции ESLint для поддержки ESLint v9 с flat config, а также новый модуль с гораздо большими возможностями.

TL;DR

Мы переделали наши интеграции ESLint для поддержки ESLint v9 с новым flat config. Попутно мы изучили множество новых возможностей, чтобы сделать ее более персонализированной, мощной и с лучшим опытом для разработчиков.

Вы можете выполнить следующую команду, чтобы установить новый @nuxt/eslint модуль:

Terminal
npx nuxi module add eslint

Продолжайте прочтение статьи или узнайте больше с помощью документации.

Справочная информация

ESLint стал незаменимым инструментом в современной веб-разработке. Он помогает отлавливать ошибки и обеспечивать последовательный код стайл в проекте. В Nuxt мы делаем все возможное, чтобы обеспечить ESLint «из коробки», облегчая его использование, настройку и следование лучшим практикам, которые мы рекомендуем.

С тех пор и Nuxt, и ESLint претерпели значительные изменения. Исторически сложилось так, что в итоге мы получили несколько различных пакетов и интеграций для ESLint в Nuxt, и не всегда было понятно, какой из них для чего использовать. Мы получили много отзывов от нашего сообщества.

Чтобы улучшить ситуацию, а также сделать ее безопасной для будущего, мы недавно обновили наши интеграции ESLint, чтобы они поддерживали ESLint v9 с плоским конфигом. Это открывает гораздо больше возможностей для настройки вашего ESLint, обеспечивая более простой и унифицированный опыт.

Nuxt ESLint монорепозиторий

Мы перенесли пакеты, связанные с ESLint, разбросанные по разным репозиториям, в один монорепозиторий: nuxt/eslint, с выделенным новым сайтом документации: eslint.nuxt.com.

Чтобы помочь разобраться в различиях между каждым пакетом и понять, какой из них использовать, мы также создали страницу FAQ, где сравниваем их и объясняем сферы их применения.

Этот монорепо теперь включает в себя:

  • @nuxt/eslint - Новый, универсальный модуль ESLint для Nuxt 3, поддерживающий flat config ESLint с учетом проекта и многое другое.
  • @nuxt/eslint-config - Не описываемый, но настраиваемый общий конфиг ESLint для Nuxt 3. Поддерживает как flat config, так и унаследованный формат.
  • @nuxt/eslint-plugin - Плагин ESLint для Nuxt 3 обеспечивает правила и конфигурации, специфичные для Nuxt.
  • Два пакета для Nuxt 2 в режиме обслуживания.

ESLint flat config

Прежде чем погрузиться в новые интеграции Nuxt, позвольте мне познакомить вас с концепцией ESLint flat config.

Flat config - это формат конфигурации, представленный в ESLint v8.21.0 как экспериментальный, и ставший форматом по умолчанию в ESLint v9.

Краткое руководство по дифференциации:

  • Flat config: eslint.config.js eslint.config.mjs etc.
  • Legacy config: .eslintrc .eslintrc.json .eslintrc.js etc.

Почему Flat Config?

Эта запись в блоге ESLint подробно объясняет мотивацию flat config. Вкратце, унаследованный формат eslintrc был разработан в ранние времена JavaScript, когда модули ES и современные возможности JavaScript еще не были стандартизированы. В нем задействовано множество неявных соглашений, а функция extends делает конечный результат конфигурации трудно понять и предсказать. Это также делает общие конфигурации сложными для поддержки и отладки.

.eslintrc
{
  "extends": [
    // Solve from `import("@nuxtjs/eslint-config").then(mod => mod.default)`
    "@nuxtjs",
    // Solve from `import("eslint-config-vue").then(mod => mod.default.configs["vue3-recommended"])`
    "plugin:vue/vue3-recommended",
  ],
  "rules": {
    // ...
  }
}

Новый flat config переносит разрешение плагинов и конфигураций с внутренней конвенции ESLint на собственное разрешение модуля ES. Это, в свою очередь, делает его более явным и прозрачным, позволяя вам даже импортировать его из других модулей. Поскольку flat config - это просто модуль JavaScript, он также открывает возможности для гораздо большей кастомизации.

Пресеты Nuxt для Flat Config

В последнем пакете @nuxt/eslint-config мы используем имеющуюся гибкость, чтобы предоставить factory функцию, которая позволяет вам легко настраивать предустановки конфигурации более высокоуровневым способом. Вот пример того, как ее можно использовать:

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt()

@nuxt/eslint-config начинается с базового конфига, не имеющего ограничений, что означает, что мы включаем только правила для лучших практик TypeScript, Vue и Nuxt, а остальное, например, стиль кода, форматирование и т.д., оставляем на ваше усмотрение. Вы также можете запустить Prettier рядом для форматирования с настройками по умолчанию.

Конфиг также позволяет подключать более важные функции по мере необходимости. Например, если вы хотите, чтобы ESLint заботился и о форматировании, вы можете включить его, передав features.stylistic в factory функцию (на основе ESLint Stylistic):

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    stylistic: true
  }
})

Или настройте свои предпочтения с помощью объекта опций узнать больше с помощью опций можно здесь:

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    stylistic: {
      semi: false,
      indent: 2, // 4 или 'tab'
      quotes: 'single',
      // ... и остальное
    }
  }
})

А если вы автор модуля Nuxt, вы можете включить features.tooling, чтобы включить правила для разработки модуля Nuxt:

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  features: {
    tooling: true
  }
})

...и т. д. Функция фабрики в flat config позволяет предустановкам покрывать сложность базовой конфигурации ESLint и предоставлять высокоуровневые и удобные абстракции для настройки конечными пользователями. И все это без необходимости беспокоиться о внутренних деталях.

Несмотря на то, что такой подход позволяет получить Prettier-подобный опыт с минимальными конфигурациями (поскольку он основан на ESLint), вы все равно получаете полную гибкость в настройке и переопределении тонких правил и плагинов по мере необходимости.

Мы также сделали утилиту FlatConfigComposer из eslint-flat-config-utils, чтобы еще больше упростить переопределение и расширение flat config. Функция фабрики в @nuxt/eslint-config/flat возвращает экземпляр FlatConfigComposer:

eslint.config.js
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'

export default createConfigForNuxt({
  // ...опции для интеграции с Nuxt
})
  .append(
    // ...добавьте другие элементы flat config
  )
  .prepend(
    // ...добавить другие элементы flat config перед базовой конфигурацией
  )
  // переопределить конкретный элемент конфигурации на основе его имени
  .override(
    'nuxt/typescript', // укажите имя целевой конфигурации или индекс
    {
      rules: {
        // ...переопределить правила
        '@typescript-eslint/no-unsafe-assignment': 'off'
      }
    }
  )
  // и так далее, операции являются цепочечными

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

Nuxt ESLint модуль

Развивая эту идею, мы создали новый универсальный модуль @nuxt/eslint для Nuxt 3. Он использует контекст Nuxt для генерации конфигураций ESLint с учетом проекта и безопасности типов для вашего проекта.

Правила, ориентированные на проект

Мы знаем, что руководство по стилю Vue предлагает использовать многословные имена для компонентов, чтобы избежать конфликтов с существующими и будущими элементами HTML. Таким образом, в eslint-plugin-vue у нас по умолчанию включено правило vue/multi-word-component-names. Это хорошая практика, но мы знаем, что в проекте Nuxt не все файлы .vue регистрируются как компоненты. Такие файлы, как app.vue, pages/index.vue, layouts/default.vue и т.д. не доступны в качестве компонентов в других файлах Vue, и правило для них будет неактуально.

Обычно мы можем отключить правило для этих файлов следующим образом:

eslint.config.js
export default [
  {
    files: ['*.vue'],
    rules: {
      'vue/multi-word-component-names': 'error'
    }
  },
  {
    files: ['app.vue', 'error.vue', 'pages/**/*.vue', 'layouts/**/*.vue'],
    rules: {
      // отключите правило для этих файлов
      'vue/multi-word-component-names': 'off'
    }
  }
]

Это должно работать в большинстве случаев. Однако мы знаем, что в Nuxt вы можете настраивать путь для каждой директории, а слои позволяют вам иметь несколько источников для каждой директории. Это означает, что правила линтера будут менее точными и потенциально заставят пользователей прилагать дополнительные усилия, чтобы выровнять их вручную.

Аналогично, мы хотим, чтобы vue/no-multiple-template-root был включен только для pages и layouts, и т.д. По мере роста числа случаев становится нереальным просить пользователей поддерживать правила вручную.

Вот тут-то и приходит на помощь магия @nuxt/eslint! Он использует контекст Nuxt для генерации конфигураций и правил, специфичных для структуры вашего проекта. Очень похоже на .nuxt/tsconfig.json, который предоставляет Nuxt, теперь у вас также есть проектно-ориентированный .nuxt/eslint.config.mjs для расширения.

Чтобы использовать его, вы можете добавить модуль в свой проект Nuxt:

Terminal
npx nuxi module add eslint

Интеграция инспектора конфигурации DevTools

Во время миграций и исследований нового flat config мне пришла в голову идея сделать интерактивный UI-инспектор для flat config и сделать конфигурации более прозрачными и простыми для понимания. Мы интегрировали его в Nuxt DevTools, когда у вас установлен модуль @nuxt/eslint, так что вы легко получите к нему доступ, когда он вам понадобится.

Скриншот инспектора конфигурации ESLint, запущенного как вкладка в Nuxt DevTools

Инспектор позволяет увидеть окончательно решенные конфигурации, правила и плагины, которые были включены, а также выполнить быстрое сопоставление, чтобы увидеть, как правила и конфигурации были применены к определенным файлам. Он отлично подходит для отладки и изучения того, как ESLint работает в вашем проекте.

Мы рады, что команда ESLint также находит его полезным и заинтересована в том, чтобы он был доступен для более широкого сообщества ESLint. Мы присоединились позже и помогли сделать его официальным инспектором конфигурации ESLint (кстати, он построен на Nuxt). Вы можете прочитать этот анонс для получения более подробной информации.

Генерация типов для правил

Одной из главных проблем при настройке ESLint была утечка информации о типе правил и конфигураций. Трудно понять, какие опции доступны для конкретного правила, и чтобы это выяснить, приходится перерывать всю документацию по каждому правилу.

Еще раз спасибо за то, что новый плоский конфиг стал динамическим с таким количеством возможностей. Мы придумали новый инструмент, eslint-typegen, который может генерировать соответствующие типы из схемы конфигурации правил для каждого правила на основе фактических плагинов, которые вы используете. Это означает, что это универсальное решение, которое работает для любых плагинов ESLint, и типы всегда точны и актуальны.

В модуле @nuxt/eslint эта функция интегрирована из коробки, так что вы сразу же получите этот потрясающий опыт:

Скриншот кода VS Code, демонстрирующий проверку типов и автозаполнение с помощью конфигурации правил ESLint

Программа проверки сервера разработчиков

С появлением нового модуля мы воспользовались возможностью объединить @nuxtjs/eslint-module и программу проверки сервера разработчиков для ESLint в новый модуль @nuxt/eslint в качестве опциональной возможности.

В большинстве случаев эта возможность вам не понадобится, так как интеграция с вашим редактором уже должна предоставлять диагностику ESLint прямо в вашем редакторе. Однако для некоторых команд, которые работают с разными редакторами и хотят, чтобы ESLint всегда был запущен, возможность запускать ESLint внутри dev-сервера может быть полезной в некоторых случаях.

Чтобы включить эту функцию, вы можете установить опцию checker в значение true в опциях модуля:

nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@nuxt/eslint'
  ],
  eslint: {
    checker: true // <---
  }
})

При возникновении ошибок ESLint вы увидите предупреждение в консоли и браузере. Чтобы узнать больше об этой функции, вы можете ознакомиться с документацией.

Хуки модуля

Поскольку теперь мы находимся в модуле Nuxt с возможностями codegen и конфигурациями, учитывающими проект, мы можем делать гораздо больше интересных вещей. Во-первых, мы можем позволить модулям вносить вклад в конфигурации ESLint. Представьте, что в будущем, когда вы установите модуль Nuxt, например, @nuxtjs/i18n, он сможет автоматически включать определенные правила ESLint для файлов, связанных с i18n, или когда вы установите что-то вроде @pinia/nuxt, он сможет установить плагин Pinia ESLint, чтобы внедрить лучшие практики для Pinia, и т.д.

В качестве эксперимента мы сделали модуль nuxt-eslint-auto-explicit-import, который может делать автоматические вставки для автоимпортов, зарегистрированных в вашем проекте Nuxt с предварительно настроенным ESLint пресетом. Таким образом, вы можете получить тот же приятный опыт разработчика с автоимпортами при использовании API, но при этом иметь автовставку явных импортов в вашей кодовой базе.

Это все еще находится на ранних стадиях, и мы продолжаем изучать возможности и лучшие практики. Но мы очень рады этому потенциалу и возможностям, которые он открывает. Мы будем сотрудничать с сообществом, чтобы понять, как извлечь из этого максимум пользы. Если у вас есть идеи или отзывы, пожалуйста, не стесняйтесь делиться ими с нами!

Экосистема

В Nuxt мы, как всегда, очень заботимся об экосистеме и сообществе. Во время наших исследований по внедрению новой плоской конфигурации и улучшению опыта разработчиков, мы создали довольно много инструментов для достижения этой цели. Все они имеют общее назначение и могут использоваться вне Nuxt:

  • @eslint/config-inspector - Официальный инспектор конфигураций ESLint, предоставляет интерактивный пользовательский интерфейс для ваших конфигураций.
  • eslint-typegen - Генерирует типы TypeScript для правил ESLint, основываясь на фактических плагинах, которые вы используете.
  • eslint-flat-config-utils - Утилиты для управления и составления плоских конфигураций ESLint.

Мы стремимся поддерживать широкое сообщество и сотрудничать с разработчиками для улучшения этих инструментов и расширения их возможностей. Нам не терпится увидеть, как эти инструменты могут принести пользу экосистеме ESLint и способствовать общему улучшению работы разработчиков.

Планы на будущее

Формат плоских конфигураций все еще довольно новый, а ESLint v9 был выпущен всего пару недель назад. Плагины и сообщество постепенно осваивают новый формат. Он все еще находится на стадии изучения и экспериментов.

Заглядывая в будущее, мы с нетерпением ждем, как будет развиваться экосистема ESLint и как мы сможем использовать новые возможности и способности для дальнейшего расширения возможностей разработчиков Nuxt. Мы стремимся обеспечить бесшовную и мощную среду разработки для пользователей Nuxt, и мы будем продолжать изучать новые идеи и сотрудничать с сообществом для достижения этой цели.

← Вернуться к блогу