ESLint и Prettier в TypeScript проекте

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

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

Компиляция кода TypeScript

Typescript — это расширенная версия JavaScript, которая помогает нам выполнять статическую проверку типов во время компиляции. TypeScript упростит разработку благодаря автозаполнению в вашем редакторе. TypeScript также помогает поддерживать код в больших базах кода.

Во-первых, нам нужен компилятор, который преобразует код TypeScript в JavaScript, чтобы браузер мог его прочитать. Давайте установим зависимость, используя ваш любимый менеджер пакетов.

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

#npm
npm install --save-dev typescript

#yarn
yarn add typescript --dev

После установки вы увидите новую запись в devDependencies атрибуте вашего файла package.json:

{
  "name": "Linting TypeScript with ESLint",
  "version": "1.0.0",
  "devDependencies": {
    "typescript": "^5.2.2"
  }
}

Если вы хотите убедиться, что он установлен, вы можете запустить это, чтобы проверить версию:

npx tsc --version
# Version 5.2.2

В своей папке создайте файл index.ts в каталоге src и добавьте следующий код TypeScript:

// src/index.ts
const favoriteFruits: string[] = ["apple", "strawberry", "orange"];

function addFruit(fruit: string) {
  favoriteFruits.push(fruit);
}

Мы можем скомпилировать код TypeScript в JavaScript, выполнив в терминале следующую команду:

npx tsc src/index.ts

Сразу после этого мы увидим вновь созданный файл JavaScript в том же каталоге, что и файл TypeScript:

// src/index.js
var favoriteFruits = ["apple", "strawberry", "orange"];

function addFruit(fruit) {
    favoriteFruits.push(fruit);
}

По умолчанию компилятор создает файлы JavaScript параллельно с исходным файлом TypeScript, который их создал. Это не очень хорошая идея, поскольку в конечном итоге вы смешаете результаты сборки с исходным кодом.

Итак, давайте изменим некоторые настройки компилятора по умолчанию, начиная с того, куда мы хотим поместить наш скомпилированный код, какой уровень JavaScript предназначен для передачи (по умолчанию: ECMAScript 3) и какие файлы мы хотим скомпилировать.

Существует два способа создания настроек компилятора TypeScript:

  1. Выполните в терминале следующую команду: npx tsc --init . Это создаст файл конфигурации TypeScript по умолчанию.
  2. Создайте файл tsconfig.json в корневом каталоге вашего проекта и включите ваши настройки.

В этом случае я создам настройки компилятора TypeScript вручную. Однако я бы посоветовал вам выбрать первый вариант. Будет создан файл конфигурации с некоторыми рекомендуемыми параметрами — все параметры описаны с комментариями, объясняющими, что они делают.

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

// tsconfig.json
{
  "compilerOptions": {
    "outDir": "dist", // where to put the compiled JS files
    "target": "ES2020", // which level of JS support to target
    "module": "CommonJS", // which system for the program AMD, UMD, System, CommonJS

    // Recommended: Compiler complains about expressions implicitly typed as 'any'
    "noImplicitAny": true, 
  },
  "include": ["src"], // which files to compile
  "exclude": ["node_modules"], // which files to skip
}

Поздравляем! Теперь вы можете начать писать TypeScript и компилировать его в JavaScript, запустив npx tsc.

Вы можете включить приведенную выше команду в свои сценарии, чтобы упростить ее запуск. Перейдите в package.json и добавьте флаг --watch, чтобы следить за изменениями в файлах. Имейте в виду, что все, что описано в compilerOptions, можно передать в командную строку с помощью флагов CLI:

// package.json
{
  "name": "Linting TypeScript with ESLint",
  "version": "1.0.0",
  "devDependencies": {
    "typescript": "^4.9.4"
  },
  "scripts": {
    "dev": "tsc --watch"
  }
}

Что такое линтинг?

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

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

Что такое ESLint?

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

Сначала установите следующие зависимости на свой devDependencies:

npm install eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --save-dev
  • eslint: Основная библиотека ESLint
  • @typescript-eslint/parser: парсер, который позволяет ESLint понимать код TypeScript.
  • @typescript-eslint/eslint-plugin: Плагин с набором рекомендуемых правил TypeScript.

Подобно настройкам компилятора Typescript, вы можете использовать командную строку для создания файла конфигурации с использованием флага --init ESLint или создать его вручную. В любом случае наличие файла конфигурации ESLint обязательно.

Давайте создадим файл конфигурации с помощью CLI. Запустите следующую команду в терминале:

