Раньше я думал, что иметь индивидуальный стиль кодирования это хорошо для программиста. Это показывает, что вы опытный разработчик, который знает, как должен выглядеть хороший код.
В колледже мои преподаватели говорили, что они понимают, когда мои однокурсники используют мой код в своих работах из-за особого стиля кодирования. Сейчас я думаю, что они понимали это потому, что мой код был по крайней мере хоть как-то отформатирован, в то время как у других была полная неразбериха.
С тех пор я потратил много времени, рассуждая о стиле кодирования и выбирая инструменты для его осуществления. Настало время что-то менять.
Несколько примеров
После прочтения “The Programmers’ Stone”, я еще долгое время ставил скобки таким образом:
if (food === 'pizza')
{
alert('Pizza ;-)');
}
else
{
alert('Not pizza ;-(');
}
Но потом я понял, что я, наверное, единственный, среди пользователей, кто так делает. Все остальные придерживаются этого стиля:
if (food === 'pizza') {
alert('Pizza ;-)');
} else {
alert('Not pizza ;-(');
}
Или этого
if (food === 'pizza') {
alert('Pizza ;-)');
}
else {
alert('Not pizza ;-(');
}
Так что я поменял свой стиль на вышеупомянутый.
Мне очень нравится использовать этот стиль для создания цепочек:
function foo(items) {
return items
.filter(item => item.checked)
.map(item => item.value)
;
}
На мой взгляд, это также способствует рефакторингу в случае перемещения запятых:
const food = [
'pizza',
'burger',
'pasta',
]
Но, наверное, в использовании этого стиля я даже более одинок, нежели в случае со скобками.
Никто никогда не пришлет мне на проверку код с использованием этого стиля, никакой инструмент контроля качества кода не заставит их это сделать. Так что мне пришлось прекратить использовать его, чтобы быть ближе к реальному миру.
Есть еще кое-что, что никто кроме меня не делает. Я всегда использую двойной пробел перед комментарием в конце строки.
const volume = 200; // ml
Я думал, это улучшает читабельность кода. Но, на самом деле, это делает кодовую базу несогласованной, потому что остальные разработчики ставят только один пробел.
Что делают разработчики JavaScript
К сожалению, у JavaScript нет официального стиля кодирования. Есть несколько популярных стилей написания кода, таких как Airbnb или Standard. Вы можете использовать их для того, чтобы ваш код выглядел знакомым для других разработчиков.
Вы можете использовать ESLint, чтобы задавать стиль кодирования и даже проводить автоформатирование кода. Но это не сделает вашу кодовую базу на 100% согласованной. ESLint c конфигурацией Airbnb упорядочат только первый мой первый пример и создадут противоречия в двух других.
Что должны делать разработчики JavaScript
В некоторых языках есть строгие стили кодирования, а также инструменты для форматирования кода. Таким образом, разработчики не тратят время на рассуждения о стиле кодирования. Взгляните на Refmt для Reason или на Rustfmt для Rust.
Кажется, что у JavaScript наконец-то имеется решение этой проблемы. Новый инструмент под названием Prettier переформатирует ваш код в соответствии со своими правилами. Он совершенно не учитывает изначальный вид кода.
Давайте опробуем работу Prettier на моих примерах:
if (food === 'pizza') {
alert('Pizza ;-)');
} else {
alert('Not pizza ;-(');
}
function foo(items) {
return items.filter(item => item.checked).map(item => item.value);
}
const volume = 200; // ml
Вы можете оспорить этот стиль. Мне, например, не нравится размещение
else
, сомнения вызывает также написание функциональной цепи в одну строку. Однако я вижу огромные преимущества во внедрении Prettier’а:- нечего даже обсуждать — у Prettier’а несколько опций;
- никаких споров о конкретных правилах, если вы работаете в команде;
- вашим напарникам не нужно изучать стиль кодирования вашего проекта;
- нет нужды исправлять стилевые ошибки, о которых сообщает ESLint;
- есть возможность установить сохранение автоформата.
Заключение
Prettier уже используется некоторыми популярными проектами, такими как React или Babel. И я начинаю переделывать свои проекты, отходя от своего привычного стиля кодирования, в пользу Prettier’a. Я бы порекомендовал использовать его вместо стиля кодирования Airbnb.
В начале моей работы с Prettier’ом было много моментов, когда я думал “фу, это ужасно”. Но когда я думаю, что мне нужно было бы, например, вручную форматировать код JSX из однострочного вида в многострочный, если я добавляю еще один prop и это не умещается в одну строку — тогда я понимаю, что оно абсолютно точно стоит того.
Prettier форматирует ваш код, когда вы сохраняете файл.
Прочитайте, как внедрить Prettier в свой проект.
P.S. Посмотрите на мое новое средство, которое упростит добавление ESLint, Prettier и других инструментов в ваш проект, а также хранение и синхронизацию их настроек.
Перевод выполнен при поддержке компании EDISON Software, которая профессионально занимается разработкой сайтов на Amiro.CMS и WordPress и для крупных заказчиков.
Комментарии (60)
dolphin4ik
18.10.2017 17:52+2Так же работаю с Prettier, но заметил, что эта штука не до конца понимает чейны и уж слишком разворачивает объекты конфигураций json
MrGobus
18.10.2017 18:56Спасибо, не надо.
<div className="HelloWorld" title={`You are visitor number ${num}`} onMouseOver={onMouseOver} >
(из официального примера)
zagayevskiy
18.10.2017 18:58+1Придерживаемся такого стиля в форматировании xml в Android. Сначала было непривычно, потом стало норм. Особых минусов нет.
gibson_dev
19.10.2017 09:01+3очень удобный стиль — когда надо добавить или удалить свойство — просто добавь или удали строку, да и в jsx свойств может быть очень много
myxo
18.10.2017 19:03Единственное, что меня смущает в а автоматических форматтерах — то, что они не могут распознавать случаи, когда программист сам выставляет пробелы для форматирования. Они их убирают и код наоборот становится нечитаемым.
justboris
18.10.2017 22:16Для таких случаев можно поставить коммент prettier-ignore. Prettier оставит форматирование этого куска как и было:
// prettier-ignore matrix( 1, 0, 0, 0, 1, 0, 0, 0, 1 );
VladlenBronislav
18.10.2017 19:40+1В Java стиль чистого кода появился с лёгкой руки Боба (Robert Martin), и не говоря про JavaCodeConvention.
Возможно, и у JavaScript появиться свой евангелист…
ameli_anna_kate
18.10.2017 22:15Так привыкла писать код с определенными стилевыми правилами, что уже делаю это на автомате.
Кода вижу что-то вроде этого:
function getTotalPrice(sum){ var price=sum || 0, tax = 5; price+= tax; var delivery = 3; if(price<10) price += delivery; return price; }
Не могу удержаться и не переписать с «правильными» пробелами, скобками и тд:
function getTotalPrice(sum) { var price=sum || 0, tax = 5, delivery = 3; price += tax; if (price < 10) { price += delivery; } return price; }
Есть главы в книгах Стефанова «JavaScript. Шаблоны » и у Крокфорда «JavaScript. Сильные стороны»(где он про JSLint пишет) рекомендации как оформлять код.Idot
19.10.2017 12:40+1Было бы лучше, так:
function getTotalPrice(sum) { var price = sum || 0, tax = 5, delivery = 3; price += tax; if (price < 10) { price += delivery; } return price; }
justboris
19.10.2017 13:26+2нет, пожалуйста, не надо! Нет ничего хуже, чем центрирование кода относительно знака равенства.
Потом придется добавить еще одну переменную с именем подлиннее, и придется переформатировать весь блок кода, создавая большой diff и потенциальные merge-конфликты.
justboris
18.10.2017 22:23нечего даже обсуждать — у Prettier’а несколько опций;
Это не совсем правда. Опций немного, но они очень холивароспособствующие.
Есть опции для отступов табами вместо пробелов, установки точек с запятой или нет, одинарных кавычек вместо двойных. Пространство для холивара имеется, пусть и не такое большое, как при настройке Eslint.
playaaa
19.10.2017 22:14+1Несовсем понятно, с чего вдруг холивару начатся — как техлид сказал код оформить, так все и сделали, точка. Никакого холивара, все заняты работой, а не ерундой.
Про development standards никогда не слышали? Простой документ с элементарным набором правил по разработке (включающий, но не ограниченный, naming conventions и тем самым форматированием), который почетно вручается каждому программеру, пришедшему на проект/в компанию. Тому, кто не блюдет — по шапке. Проблемы?justboris
19.10.2017 22:24Странно, если все так легко, то отчего же спор "табы против пробелов" до сих пор не закончился? Сходили бы все разработчики к мудрейшему техлиду, и узнали у него как надо.
Но почему-то так не происходит, а любой пост на эту тему набирает немало комментариев, например, вот этот.
playaaa
20.10.2017 00:49Все это происходит по той же причине, по которой некоторые "работники" на рабочем месте проводят меньше времени, чем возле кофе-машины и в курилке — видимо заниматься ерундой гораздо важнее, чем совместно добиваться успешного выполнения поставленной задачи. И это уже проблема не отдельно взятого техлида, а менеджмента проекта, а то и компании в целом. Рыба гниет с головы и о корпоративной культуре недаром написаны книги. Если подобные вещи Вам не кажутся очевидными, то этот разговор окончен — мне Ваш опыт, как представителя по-видимому низшей лиги, неинтересен.
johnnymmc
18.10.2017 23:27Есть мысль, что возможно следовало бы просто учитывать это всё в самом языке.
Например вот сейчас в Питоне можно написать
def f(a, b, c): pass
а можно
def f(a, b, c): pass
или даже
def f(a, b, c): pass
и в случае длинного (зачастую из-за названий параметров, указания дефолтных значений, типов и т.п.) списка параметров приходится прибегать ко второму или третьему варианту, но в случае короткого используют первый.
Не лучше ли было бы, если бы второй или что-то типа него было бы единственно разрешённым? Разнообразие в этом лично мне кажется «untidy», а третий вариант (который зачастую выбирают IDE при автоматическом форматировании) как по мне и вовсе исчадие «ада перфекциониста».
Ни в коем случае не настаиваю и сам не уверен, просто подумалось, решил вынести на суд коллективного разума.Idot
19.10.2017 10:45def f(a, b, c): pass
— хороший вариант, если нет комментариев
def f(a, b, c): pass
— плохой вариант, если нет комментариев, но, который легко превращается в очень хороший, если добавить комментарии
def f(a, # комментарий a b, # комментарий b c): # комментарий c pass # итоговый комментарий
PS с Питоном не знаком, просто нагуглил аналог // из C++
johnnymmc
18.10.2017 23:43Любопытно, кстати, почему люди вообще до сих пор используют текстовое представление для хранения программ. По-моему тут на лицо сращивание данных и форматирования в одну сущность, которого вроде всегда стоит стараться избегать. Почему вместо этого не хранить типы, переменные, функци и т.п. в качестве записей, скажем, в реляционной БД, с указанием отношений между ними, имён и инициализационные значений как отдельных полей, а для каждого разработчика рендерить как ему больше нравится?
Deosis
19.10.2017 07:24Тогда уж хранить код в виде AST, а в редакторе разворачивать с применением персонального файла стилей.
Минус данного подхода: как хранить AST в системе контроля версий?Sklott
19.10.2017 11:48А что мешает сделать diff для AST? А уж если некий формат описания AST станет стандартным то и вообще все будет замечательно.
Sirikid
19.10.2017 13:03+1Современные системы контроля версий ориентированны на текст, очевидно нужна новая система, ориентированная на AST.
Deosis
20.10.2017 08:55Как-то решение сразу не пришло в голову.
Можно сформировать отдельный файл стилей для хранения.
При загрузке переформатировать в пользовательский формат, при сохранении — в машинный.
potan
19.10.2017 07:58Еще при изучении и рефакторинге больших программ хочется уметь работать с кодом чем-то типа SQL или SPARQL запросов.
vtvz_ru
19.10.2017 01:32Использую автоформатирование, которое даёт мне JetBrains. Неплохо справляется со своей задачей. И ESLint сбоку ещё повесил, чтобы в случае косяков со стороны IDE форматтера, я мог это сразу увидеть. Поэтому для себя не вижу смысла использовать ещё и Prettier.
Staltec
20.10.2017 07:57Суть prettier в том, что ты пишешь код как пишешь, а потом одной комбинацией клавиш приводишь его вид к общему стандарту в команде
vtvz_ru
20.10.2017 13:16+1Я тоже пишу код, как хочу, а потом нажимаю
Ctrl+Alt+L
(В поиске: Reformat Code) и привожу его к общему стандарту. Помимо этого, PHPStorm неплохо синхронизируется с настройками.eslintrc.json
.
potan
19.10.2017 07:55Сейчас изучаю язык ELM, в котором есть стандартный форматер elm-format, вставляющий кучу лишних пустых строк и разбивающий строки без пользы для читаемости. Не все любят такой стиль, и появился сторонний продукт elm-format-short, который более экономно относится к месту на экране. Мне удобно видеть сразу больше кода, держать в уме не поместившееся на экран памяти не хватает, я быстро перешел на него. При этом идея сделать форматер настраиваемым в комьюнити поддержкой не пользуется.
Я вот думаю, хорошо бы если бы IDE при сохранении форматировала стандартным образом, а при загрузке — по настройкам пользователя. Тогда бы и взаимодействие в команде не страдало бы, и редактировать код в своем стиле было бы удобнее.Goodkat
19.10.2017 09:04Делайте форматирование по стандартам в pre commit hook, а каждый разработчик настроит в своей IDE автоформатирование по своему вкусу.
dreka5
19.10.2017 09:52-1очень раздражает автоформатирование GO. он просто заставляет следовать егоному стилю.
так и стремится удалить лишние строки, пробелы, выстроить выражение по своему образцу.
лучше бы сделали подобную опцию опциональной. ломать через колено это неприятно, после других то языков.
MaxLich
19.10.2017 09:52Пишу на Java в Intellij IDEA, и там код можно автоматически отформатировать одним сочетанием клавиш. Довольно удобно. Неужели для JS нет такой же удобной IDE? (WebStorm, не?)
PS Хотя и вручную я тоже стараюсь придерживаться какого-то (чаще всего наиболее читабельного) форматирования кода.
pygubanov
19.10.2017 11:57Причина, по которой приходится использовать стандартное авто форматирование кода это использование систем контроля версий (git, svn и пр.), которые универсальные и работают с текстом. Если форматирование изменится, то это будет уже новая версия кода. Поэтому для командной разработки кода лучше всего применять авто форматирование.
Germanets
19.10.2017 11:59Первый и второй вариант одновременно — большая часть форматируется «роботом», если где-то было трудно это сделать руками, меньшая — руками, так как там форматирование улучшает понимание, а «робот» его портит.
SadOcean
19.10.2017 12:09+1В конце концов понял, что мне в целом все равно (хотя конечно же есть вид, который мне нравится), и, гораздо важнее, чтобы стиль был одинаковый у людей, с которыми работаешь. Иначе сбиваешься при чтении в разных местах проекта.
То есть важнее договориться одинаково, чем сделать как то особенно правильно.
В этом смысле имеет смысл смотреть на стандарты для языка — от мейнтейнера, популярной ide или стандартных модулей.
knotri
19.10.2017 13:16+1Перешел на prettier с standardJs — Это просто божественно — да, в нем мало настроек, по началу это бесило (например нельзя в реакте сделать ковычки на пропсах одинарными) — но сейчас я понимаю что вообще больше руками не форматирую код — все делается автоматически за меня.
Я не представляю себе ситуацию чтоб я вернулся к ручному форматированию.
Но у преттиера есть минус — он немного сырой и кое-где ведет себя странно, с теми же промисами
Staltec
20.10.2017 08:08У нас практика показала, что если prettier что то форматирует странно, это значит изначально код написан сильно криво. Я своих ребят ещё какое-то время отучал от фраз типа «это претир так сформатировал». Писать надо так чтобы форматировалось нормально. Выносить вычисления в константы, не совмещать вычисления с возвратами, особенно тринарники. И всё сразу нормально форматироваться начинает.
artemisia_borealis
19.10.2017 14:32+2В одной американской компании, в которой работал шесть лет был первый упомянутый стиль оформления для кода на C++.
Заголовок спойлераif (food == 'pizza') { print('Pizza ;-)'); } else { print('Not pizza ;-('); }
Idot
19.10.2017 14:41-1Намного лучше и удобнее
if (food == 'pizza'){//комментарий if print('Pizza ;-)');} else{//комментарий else print('Not pizza ;-(');} another.code();//следующий код с начала строки
— выделяется целиком весь блок if-else, и видно, где он кончается
— выделяется, где else
— компактно, и на экране можно одним взглядом охватить больше кодаSklott
19.10.2017 15:25А уж как «удобно» мержом добавлять новую строчку перед закрывающей скобкой!
Idot
19.10.2017 17:59Можно и так:
if (food == 'pizza'){//комментарий if print('Pizza ;-)');} }else{//комментарий else print('Not pizza ;-('); } another.code();//следующий код с начала строки
PS судя по минусам в Карму, у Вас явно не хило бомбануло, от указания недостатков варианта:
if (food == 'pizza') { print('Pizza ;-)'); } else { print('Not pizza ;-('); }
Idot
19.10.2017 19:47Вариант
if (food == 'pizza') { print('Pizza ;-)'); } else { print('Not pizza ;-('); }
— это классика от Кэрригана и Риччи, созданная тогда, когда шли жаркие споры о том, что "форматирование и отступы — вообще не нужны", и потому ими был выбран именно такой компромиссный вариант, оказавшийся, как это выяснилось позже, "ни рыба, ни мясо".
Zenitchik
19.10.2017 20:10Удобнее всего
if (food == 'pizza'){ print('Pizza ;-)'); } else{ print('Not pizza ;-('); }
Тогда при сворачивании блока я вижу его первую строку, строка с "{" не маячит. А в развёрнутом виде хорошо видна структура блока.
urrri
19.10.2017 22:54С моей точки зрения идеальным вариантом, исключающим большинство холиваров, был бы такой подход: при загрузке в редактор — персональное автоформатирование, а при сохранении/коммите — стандартизированное форматирование. В обоих случаях должно происходить полное переформатирование без учета текущего формата. Исключением могут быть специально обозначенные блоки, которые никогда не переформатируются, только вручную. Тогда каждый будет работать с удобным и привычным ему лично форматом, а стандартизированный формат позволит более корректно проводить мерджи и позволит избежать различных проблем, присущих, например, JS. Причем персонализированный формат должен быть максимально настраиваимым, а стандартизированный наоборот не должен иметь натроек совсем.
urrri
19.10.2017 23:04Я бы даже сказал, что это чем-то напоминает загрузку и сохранения файлов в текстовых редакторах, где сам файл представляет некий стандартный формат, а в редакторе виден удобный для работы текст.
Zenitchik
Ммм… Потому что могут?