Pull to refresh

Comments 32

Форматирование листингов поехало

А можно эту же статью на английском? Я бы своим показал.

Александр, привет! Да, закидываем контент-отделу в задачки, как будет готово — опубликуем и дадим ссылку.

И спасибо за идею: как будете в районе Таганки в Москве, пишите, угостим чем-нибудь)
Прочитал статью, сначала подумал о том, что надо б пойти возмутиться о том, что предлагается грести весь код под одну гребенку; но уже через десяток минут подумал, что плюсов от этого практически всегда будет больше, чем минусов.

Ну и пошел включил prettier у себя в репах, до кучи. Это занимает сильно меньше 20 минут, если линтер уже есть.
UFO just landed and posted this here
я такой же подход использую для php в связке codesniffer + pre commit hook.
Почему pre-commit?
Имхо, гораздо удобнее post-save.
Например для VSCode есть плагин такой.
Меня, например, крайне раздражает, когда код у меня переформатируется в что-то еще прямо перед глазами. Build / pre-commit — самый нейтральный вариант, когда изменения обязательно применятся, но не обязательно сию секунду.
Pre-commit работает у всей команды, а хуки у каждого индивидуально
Работали с Prettier в паре проектов, первое время восхищались, потом начало раздражать, что при изменении пары символов в коммите часто меняется по 10 строк и пулл-реквесты становятся нечитаемыми. Кроме того, часто бывает более выразительно написать в одном месте, скажем, разреженно, а в другом — компактно. В итоге в последних проектах от Prettier отказались. А вообще, странно видеть обзорную статью про проект двухлетней (или больше) давности, раньше на хабре такое минусовали.
Кроме того, часто бывает более выразительно написать в одном месте, скажем, разреженно, а в другом — компактно.

// prettier-ignore

А вот если вам постоянно нужно это куда-то писать — это повод задуматься о причинах. Исключения, подтверждающие правила, хороши только тогда, когда это и вправду исключения, а не когда под их соусом пытаются пропихнуть своё особое мнение.
Цель Prettier сделать код красивым и выразительным. Это не что-то критичное для проекта и, в добавок, довольно субъективное. Конструкции вроде prettier-ignore создают шум в коде и рассеивают внимание разработчика, что противоречит изначальной цели сделать код выразительным. Я иногда работаю с коллегами из Индии и других южных стран, со всеми вытекающими, так там использование Prettier может быть оправдано, так как люди косячат на пустом месте каждый день и снизить деструктив от них хотя бы на уровне синтаксических соглашений будет полезно. Но когда вы работаете в опытной команде людей, которые не косячат — Prettier играет роль того самого джуна, который услышал о лучшей практике и пытается пихать её везде, уместно и не уместно, создавая больше шума, чем пользы.
Мой тезис в том, что если в 2020-м человек о таких инструментах никогда не слышал — вероятно он и есть джун, и использование Prettier для него будет в пользу. Но я против практики навязывания этого инструмента как обязательного или как бесспорно хорошей практики.
Цель Prettier сделать код красивым и выразительным.

Это не цель. «О вкусах не спорят». Цель prettier — привести весь код к констистентному виду. Можете это прямо с их сайта прочитать. Именно поэтому у prettier минимум опций, и они не собираются это менять.

Этого же можно добиваться и линтером, но линтеры наоборот тяготеют к полному конфигурированию каждого чиха, из-за чего с ними во-первых долго возиться, а во-вторых — применив парочку более сомнительных оформительских правил, можно вызвать бурные протесты внутри команды. В prettier экзотического форматирования нет вовсе, а по основным случаям можно не соглашаться, но это явно не случаи разряда «вижу такое форматирование — и аж аппетит портится, а рука сама выводит заявление по собственному».

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

