Плавильный котел JavaScript.

Перевод статьи Дэна Абрамова «The melting pot of JavaScript»

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


Люди, с которыми я общался имеют смешанные чувства об экосистеме JavaScript.

Некоторые жалуются на то, как они устали от утомительности JavaScript. Другие утверждают, что мы живем в эпоху Возрождения JavaScript.

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

Некоторые расценивают JavaScript как результат компиляции, в то время как другие формируют субкультуры вокруг конкретных способов написания кода на нем. И он запускается везде: на вашем ноутбуке, на вашем телефоне, на сервере, и скоро, вероятно, на вашем холодильнике.

Непривязанная к одному вендору, экосистема JavaScript близко отражает человеческую культуру. Она изобретательна, инкрементальна, беспорядочна, адаптирующая все на своем пути, и вездесуща.

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

Но сперва, давайте взглянем на то как JavaScript-экосистема пришла к тому, чем она является сейчас.

Непривязанная к одному вендору, экосистема JavaScript близко отражает человеческую культуру. Она изобретательна, инкрементальна, беспорядочна, адаптирующая все на своем пути, и вездесуща.

Появилась дикая вереница инструментов

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

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

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

Инновации в браузерных движках JavaScript сделали возможным создание богатых клиентских веб-приложений. Node.js основываясь
на этих инновациях, исполняет JavaScript на сервере и внедряет модульную систему JavaScript. Приложения на стороне клиента также остро нуждались в модульной системе. Появились и стали популярными инструменты реализующие схожее модульное API для клиентских приложений.

Экосистемы клиентского и серверного JavaScript продолжают обогащать друг друга. Многие модули, с которыми люди хотят делиться, агностичны к окружению, в конечном итоге оба сообщества сошлись в использовании пакетной экосистеме Node. Люди часто шутят об этом, но это факт, что реестр NPM это самая большая платформа для распространения кода в человеческой истории.

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

Инструменты сборки стали более обычным делом в JavaScript, нежели в других сообществах. Я являюсь частью этого. Было ощущение, что хорошо быть любителем, потому что большинство людей являются таковыми. Как только вам станет комфортно создавать приложения, вы можете начать создавать инструменты для себя и других. Вам необязательно быть инженером в области построения компиляторов, чтобы контрибьютить в Babel.

Также помогает то, что JavaScript модули поставляются как исходный код, таким образом, вы всегда можете заглянуть под капот. Поскольку NPM размещает зависимости прямо в директории с вашим проектом, вы всегда можете перейти к коду, которое заставляет ваше приложение работать. Мне казалось, что установка кода делает этот код моей ответственностью. Я мог бы помочь исправить ошибки и сделать инструменты, на которые я полагался, лучше.

И все еще…

Айсберг зависимостей

Сегодня перспектива столкновения с зависимостями пугает многих разработчиков. В типичном проекте на JavaScript их так много! И с тех пор как NPM делает зависимости «плоскими», вы сразу же подвергаетесь воздействию всех транзитивных зависимостей.

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

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

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

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

Так что нет, не айсберг зависимостей беспокоит меня.

Это расширение параметров конфигурации.

Наши инструменты делают меня жирным

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

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

Кэтти Сиерра написала ужасающую статью «Ваше приложение делает меня жирным» четыре года назад. Я не могу перестать думать о ней. Вы совершенно точно должны прочитать ее, но вот часть, которая поразила меня:

Если ваш UX просит пользователя сделать выбор, к примеру, даже если оба этих выбора понятны и полезны, акт принятия решения является когнитивной утечкой. И не в период принятия решения пользователем… Даже после того, как мы сделали выбор, подсознательная когнитивный фоновая нить медленно потребляет ресурс. «Был ли это правильный выбор?»… Если наша рабочая утечка это пользовательский когнитивный ресурс, то что он теряет? Что еще он можем сделать с этими скудными, драгоценными, легко истощаемыми ресурсами? Может быть, он пытается придерживаться диеты. Или практикует игру на гитаре. Или играет со своими детьми.

Как создатели инструментов, мы часто не до конца понимаем эту цену.

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

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

Если вы, как и я, работаете над JavaScript-инструментами, вы приверженец самого большого сообщества на земле. Это страшно.

Если вы, как и я, работаете над JavaScript-инструментами, вы приверженец самого большого сообщества на земле. Это страшно. Когда мы привинчиваем и печатаем непонятное сообщение об ошибке, кто-то где-то решает, что они не предназначены для программирования. Когда они не могут правильно сконфигурировать проект, мы теряем их даже до того как они хотя бы начали.

Есть несколько стратегий, с помощью которых мы можем сделать инструменты более дружелюбными. Каждая из них не является новой идеей, но я нахожу их постоянно не используемыми в экосистеме JavaScript. Такие проекты, как Ember и Elm делают это правильно, и мы все можем поучиться у них. Вот что, на мой взгляд, упущено.

Конфигурация не должна вставать на пути к началу работы

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

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

Сопротивление добавляет больше конфигурации, чем необходимо

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

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

Раскрывайте расширенную функциональность постепенно

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

Следите за своим выводом

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

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

Создавайте переиспользуемые инструментарии

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

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

Инструментарии, не шаблоны

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

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

Когда новая версия используемых инструментов выходит, мы обновляем их с нашей стороны, меняем конфигурацию, если нужно и выпускаем обновление для нашей общей зависимости, которую каждый может обновить одной командой. Я слышал от множества людей, что хотя они не используют приложение «Create React» сами, они приняли аналогичную стратегию в своих компаниях, централизуя интерфейсную оснастку в одном пакете.

Конечно, некоторые проекты действительно нуждаются в специфичных для проекта настройках. В приложении «Create React» мы решили эту проблему с использованием, так называемого, «извлечения», впервые появившемся в Enclave. Если вы выполняете команду eject, конфигурационные файлы и все низлежащие зависимости копируются напрямую к вам в проект. Теперь вы можете менять все что хотите, но вы не получаете общих обновлений после того как вы форкнули среду инструмента к вам в проект. Извлечение содержит свои слабые стороны, но оно позволяет сделать выбор: хотите ли вы сохранить свою собственную настройку инструмента для каждого проекта или нет.

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

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

Вы можете помочь

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

Если проект принимает ишью, вы можете создать ишью и описать ваше предложение, или вы можете просто отправить Pull Request. Как мейнтейнеры, мы часто перестаем обращать внимание на вопросы удобства использования в наших проектах, потому что мы проводим с ними так много времени.

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

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

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

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

Я не могу дождаться, чтобы увидеть, что они создадут с их помощью.