Открыть список
Как стать автором
Обновить
31
Карма
0
Рейтинг

Пользователь

Putout: линтер нового поколения

На всех проектах, которых я работал, ворнинги не использовались никогда :). И так получалось, что не имело значения: это фронт на angular/react, бэк на node.js, либо больше 200-та npm-пакетов. Правило либо исправляется, либо отключается до лучших времен — все просто. В статье об этом было сказано для того, что бы показать фундаментальные отличия в философии инструментов.


По-поводу того, что не просто пофиксить автоматически, конечно, не все возможно исправить, для тех моментов, которые исправить нельзя есть code review, и если это действительно важно, то вся команда об этом напомнит.


Однако, если разработчику удобнее с ворнингами и это делает код лучше, а работу продуктивнее — то, пожалуйста, это личный выбор каждого :).


С помощью плагина eslint-plugin-putout возможно использовать ESLint с привычными ворнингами совместо с Putout, который исправить может все, что найдет, при этом показывая только ошибки.

Putout: линтер нового поколения

Плюсы в этом подходе безусловно есть, однако у Putout подход диаметрально противоположный: вместо того, что бы закидывать 100 сообщений (которые разработчики очень быстро перестанут читать, захлебнувшись в потоке информации, ибо слишком много информации = 0 информации), берет и исправляет то что нашел, либо не исправляет и молчит :).


Еще есть возможность написать кодмод, который будет в автоматизированном режиме править deprecated методы, гораздо более простым способом, чем делая это с помощью ESLint. Такой подход, например, применяется для правил Putout, с помощью плагина @putout/plugin-putout.


Идея в сдвиге парадигмы: вместо того, что бы заставлять человека переделывать код — пишется скрипт, который исправит все места сразу без всяких ворнингов.

Автоматизируем переход на React Hooks

А можно ли назвать такой подход автоматизацией, если в обязательном порядке нужно проверять код?

Да можно.


плагин @putout/plugin-react-hooks, представляет собой базовую реализацию, которую можно развивать для поддержки нужных условий.

Если вас заинтересовала тема автоматизированного рефакторинга, вы так же можете написать интересующие правила, пул реквесты приветствуются.

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

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

Автоматизируем переход на React Hooks

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


Вы забываете, что есть еще кастомные хуки, вроде описанного Деном Абрамовым useInterval, в них можно сложить многие описанные вами проблемы, такие как useEffect, useMemo и прочее, взгляните на примеры с usehooks. Опять же, статья не о том, зачем нужны хуки, а том как автоматизировать рефакторинг, на примере хуков.

Автоматизируем переход на React Hooks

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


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

Я же предлагаю третий вариант: автоматизировать. Я согласен, что React Hooks, это не мажорное изменение, и можно ничего не трогать. Ну так вас никто и не заставляет. Если все устраивает в старом подходе, а новый не подходит, конечно, ненужно ничего менять. Но если так получается, что не устраивает, то почему бы не автоматизировать переход? И использовать однородные компоненты по всей кодовой базе, а не какие придется.

Автоматизируем переход на React Hooks

По-поводу де-оптимизации, согласно документации реакта, оптимизировать, в том числе, используя useCallback, имеет смысл лишь в случае падения производительности, и в большинстве случаем это ни на что не повлияет. Вы занимаетесь преждевременной оптимизацией используя useCallback везде. Прежде чем оптимизировать, имеет смысл делать замеры. Возможно такая оптимизация ни на что не повлияет.

Автоматизируем переход на React Hooks

На данном этапе разработки в любом случае стоит просмотреть результат выполнения преобразования, конечно не стоит слепо комитить и деплоить приложение. Попробуйте установить putout вместе с плагином, прописать конфиг и попробовать на простых компонентах, и будете знать, что как работает. Если вас заинтересовала тема автоматизированного рефакторинга, вы так же можете написать интересующие правила, пул реквесты приветствуются. Поймите правильно, без фидбека пользователей, для меня не было никакого смысла реализовывать все возможные кейсы :). Если комьюнити не нуждается в поддержке преобразований такого рода, гораздо лучше узнать об этом на ранних стадиях разработки. То же самое, и в обратном случае: если многие загорятся идеей, все быстро начнет продвигаться.

Автоматизируем переход на React Hooks

PureComponent проигнорирует, а shouldComponentUpdate удалит. Используя приемы описанные в статье, поддержку и того и другого легко добавить.

Автоматизируем переход на React Hooks

Для этого стоит написать новые правила, плагин @putout/plugin-react-hooks, представляет собой базовую реализацию, которую можно развивать для поддержки нужных условий.

Автоматизируем переход на React Hooks

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

Автоматизируем переход на React Hooks

Для простоты изложения и наглядности, из всего что касается React Hook'ов использовалась лишь функция useState. useCallback можно будет добавить в будущем. Статья описывает способ, с помощью которого это можно реализовать, а архитектура плагина состоящая из достаточно простых правил к этому стимулирует.

Практическое применение трансформации AST-деревьев на примере Putout

Для babel 5-ой версии параллельный обход всеми плагинами был штатным способом.
И был отдельный ключ(не помню для CLI, или babelRc), который гонял плагины последовательно
И в сложных плагинах(когда замена производилась не для текущей ноды) паралельный обход создавал трудности