Когда я работаю в команде опытных людей — я всё так же предпочитаю не раздражаться, увидев в коде «if() {» вместо «if () {». Вы можете сказать «ну так не раздражайся, и пиши у себя как надо, а читай чужой код с ледяным спокойствием», но в итоге это выливается в бесполезный шум в коммитах (если я буду править чужой if, я машинально добавлю пробел, а мой коллега, пробел не любящий — будет править, и уберет пробел), и служит вялотлеющим источником конфликтов.
Согласен, что вкусы у всех разные, это не суть. Больше претензий вызывает когда строка кода становится из длинной короткой или из короткой длинной. Prettier старается её разбить или наоборот сжать, хотя иногда разница пара символов. Подобные инициативы автоматики портят читаемость пулл-реквестов, когда человек поменял число 25 на 115, а ощущение будто пол класса переписал. Кроме того часто бывает такое, когда Prettier как раз портит консистентность, в примерах вроде такого:
const { short, line } = this.props;
const {
  longLongLineElement1,
  longLongLineElement2
} = this.state;

когда одни инструкции получаются развернутыми, а другие сжатыми, хотя они могут быть очень близки и структурно, и идейно, и даже по длине (например, 79 и 81 при максимуме стрики 80). Да, в 95% случаев Prettier срабатывает корректно, и только в 5% промахивается. Но когда работаешь в команде, где в 99% люди пишут верно — от Prettier с его промахами больше вреда.

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

при изменении пары символов в коммите часто меняется по 10 строк и пулл-реквесты становятся нечитаемыми

А почему такое происходит? Вы используете prettier вместе с lint-staged, только для изменённых файлов? В такой ситуации можно однократно прогнать весь код через форматтер, закоммитить, и тогда все будущие коммиты не будут содержать лишних изменений

Prettier переносит строки в зависимости от длинны. Иногда увеличение\уменьние длины строки на пару символов попадает на брейкпоинт и происходит переформатирование.

А какие тут могут быть варианты? Если строка получается слишком длинная, руками разработчик бы сделал то же самое

Работаю front-end разработчиком, всегда код форматирую в последнюю очередь с помощью настроенной gulp сборки и потом отправляю на коммит и никаких проблем.
prettier реально напрягает в работе в реальном времени

Использую Prettier почти три года и могу сказать, что у него есть свои плюсы и минусы, как и у любого другого инструмента.


Порой Prettier совсем невнятно форматирует код или форматирование может зависеть от любопытных хаков. Например год назад я предложил вот такой https://github.com/prettier/prettier/issues/1974#issuecomment-385277713, правда теперь он уже не нужен, так как по итогам обсуждения обновили правила форматирования и теперь оно такое, какое я и хотел, по-дефолту))). Не всегда изменения, сделанные им, удобно просматривать в diff-ах.


Но в то же время, даже если не использовать Prettier как основной форматтер, он довольно удобен для форматирования вспомогательных файлов. Markdown, JSON, Yaml, вот это вот все. Я на проектах использую его вместе с ESLint и вполне доволен. Кстати ESLint еще может определять и частично исправлять всякие дурацкие ошибки, поэтому в плане чистоты кода пользы от него намного больше. Prettier предназначен исключительно для форматирования кода, и хотя его и пытаются иногда притянуть на проект в качестве линтера, это неправильно. Но вместе они позволяют на ревью обсуждать действительно важные вещи: что и как этот код делает, а не всякую фигню, вроде отсутствия/наличия пробелов в каких-то конструкциях.


Так что Prettier вполне успешно можно использовать в качестве форматтера поверх линтеров, а также для файлов, для которых линтер не особо нужен, а вот форматирование было бы выдерживать неплохо. При этом на проекте будет стайлгайд "prettier-like". Если Prettier чем-то не понравился (например ньюансами как в https://habr.com/ru/company/skyeng/blog/484992/#comment_21186642), помимо него есть еще куча "zero config" решений: xo, Lynt например. Можно тот же ESLint использовать и для форматирования с каким-нибудь популярным готовым набором правил, от airbnb например. Какой бы инструмент не был бы выбран, на хуки гита его можно повесить с одинаковым успехом и он так же перед коммитом поправит форматирование кода. Стайлгайд только будет немного отличаться. Но что останется неизменным — так это то, что стиль кода внутри проекта будет одинаковым. Чего собственно и добивались, и это экономит силы и нервы людей на проекте. Удачного code review!

Не в первый раз слышу о проблемах с форматированием кода при code review

Мы сделали так. В CI на гитабе подключили в том числе прогон линтером. Тесты просто не проходят если есть какое-то форматирование отличное от того что задано линтером.

Ну и понятно — пока тест красный — код можно даже и не смотреть. Разве что написать реквестеру — что тесты не прошли.
UFO just landed and posted this here
И не надо каждому настраивать разные pre-commit хуки и прочее. Все делается централизованно админом.
Так что prettier пока не особо и нужен. Каждый форматит код руками как хочет — но в рамках общих правил. Если что — правила всегда можно скорректировать.
Проверил сейчас автоформат Prettier'а в Atom: не всегда работает гладко, приходится проверять, что он там наформатировал. Например, сложные миксины LESS превращает в дикую кашу, а закрывающие скобки иногда переносит в конец закомментированных строк.
По итогу — годится причесывать небольшие файлы, которые можно сразу отсмотреть, или куски кода (хотя «формат выделенного» игнорирует отступы вокруг), а вот проходиться им по большому проекту я бы стал с крайней осторожностью. Ну и Format on save точно не стоит использовать.

Вместо кода типа:


  public listenDndForFocusEvents(channel: string): Observable<boolean> {
    return this.drag.pipe(
      filter(event => event.channel === channel),
      filter(event => event instanceof DndDragStartEvent || event instanceof DndDragEndEvent),
      map(event => event instanceof DndDragStartEvent),
    );
  }

Я всегда наблюдал что-то вроде:


  public listenDndForFocusEvents(
     channel: string
  ): Observable<
   boolean
   > {
    return this.drag.pipe(
      filter(event => event.channel === channel),
      filter(
        event => 
           event instanceof DndDragStartEvent || 
           event instanceof DndDragEndEvent
      ),
      map(event => event instanceof DndDragStartEvent),
    );
  }

Чего стоят if-ы вроде:


if(
  exp1 &&
  exp 
) {
// ....
}

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

Так в Prettier тоже есть опция printWidth, можно там выставить значение побольше, чем дефолтные 80

Более того, там можно выставить значение даже чуть побольше, чем согласованная ширина (выставленная у разработчиков в IDE), чтоб prettier не резал бы маниакально превышение на символ.
Хотя в доках prettier пишут, что эту ширину стоит выставлять поменьше, я пришел к строго обратному выводу: стоит выставлять побольше.
Sign up to leave a comment.