npx eslint --init

Далее вы увидите ряд вопросов, которые позволят вам настроить файл конфигурации в соответствии с вашими предпочтениями:

  • How would you like to use ESLint?
  • What type of modules does your project use?
  • Which framework does your project use?
  • Does your project use TypeScript?
  • Where does your code run?
  • How would you like to define a style for your project?

В зависимости от выбранных параметров ESLint CLI создаст файл .eslintrc конфигурации в корневом каталоге проекта с некоторыми настройками по умолчанию. Если у вас уже есть любимые настройки, вы можете заменить некоторые параметры в файле конфигурации.

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

Линтинг с помощью ESLint

В этой статье замените настройки по умолчанию в файле конфигурации следующим:

// .eslintrc
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "plugins": ["@typescript-eslint"],
  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
  "rules": {

  },
  "env": {
    "browser": true,
    "es2021": true
  },
}
  • parser: указывает синтаксический анализатор, который ESLint будет использовать при анализе кода.
  • parserOptions: указывает, какие параметры языка JS вы хотите поддерживать, например версию синтаксиса ECMAScript, которую вы хотите использовать.
  • plugins: Здесь вы определяете используемые плагины.
  • extends: сообщает ESLint, из какой конфигурации установлено расширение. Порядок имеет значение, поскольку последний параметр расширения переопределяет предыдущие в любых конфликтующих конфигурациях.
  • env: указывает, в каких средах будет работать ваш код.

Когда мы добавляем правило ESLint, оно переопределяет конфигурацию, определенную в extends списке. Давайте добавим пару правил, чтобы увидеть, как это работает:

// .eslintrc
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 12,
    "sourceType": "module",
  },
  "plugins": ["@typescript-eslint"],
  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],

  "rules": {
    "@typescript-eslint/no-unused-vars": "error",
    // to enforce using type for object type definitions, can be type or interface 
    "@typescript-eslint/consistent-type-definitions": ["error", "type"], 
  },

  "env": {
    "browser": true,
    "es2021": true
  }
}

Короче говоря, первому правилу, которое мы применяем, присваивается значение error, но errorэто не единственное значение, которое мы можем присвоить — у нас есть три варианта:

  • off или 0: полностью отключить правило.
  • warn или 1: Считать правило предупреждением, но оно не сработает при запуске линтера.
  • error или 2: Считать правило ошибкой. Ошибка при запуске линтера

NB . В некоторых правилах ESLint, например во втором правиле, вам потребуется установить дополнительные параметры для использования синтаксиса литерала массива.

Вы можете указать ESLint проверить ваш код с помощью следующей команды: eslint --ext .js,.ts . Флаг ext используется для указания того, какие расширения файлов ESLint следует учитывать при поиске файлов в целевом каталоге. В этом случае мы включаем расширения файлов TypeScript: .ts (по умолчанию это .js)

Теперь вы можете добавить lint скрипт в свой package.json с помощью приведенной выше команды:

// package.json
{
  "name": "Linting TypeScript with ESLint",
  "version": "1.0.0",
  "scripts": {
    "dev": "tsc --watch",
    "lint": "eslint --ext .js,.ts",
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^6.7.3",
    "@typescript-eslint/parser": "^6.7.3",
    "eslint": "^8.50.0",
    "typescript": "^5.2.2"
  }
}

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

node_modules
dist

Это часто совпадает с содержимым вашего файла .gitignorelint, поэтому, чтобы иметь единый источник истины, вы можете обновить скрипт, чтобы использовать --ignore-path флаг:

// package.json
{
  // ...
  "scripts": {
    "lint": "eslint --ignore-path .eslintignore --ext .js,.ts"
   },
  // ...
}

Теперь вы готовы к работе! Мы предлагаем вам интегрировать ESLint в любой редактор, который вы используете. Если это VSCode, перейдите к расширению и установите расширение ESLint .

После того, как вы его установили и включили, вы увидите, какие ошибки вы допустили в своем коде, не запуская скрипт, подчеркнутый красной линией.

Вы увидите, что сообщение об ошибке ESLint выводится в редакторе; это еще одно расширение, называемое Error Lens , которое выделяет всю строку и сразу показывает сообщение об ошибке, вместо того, чтобы наводить указатель, чтобы увидеть его:

Сообщение об ошибке ESLint

Еще одна особенность ESLint заключается в том, что он может автоматически исправлять код при наведении курсора мыши и щелчке правой кнопкой мыши Quick fix или при нажатии command и +:

Быстрое исправление ESLint

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

npm run lint --fix
Совет : Вы можете передавать параметры, используя двойные тире --для npm скриптов, которые будут получены в качестве параметров для npm выполняющегося скрипта:
npm run <команда> [-- <аргументы> ]  

Что такое Prettier?

Prettier — известный форматировщик кода, поддерживающий множество различных языков программирования. Это помогает нам избежать ручного форматирования кода, автоматически форматируя его на основе указанного стиля кода.

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

Зачем нам Prettier с ESLint?

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

С другой стороны, форматировщик кода, такой как Prettier, обеспечивает единообразный стиль, анализируя ваш код и перепечатывая его в соответствии с его правилами. Например, вы можете указать стиль, согласно которому все операторы JavaScript должны заканчиваться точкой с запятой; средство форматирования кода автоматически добавит точку с запятой ко всем операторам без нее.

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

Интеграция

Закончив с этим, давайте добавим Prettier в наш проект. Запустите следующую команду в терминале:

npm install -- save - dev prettier

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

Вы можете просмотреть полный список параметров формата и поиграться на Prettier Playground :

// .prettierrc.json
{
  "semi": false, // Specify if you want to print semicolons at the end of statements
  "singleQuote": true, // If you want to use single quotes
  "arrowParens": "avoid", // Include parenthesis around a sole arrow function parameter
}

Далее мы начнем форматировать наш код, используя Prettier в командной строке:

npx prettier --write src/index.ts
# src/index.ts 37ms

Я добавил write флаг для перезаписи файла TypeScript, в противном случае он не будет перезаписывать его, а будет регистрировать только отформатированный код в вашем CLI.

Давайте добавим более привлекательную команду в наши скрипты, точно так же, как мы сделали это для TypeScript и ESLint. Давайте также поддержим все файлы, которые заканчиваются на .ts, .js и .json, и проигнорируем те же файлы и каталоги, что и gitignore (или вы можете создать файл .prettierignore):

// package.json

{
  // ...
  "scripts": {
    "dev": "tsc --watch",
    "lint": "eslint --ext .js,.ts .",
    "format": "prettier --ignore-path .gitignore --write \"**/*.+(js|ts|json)\""
  },
  // ...
}

Теперь вы можете запустить npm run format команду, чтобы отформатировать и исправить весь ваш код. Но что, если мы захотим отформатировать код сразу после сохранения файлов?

Это возможно! В VSCode перейдите на extensions вкладку, найдите Prettier расширение и убедитесь, что оно включено. После включения нам нужно настроить несколько вещей в VSCode.

Вы можете открыть палитру команд ( Command++ Shift) P и найти Preferences: Open User Settings (JSON) . Затем вам нужно будет изменить форматировщик вашего редактора по умолчанию и добавить дополнительную конфигурацию для кода форматирования при сохранении файлов:

// settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  ...
}

Предварительный просмотр расширения Prettier

Как избежать конфликтов при работе с ESLint и Prettier

Скорее всего, вы столкнетесь с проблемой, когда правила Prettier и ESLint перекрываются. Вы можете попробовать автоматически отформатировать свой код, но он обнаружит некоторые конфликты с ESLint.

Лучшее решение здесь — использовать eslint-config-prettier плагин для отключения всех правил ESLint, не имеющих отношения к форматированию кода, поскольку Prettier уже хорошо в этом разбирается:

npm install --save-dev eslint-config-prettier

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

// .eslintrc
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 12,
    "sourceType": "module",
  },
  "plugins": ["@typescript-eslint"],
  // HERE
  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],

  "rules": {
    "@typescript-eslint/no-unused-vars": "error",
    "@typescript-eslint/consistent-type-definitions": ["error", "type"],
  },

  "env": {
    "browser": true,
    "es2021": true
  }
}

Вот и все! Теперь вы знаете, как эффективно использовать эти инструменты статического тестирования. Замечательно иметь некоторую автоматизацию для конкретных задач, таких как анализ, форматирование и проверка типов.

ESLint против Prettier

Ниже приведено общее сравнение ключевых различий и целей, которым служат ESLint и Prettier:

Подводя итог, ESLint и Prettier служат разным целям в разработке JavaScript. В то время как ESLint фокусируется на обеспечении соблюдения стандартов и шаблонов кодирования, обнаружении проблем с качеством кода и выявлении ошибок, Prettier фокусируется на автоматическом форматировании кода для обеспечения согласованности.

Заключение

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