Это действительно создает трудности, в прочем, для putout в данный момент времени, мало смысла в паралельной обработке, поскольку, работает он достаточно быстро, и разрабатывается на компьютере, на котором прирост скорости от использования redrun имеет огромное значение, если учесть что для большинства пользователей ускорение оказалось не особо ощутимым, putout у них будет летать :). В прочем, в случае медленной работы у пользователей, можно будет подумать об ускорении. Что вы скажете о скорости? У вас быстро файлы трансформируются?


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

Как выглядел этот апи? Я не нашел об этом информации.

Практическое применение трансформации AST-деревьев на примере Putout

Eslint умеет исправлять ошибки, хотя его API и несколько ограничено/непривычно по сравнению с трансформациями babel

API Eslint значительно более ограничены и ориентированы в основном на форматирование, в то время как babel содержит, например такую удобную вещь как template, что значительно упрощает создание новых узлов.


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

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


Плагин сам вызывает traverse. Тут есть и плюсы и минусы:
  1. Каждый плагин выполняет свой traverse, что медленнее чем один комбинированный traverse, выполненый ядром

Да, это действительно медленее, вы уверены, что babel и eslint объединяют параметры всех визиторов и обходят их за один проход? В этом может быть смысл. Идея каждому плагину использовать свой traverse возникла при разработке плагина remove-unused-variables, принцип работы сводится к тому, что бы найти все переменные, и определить использовались они или нет, после чего те которые использовались откидываются. Для того, что бы выполнить такую операцию необходимо обойти все AST-дерево сперва. После чего фильтровать. Если плагин будет предоставлять только опции обхода, он не сможет узнать, что обход дерева закончен.


  1. Трансформации делаются последовательно, и не могут конфликтовать с другими плагинами.
    Параллельные трансформации — не самая легкая в разработке и отладке вещь.

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


2.1. Но и взаимодействовать они также не могут, и их работа зависит от порядка. Например если сперва вызывается плагин удаляющий пустые блоки, а только потом удаление debugger/console.log, после чего могут остаться пустые блоки, которые уже не будут удалены

Есть идея во-время исправлений проходить по коду до тех пор, пока не будут исправлены все ошибки (либо до какого-то количества раз, например 10), как это реализовано в eslint. Сейчас же, если после одного прохода putout останется что исправить, его можно будет вызвать еще раз, и он улучшит ситуацию.

Ускоряем npm-скрипты

и запись у вас не полная — пути до istanbul и mocha потерялись

В этих путях нет смысла, они добавляются в переменную окружения PATH во-время запуска npm-скриптов.

Ускоряем npm-скрипты

Действительно очень длинно, такую команду в любом случае стоит упростить. Сделать это можно добавив пару секций в package.json:


{
  "config": {
    "mocha": "--reporter spec test",
    "istanbul": "-x test --dir=./build/coverage --report=lcov --hook-in-context",
  },
  "scripts": {
    "coverage" : "istanbul cover $npm_config_istanbul _mocha -- $npm_config_mocha"
  }
}

После чего скрипт можно запускать с помощью:


redrun coverage

либо


npm run coverage

Ускоряем npm-скрипты

Redrun разворачивает секцию скриптов, за счет чего увеличивается скорость по сравнению с npm и npm-run-all. Этот частный случай интересует пользователей npm-скриптов, для которых важны: скорость, удобство и совместимость с существующими решениями — то о чем автор думает достаточно часто.

Ускоряем npm-скрипты

В redrun v5.5.0 добавлена поддержка автодополнения названий скриптов по табу аналогичную той, что используется в npm. Для установки достаточно выполнить:


redrun-completion >> ~/.bashrc
redrun-completion >> ~/.zshrc

Ускоряем npm-скрипты

Мне даже кажется, что в данном случае make будет лучше, чем redurn, потому что самому make на линуксах ничего устанавливать не надо, он там и так стоит, а рэдран надо.

Make есть на линуксах, но не на Windows.


Просто конфиги свои берёт не из специального файла, а из package.json, который по идее должен быть в node-проектах. Да, умно брать конфиги от туда, эта идея хороша, но не нова.

Не свои конфиги, а конфиги npm. Redrun в этом плане совместим с npm, и ничего нового не привносит.


Я хочу попросить сравнить скорость redrun и make, если не затруднит, сделайте пожалуйста.

У redrun и make разные цели. Redrun разворачивает npm-скрипты, и запускает получившуюся команду. Make автоматизирует процесс преобразования файлов из одной формы в другую, у него свой формат, и возможности гораздо шире, чем у redrun, но в его штатную поставку не входит чтение и исполнение npm-скриптов, скорее он предлагает писать скрипты в Makefile. Этот подход не хуже, он может быть быстрее, но он кардинально отличается от используемого в redrun а именно: использование существующих скриптов, а не написание новых.


Я не владею make и мне не близка его философия, поэтому я не смогу сделать такое сравнение.

Ускоряем npm-скрипты

Спасибо, поддержка $npm_package_version добавлена в v5.4.0.

Ускоряем npm-скрипты

Действительно, этого не хватает. Нужно будет подумать об этом.

Информация

В рейтинге
5,939-й
Зарегистрирован
Активность