Статьи

Как мы используем модули для организации нашего кода переднего плана

Вы когда-нибудь задумывались, как большой сайт, такой как Tuts +, сохраняет свои CSS, HTML и JavaScript в порядке непрерывной разработки и итерации? Я собираюсь показать вам процесс, который мы реализовали, чтобы все было аккуратно и легко обслуживалось.

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

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

1
2
h1 { font-size: 22px;
.subtitle { font-size: 18px;

Если вам необходимо переопределить эти селекторы в определенной части страницы, вы можете использовать вложенные правила для создания селекторов, предназначенных для более конкретных элементов:

1
2
3
4
.site-header h1 { font-size: 40px;
.site-header .subtitle { font-size: 28px;
.site-header a.navigation { color: #136FD2 }

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

Что происходит, когда мы меняем стиль h1 или .subtitle на глобальном уровне? font-size уже переопределяется более конкретным стилем, но если мы добавим font-weight или line-height этого не произойдет. Любые изменения, внесенные в глобальные стили, могут распространяться и влиять на более специфические стили способами, которые невозможно предсказать без глубокого знания всех стилей на сайте.

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

Чтобы помочь предотвратить эту проблему, мы приняли подход к CSS, основанный на методологии БЭМ . Вместо определения стилей, которые применяются глобально, все стили разделены на отдельные «блоки» в соответствии с соглашением об именах. «Блок» определяется более или менее как отдельная автономная единица контента, которая потенциально может использоваться повторно (хотя необязательно, что она фактически используется повторно).

Например, давайте посмотрим на блок «Featured-секции»:

Блок Tuts Featured Sections

Согласно нашему соглашению об именах, в этом блоке есть корневой элемент div с именами классов featured-sections . Он содержит элементы с именами классов, такими как featured-sections__title и featured-sections__section-link .

Мы используем соответствующее соглашение об именах для нашего исходного кода, так как все стили для этого блока featured-section Section хранятся в modules/featured_section.sass :

1
2
3
4
5
6
7
8
.featured-sections
  margin: 0 0 $gutter-width 0
  padding-top: 8px
  border-top: 4px solid #dae1e5
 
.featured-sections__title
  color: #8fa6b3
  font: bold 14px/1.2em $font

Это соглашение об именах гарантирует, что стили больше не будут конфликтовать и смешиваться. До тех пор, пока соблюдается наше соглашение об именах, с именем блока в начале каждого имени класса, стиль не может влиять на что-то вне его собственного блока.

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

Мы решили пойти дальше и применить это соглашение об именах и к нашим представлениям. Каждый блок имеет частичное представление с тем же именем, которое хранится в views/modules . Например, HTML-представление для нашего блока views/modules/_featured_sections.html.slim в views/modules/_featured_sections.html.slim :

Блок избранных разделов

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

Мы также пошли дальше и приняли те же соглашения об именах для нашего кода JavaScript, с небольшой помощью из Backbone.js .

Каждый блок, для которого необходимо применить поведение JavaScript, получает объект представления Backbone с тем же именем блока:

1
2
3
4
5
6
7
8
9
class window.AccountHeader extends Backbone.View
 events:
   ‘change .account-header__mobile-menu-select’: ‘mobileMenuChange’
 
 mobileMenuChange: ->
   document.location = @_selectedOption().data(‘url’)
 
 _selectedOption: ->
   @$ ‘option:selected’

Мы написали некоторый код загрузки представления, который применяется при загрузке страницы, поэтому соответствующее представление Backbone автоматически загружается для каждого элемента с классом CSS, который соответствует списку имен блоков со связанным JS.

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

Полнофункциональная блочная структура

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

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

Определенно все еще возможно перейти от глобального стиля CSS к более модульному стилю БЭМ, и я бы поспорил, что оно того стоит в долгосрочной перспективе. Тем не менее, ожидайте, что вам будет немного сложнее создать свои стили БЭМ некоторое время, и будьте готовы добавить хотя бы несколько временных !important объявлений в свой CSS, пока вы не сможете полностью избавиться от своего глобального стили.