Статический анализ кода

Как заставить компьютер проверять ваш код.

Время чтения: меньше 5 мин

Кратко

Скопировано

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

Самый популярный линтер для JavaScript — это ESLint. Он находит участки кода, которые могут потенциально привести к ошибкам, и сообщает об этом.

Как пользоваться

Скопировано

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

        
          
          npm install --save-dev eslint
          npm install --save-dev eslint

        
        
          
        
      

После установки нужно инициализировать конфигурационный файл .eslintrc.json:

        
          
          npx eslint --init
          npx eslint --init

        
        
          
        
      

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

        
          
          {  // ...  "extends": "eslint:recommended",  // ...}
          {
  // ...
  "extends": "eslint:recommended",
  // ...
}

        
        
          
        
      

Теперь можно добавить в package.json новый скрипт, который будет запускать статический анализ:

        
          
          {  // ...  "scripts": {    "lint": "eslint ./**/*.js"  }  // ...}
          {
  // ...
  "scripts": {
    "lint": "eslint ./**/*.js"
  }
  // ...
}

        
        
          
        
      

После запуска линтера командой npm run lint, в консоли появится результат его работы.

Для наглядности положим в папку проекта JavaScript-файл с ошибками, которые ESLint способен отловить.

        
          
          // script.jsconst x = 12// Сравнения с -0 запрещены стандартной конфигурацией ESLint// При запуске он выведет ошибкуif (x === -0) {  console.log('Hello!')}
          // script.js

const x = 12

// Сравнения с -0 запрещены стандартной конфигурацией ESLint
// При запуске он выведет ошибку
if (x === -0) {
  console.log('Hello!')
}

        
        
          
        
      

Как понять

Скопировано

Линтер — это программа, которая разбирает исходный код на стандартизированные кусочки, а потом даёт эти кусочки на проверку специальным плагинам. Плагин получает разобранный участок кода и проверяет его на корректность по ряду правил, которые определены в этом плагине.

Советы линтера — это не абсолютная истина. Скорее подсветка спорных моментов, на которые стоит обратить внимание.

Типичные проблемы, которые отлавливают линтеры:

Например, функцию parseFiles():

        
          
          async function parseFiles(files) {  const data = []  // parseFile будет вызываться последовательно  // сначала будет обработан первый файл  // потом второй, третий и так далее  for (const file of files) {    const parsed = await parseFile(file)    data.push(parsed)  }  return data}
          async function parseFiles(files) {
  const data = []

  // parseFile будет вызываться последовательно
  // сначала будет обработан первый файл
  // потом второй, третий и так далее
  for (const file of files) {
    const parsed = await parseFile(file)
    data.push(parsed)
  }

  return data
}

        
        
          
        
      

Линтер может предложить переписать так:

        
          
          async function parseFiles(files) {  // parseFile вызовется для всех файлов почти одновременно  const data = await Promise.all(files.map((file) => parseFile(file)))  return data}
          async function parseFiles(files) {
  // parseFile вызовется для всех файлов почти одновременно
  const data = await Promise.all(files.map((file) => parseFile(file)))

  return data
}

        
        
          
        
      

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

Статический анализатор работает только с исходными текстами программы, но никогда не запускает само приложение. Поэтому, не все проблемы можно отловить линтингом. Статический анализ — это отличное дополнение к другим способам проверки кода: код-ревью, юнит и интеграционным тестам.

На практике

Скопировано

Игорь Камышев советует

Скопировано

Линтер для CSS

Скопировано

На самом деле, статически проанализировать можно почти любой язык программирования. Поэтому, при разработке веб-приложений часто не останавливаются на использовании ESLint, а добавляют ещё Stylelint — линтер для стилей. Он умеет работать не только с CSS, но и почти с любым языком описания стилей, например, CSS-in-JS, SCSS или Stylus.

Автоматический запуск

Скопировано

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

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