image

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

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

С тех пор я потратил много времени, рассуждая о стиле кодирования и выбирая инструменты для его осуществления. Настало время что-то менять.

Несколько примеров


После прочтения “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 и это не умещается в одну строку — тогда я понимаю, что оно абсолютно точно стоит того.

image

Prettier форматирует ваш код, когда вы сохраняете файл.

Прочитайте, как внедрить Prettier в свой проект.

P.S. Посмотрите на мое новое средство, которое упростит добавление ESLint, Prettier и других инструментов в ваш проект, а также хранение и синхронизацию их настроек.



Перевод выполнен при поддержке компании EDISON Software, которая профессионально занимается разработкой сайтов на Amiro.CMS и WordPress и для крупных заказчиков.

Комментарии (60)


  1. Zenitchik
    18.10.2017 17:47
    +2

    Ммм… Потому что могут?


  1. dolphin4ik
    18.10.2017 17:52
    +2

    Так же работаю с Prettier, но заметил, что эта штука не до конца понимает чейны и уж слишком разворачивает объекты конфигураций json


    1. Shifty_Fox
      18.10.2017 23:40

      Я рекомендую eslint auto fix


  1. novikovden411
    18.10.2017 18:30

    Многие хотят писать так как хотят, я в их числе.


    1. MagisterLudi Автор
      18.10.2017 18:33

      Добавил опрос, посмотрим сколько это «многие»


    1. wing_pin
      18.10.2017 20:36

      У меня для вас плохие новости. На момент написания это комментария вы находитесь в меньшинстве.


      1. Defersa
        20.10.2017 15:52
        -1

        Почему плохие? Миллионы мух не могут ошибаться?


  1. MrGobus
    18.10.2017 18:56

    Спасибо, не надо.


        <div
          className="HelloWorld"
          title={`You are visitor number ${num}`}
          onMouseOver={onMouseOver}
        >

    (из официального примера)


    1. zagayevskiy
      18.10.2017 18:58
      +1

      Придерживаемся такого стиля в форматировании xml в Android. Сначала было непривычно, потом стало норм. Особых минусов нет.


    1. gibson_dev
      19.10.2017 09:01
      +3

      очень удобный стиль — когда надо добавить или удалить свойство — просто добавь или удали строку, да и в jsx свойств может быть очень много


  1. myxo
    18.10.2017 19:03

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


    1. justboris
      18.10.2017 22:16

      Для таких случаев можно поставить коммент prettier-ignore. Prettier оставит форматирование этого куска как и было:


      // prettier-ignore
      matrix(
        1, 0, 0,
        0, 1, 0,
        0, 0, 1
      );


  1. VladlenBronislav
    18.10.2017 19:40
    +1

    В Java стиль чистого кода появился с лёгкой руки Боба (Robert Martin), и не говоря про JavaCodeConvention.
    Возможно, и у JavaScript появиться свой евангелист…


  1. EndUser
    18.10.2017 21:15

    AStyle при сохранении, но опции мои.


  1. dmitry_dvm
    18.10.2017 21:17
    +1

    Ctrl+KD в студии и таких вопросов даже не возникает.


  1. 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 пишет) рекомендации как оформлять код.


    1. domix32
      19.10.2017 10:28
      +1

      В итоге один оператор равенства отбит пробелами, а самый первый — нет.


    1. 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;
      }


      1. justboris
        19.10.2017 13:26
        +2

        нет, пожалуйста, не надо! Нет ничего хуже, чем центрирование кода относительно знака равенства.


        Потом придется добавить еще одну переменную с именем подлиннее, и придется переформатировать весь блок кода, создавая большой diff и потенциальные merge-конфликты.


  1. justboris
    18.10.2017 22:23

    нечего даже обсуждать — у Prettier’а несколько опций;

    Это не совсем правда. Опций немного, но они очень холивароспособствующие.


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


    1. playaaa
      19.10.2017 22:14
      +1

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

      Про development standards никогда не слышали? Простой документ с элементарным набором правил по разработке (включающий, но не ограниченный, naming conventions и тем самым форматированием), который почетно вручается каждому программеру, пришедшему на проект/в компанию. Тому, кто не блюдет — по шапке. Проблемы?


      1. justboris
        19.10.2017 22:24

        Странно, если все так легко, то отчего же спор "табы против пробелов" до сих пор не закончился? Сходили бы все разработчики к мудрейшему техлиду, и узнали у него как надо.


        Но почему-то так не происходит, а любой пост на эту тему набирает немало комментариев, например, вот этот.


        1. playaaa
          20.10.2017 00:49

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


  1. MaKvc
    18.10.2017 22:30

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


  1. xFFFF
    18.10.2017 22:34

    Стилизаторы кода рулят)


  1. 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 при автоматическом форматировании) как по мне и вовсе исчадие «ада перфекциониста».

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


    1. raveclassic
      19.10.2017 02:50

      А как же минификация?


    1. Idot
      19.10.2017 10:45

      def f(a, b,  c):
          pass

      — хороший вариант, если нет комментариев


      def f(a,
          b,
          c):
          pass

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


      def f(a, # комментарий a
          b, # комментарий b
          c): # комментарий c
          pass # итоговый комментарий

      PS с Питоном не знаком, просто нагуглил аналог // из C++


  1. johnnymmc
    18.10.2017 23:43

    Любопытно, кстати, почему люди вообще до сих пор используют текстовое представление для хранения программ. По-моему тут на лицо сращивание данных и форматирования в одну сущность, которого вроде всегда стоит стараться избегать. Почему вместо этого не хранить типы, переменные, функци и т.п. в качестве записей, скажем, в реляционной БД, с указанием отношений между ними, имён и инициализационные значений как отдельных полей, а для каждого разработчика рендерить как ему больше нравится?


    1. Deosis
      19.10.2017 07:24

      Тогда уж хранить код в виде AST, а в редакторе разворачивать с применением персонального файла стилей.
      Минус данного подхода: как хранить AST в системе контроля версий?


      1. Goodkat
        19.10.2017 09:00

        Так и хранить, отформатированным в виде текста.


      1. domix32
        19.10.2017 10:32

        И страдать из-за непонятных git-diff?


      1. Sklott
        19.10.2017 11:48

        А что мешает сделать diff для AST? А уж если некий формат описания AST станет стандартным то и вообще все будет замечательно.


      1. Sirikid
        19.10.2017 13:03
        +1

        Современные системы контроля версий ориентированны на текст, очевидно нужна новая система, ориентированная на AST.


      1. Deosis
        20.10.2017 08:55

        Как-то решение сразу не пришло в голову.
        Можно сформировать отдельный файл стилей для хранения.
        При загрузке переформатировать в пользовательский формат, при сохранении — в машинный.


    1. potan
      19.10.2017 07:58

      Еще при изучении и рефакторинге больших программ хочется уметь работать с кодом чем-то типа SQL или SPARQL запросов.


  1. vtvz_ru
    19.10.2017 01:32

    Использую автоформатирование, которое даёт мне JetBrains. Неплохо справляется со своей задачей. И ESLint сбоку ещё повесил, чтобы в случае косяков со стороны IDE форматтера, я мог это сразу увидеть. Поэтому для себя не вижу смысла использовать ещё и Prettier.


    1. Staltec
      20.10.2017 07:57

      Суть prettier в том, что ты пишешь код как пишешь, а потом одной комбинацией клавиш приводишь его вид к общему стандарту в команде


      1. vtvz_ru
        20.10.2017 13:16
        +1

        Я тоже пишу код, как хочу, а потом нажимаю Ctrl+Alt+L (В поиске: Reformat Code) и привожу его к общему стандарту. Помимо этого, PHPStorm неплохо синхронизируется с настройками .eslintrc.json.


  1. potan
    19.10.2017 07:55

    Сейчас изучаю язык ELM, в котором есть стандартный форматер elm-format, вставляющий кучу лишних пустых строк и разбивающий строки без пользы для читаемости. Не все любят такой стиль, и появился сторонний продукт elm-format-short, который более экономно относится к месту на экране. Мне удобно видеть сразу больше кода, держать в уме не поместившееся на экран памяти не хватает, я быстро перешел на него. При этом идея сделать форматер настраиваемым в комьюнити поддержкой не пользуется.
    Я вот думаю, хорошо бы если бы IDE при сохранении форматировала стандартным образом, а при загрузке — по настройкам пользователя. Тогда бы и взаимодействие в команде не страдало бы, и редактировать код в своем стиле было бы удобнее.


    1. Goodkat
      19.10.2017 09:04

      Делайте форматирование по стандартам в pre commit hook, а каждый разработчик настроит в своей IDE автоформатирование по своему вкусу.


  1. dreka5
    19.10.2017 09:52
    -1

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


  1. MaxLich
    19.10.2017 09:52

    Пишу на Java в Intellij IDEA, и там код можно автоматически отформатировать одним сочетанием клавиш. Довольно удобно. Неужели для JS нет такой же удобной IDE? (WebStorm, не?)
    PS Хотя и вручную я тоже стараюсь придерживаться какого-то (чаще всего наиболее читабельного) форматирования кода.


    1. worldxaker
      20.10.2017 01:49

      есть конечно, vs code


  1. pygubanov
    19.10.2017 11:57

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


  1. Germanets
    19.10.2017 11:59

    Первый и второй вариант одновременно — большая часть форматируется «роботом», если где-то было трудно это сделать руками, меньшая — руками, так как там форматирование улучшает понимание, а «робот» его портит.


  1. SadOcean
    19.10.2017 12:09
    +1

    В конце концов понял, что мне в целом все равно (хотя конечно же есть вид, который мне нравится), и, гораздо важнее, чтобы стиль был одинаковый у людей, с которыми работаешь. Иначе сбиваешься при чтении в разных местах проекта.
    То есть важнее договориться одинаково, чем сделать как то особенно правильно.
    В этом смысле имеет смысл смотреть на стандарты для языка — от мейнтейнера, популярной ide или стандартных модулей.


  1. knotri
    19.10.2017 13:16
    +1

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


    Я не представляю себе ситуацию чтоб я вернулся к ручному форматированию.


    Но у преттиера есть минус — он немного сырой и кое-где ведет себя странно, с теми же промисами


    1. Staltec
      20.10.2017 08:08

      У нас практика показала, что если prettier что то форматирует странно, это значит изначально код написан сильно криво. Я своих ребят ещё какое-то время отучал от фраз типа «это претир так сформатировал». Писать надо так чтобы форматировалось нормально. Выносить вычисления в константы, не совмещать вычисления с возвратами, особенно тринарники. И всё сразу нормально форматироваться начинает.


  1. artemisia_borealis
    19.10.2017 14:32
    +2

    В одной американской компании, в которой работал шесть лет был первый упомянутый стиль оформления для кода на C++.

    Заголовок спойлера
    if (food == 'pizza')
    {
        print('Pizza ;-)');  
    }
    else
    {  
        print('Not pizza ;-(');
    }
    


    1. Idot
      19.10.2017 14:41
      -1

      Намного лучше и удобнее


      if (food == 'pizza'){//комментарий if
          print('Pizza ;-)');}
        else{//комментарий else
          print('Not pizza ;-(');}
      another.code();//следующий код с начала строки

      — выделяется целиком весь блок if-else, и видно, где он кончается
      — выделяется, где else
      — компактно, и на экране можно одним взглядом охватить больше кода


      1. Sklott
        19.10.2017 15:25

        А уж как «удобно» мержом добавлять новую строчку перед закрывающей скобкой!


        1. 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 ;-(');
          }


          1. Idot
            19.10.2017 19:47

            Вариант


            if (food == 'pizza')
            {
                print('Pizza ;-)');  
            }
            else
            {  
                print('Not pizza ;-(');
            }

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


            1. Zenitchik
              19.10.2017 20:10

              Удобнее всего


              if (food == 'pizza'){
                  print('Pizza ;-)');  
              }
              else{  
                  print('Not pizza ;-(');
              }

              Тогда при сворачивании блока я вижу его первую строку, строка с "{" не маячит. А в развёрнутом виде хорошо видна структура блока.


              1. Idot
                20.10.2017 10:18

                Отличная идея! Про сворачивание я-то и не подумал...


  1. Sklott
    19.10.2017 15:25

    промахнулся…


  1. urrri
    19.10.2017 22:54

    С моей точки зрения идеальным вариантом, исключающим большинство холиваров, был бы такой подход: при загрузке в редактор — персональное автоформатирование, а при сохранении/коммите — стандартизированное форматирование. В обоих случаях должно происходить полное переформатирование без учета текущего формата. Исключением могут быть специально обозначенные блоки, которые никогда не переформатируются, только вручную. Тогда каждый будет работать с удобным и привычным ему лично форматом, а стандартизированный формат позволит более корректно проводить мерджи и позволит избежать различных проблем, присущих, например, JS. Причем персонализированный формат должен быть максимально настраиваимым, а стандартизированный наоборот не должен иметь натроек совсем.


    1. urrri
      19.10.2017 23:04

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


  1. vdonich
    19.10.2017 23:19

    Вы еще форматируете руками? Тогда мы едем к вам!