Опубликован: 27.01.2016 | Доступ: свободный | Студентов: 913 / 58 | Длительность: 23:07:00
Лекция 5:

Заполнение шаблона

Sass и файлопровод (asset pipeline)

Одним из наиболее значитильных нововведений в последних версиях Rails является файлопровод (asset pipeline), который значительно улучшает создание и управление статическими файлами (# assets, активы) такими как CSS, JavaScript и изображения. Этот раздел даст вам общее понимание файлопровода, а затем покажет как использовать удивительный инструмент для создания CSS называемый Sass, теперь уже по умолчанию включенный в Rails как часть файлопровода.

Файлопровод

Файлопровод включает в себя множество подкапотных изменений в Rails, но с точки зрения типичного Rails разработчика есть три принципиальных момента в которых нужно разобраться: директории ассетов (активов, файлов), файлы-манифесты и препроцессоры.8Структура этого раздела опирается на замечательную статью The Rails 3 Asset Pipeline in (about) 5 Minutes от Michael Erasmus. Более подробно о файлопроводе см. (rus)Rails Guide on the Asset Pipeline. Давайте рассмотрим каждый из них по очереди.

Директории ассетов

В версиях Rails до 3.0 включительно, статические ассеты жили в директории public/ следующим образом:

  • public/stylesheets
  • public/javascripts
  • public/images

Файлы в этих директориях (даже в версиях "после 3.0") автоматически выдаются через запрос к http://example.com/stylesheets, и т.д..

Начиная с Rails 3.1 и продолжая в Rails 4, существуют три каноничные директории для статических ассетов, каждая со своим собственным назначением:

  • app/assets: ассеты специфичные для данного приложения;
  • lib/assets: ассеты для библиотек написанных вашей командой разработчиков;
  • vendor/assets: ассеты сторонних поставщиков (програмного обеспечения);

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

$ ls app/assets/
images      javascripts stylesheets

Теперь мы в состоянии понять причины, по которым мы поместили файл custom.css.scss в директорию app/assets в Разделе 5.1.2: custom.css.scss специфичен для примера приложения, поэтому он отправляется в app/assets/stylesheets.

Файлы-манифесты

После того как вы поместили ваши ассеты в предназначенные им директории, вы можете использовать файлы-манифесты для того, чтобы сказать Rails (с помошью гема Sprockets) как скомбинировать их для того чтобы сформировать один единственный файл. (Это относится к CSS и JavaScript но не к изображениям.) В качестве примера, давайте взглянем на дефолтный манифест файл для таблиц стилей приложения (Листинг 5.15).

/*
 * This is a manifest file that'll automatically include all the stylesheets
 * available in this directory and any sub-directories. You're free to add
 * application-wide styles to this file and they'll appear at the top of the
 * compiled file, but it's generally better to create a new file per style
 * scope.
 *= require_self
 *= require_tree .
*/
Листинг 5.15. Манифест файл для app-specific CSS. app/assets/stylesheets/application.css

Ключевыми строками здесь являются CSS комментарии, но именно они используются Sprockets для включения правильных файлов:

/*
 .
 .
 .
 *= require_self
 *= require_tree .
*/

Здесь

*= require_tree .

обеспечивает включение всех CSS файлов из директории app/assets/stylesheets (в том числе вложенные субдиректории) в CSS приложения. Строка

*= require_self

указывает где в загрузочной последовательности будет включен CSS код самого application.css файла.

Rails поставляется с вполне вменяемыми дефолтными манифест-файлами и в Rails Tutorial мы не будем изменять их, но в случае если вам понадобится их изменить, см. rus)Rails Guides введение в asset pipeline чтобы узнать об этом подробнее.

Препроцессоры

После того как вы собрали ваши активы, Rails подготавливает их для шаблона сайта, прогоняя их через несколько препроцессоров и комбинирует их с помощью манифест-файлов для доставки в браузер. Мы говорим Rails какой препроцессор использовать с помощью расширения файла; наиболее употребительными являются .scss для Sass, .coffee для CoffeeScript и .erb для встроенного Ruby (ERb). Мы впервые рассказывали о ERb в Разделе 3.3.3 и о Sass в Разделе 5.2.2. В этом учебнике нам не понадобится CoffeeScript. Если вам интересно узнать об этом элегантном маленьком языке который компилируется в JavaScript, советую начать с RailsCast on CoffeeScript basics.

Препроцессоры могут быть сцеплены, например

foobar.js.coffee

прогоняется через препроцессор CoffeeScript, а

foobar.js.erb.coffee

прогоняется и через CoffeeScript и через ERb (справа налево, т.е. CoffeeScript первым).

Производительность в продакшен

Одно из самых замечательных свойств файлопровода заключается в том, что он автоматически приводит к повышению производительности в продакшен приложении. Традиционный подход к организации CSS и JavaScript подразумевает разбиение функциональности между отдельными файлами и использование приятного глазу форматирования (с большим количеством отступов). Что является удобным для программистов, но неэффективно в продакшен; включение множества крупноразмерных файлов может серьезно увеличить время загрузки страниц (а это один из наиболее значимых факторов влияющих на впечатление получаемое пользователями от сайта). С файлопроводом, в продакшен все таблицы стилей приложения заворачиваются в один CSS файл (application.css), весь JavaScript код приложения заворачивается в один JavaScript файл (javascripts.js) и все подобные файлы (включая и те что хранятся в lib/assets и vendor/assets) минимизируются для удаления ненужных пробелов увеличивающих размер файла. В результате мы получаем лучшее для обоих миров: множество хорошо отформатированных файлов для удобства программистов и объединенные в один, оптимизированные файлы для продакшен.

Синтаксически обалденные таблицы стилей

Sass это язык для написания таблиц стилей который во многом улучшает CSS. В этом разделе мы узнаем о двух наиболее важных улучшениях: вложенности и переменных. (Третья техника, примеси, представлена в Разделе 7.1.1.)

Как было вкратце отмечено в Разделе 5.1.2, Sass поддерживает формат называемый SCSS (обозначается расширением файла .scss), который является расширерением самого CSS; то есть, SCSS только добавляет возможности к CSS, вместо определения совершенно нового синтаксиса.9Более старый .sass формат, также поддерживаемый Sass, определяет новый язык который является менее многословным (и в нем нет фигурных скобок), но менее удобным для существующих проектов и его сложнее изучать тем кто уже знаком с CSS. Это означает, что любой валидный CSS файл будет валидным SCSS файлом, что удобно для проектов с уже написанным стилем. В нашем случае мы использовали SCSS с самого начала для совместимости с Bootstrap. Поскольку файлопровод в Rails автоматически использует Sass для обработки файлов с .scss расширением, файл custom.css.scss будет пропущен через препроцессор Sass прежде чем он будет упакован для доставки в браузер.

Вложение

Общепринятым паттерном в написании таблиц стилей являются правила применяемые ко вложенным элементам. Например, в Листинге 5.6 у нас есть правило применяемое и для .center и для .center h1:

.center {
  text-align: center;
}

.center h1 {
  margin-bottom: 10px;
}

В Sass мы можем заменить это на

.center {
  text-align: center;
  h1 {
    margin-bottom: 10px;
  }
}

Здесь вложенное правило h1 наследует контекст правила .center.

Здесь есть второй кандидат на вложение, который требует несколько иного синтаксиса. В Листинге 5.8, мы имеем код

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
  line-height: 1;
}

#logo:hover {
  color: #fff;
  text-decoration: none;
}

Здесь id логотипа #logo используется дважды, в первый раз сам по себе и второй раз с атрибутом hover (который отвечает за его внешний вид при наведении курсора). Для того чтобы вложить второе правило нам необходимо сослаться на родительский элемент #logo; в SCSS это достигается с помощью символа & следующим образом:

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
  line-height: 1;
  &:hover {
    color: #fff;
    text-decoration: none;
  }
}

Sass заменяет &:hover на #logo:hover при конвертации из SCSS в CSS.

Обе эти техники вложения элементов применяются в CSS подвала в Листинге 5.14, который может быть трансформирован в следующее:

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid #eaeaea;
  color: #999;
  a {
    color: #555;
    &:hover {
      color: #222;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 10px;
    }
  }
}

Конвертирование Листинга 5.14 вручную это хорошее упражнение и вы должны убедиться что CSS по прежнему работает как надо после преобразования.

Переменные

Sass позволяет нам определять переменные для устранения дублирования и написания более выразительного кода. Для примера, взгляните на Листинг 5.7 и Листинг 5.14, мы видим, что здесь есть повторяющийся вызов одного и того же цвета:

h2 {
  .
  .
  .
  color: #999;
}
.
.
.
footer {
  .
  .
  .
  color: #999;
}

В данном случае, #999 это светло серый цвет, и мы можем дать ему имя, определив переменную следующим образом:

$lightGray: #999;

Это позволяет нам переписать наш SCSS следующим образом:

$lightGray: #999;
.
.
.
h2 {
  .
  .
  .
  color: $lightGray;
}
.
.
.
footer {
  .
  .
  .
  color: $lightGray;
}

Поскольку названия переменных, такие как $lightGray являются более говорящими, нежели #999, часто бывает полезным определять переменные даже для не повторяющихся значений. Действительно, фреймворк Bootstrap определяет большое количество переменных для цветов, вы можете ознакомиться с ними онлайн на странице LESS variables. Эта страница определяеет переменные используя LESS, а не Sass, но гем bootstrap-sass обеспечивает нас их Sass эквивалентами. Угадать соответствие несложно; там где LESS использует знак "at" ( @), Sass использует знак доллара $. Глядя на страницу Bootstrap с переменными, мы видим, что переменная для светло-серого цвета уже существует:

@grayLight: #999;

Это означает, что, благодаря гему bootstrap-sass должна существовать соответствующая SCSS переменная $grayLight. Мы можем использовать ее для замены нашей кастомной переменной, $lightGray, что дает нам

h2 {
  .
  .
  .
  color: $grayLight;
}
.
.
.
footer {
  .
  .
  .
  color: $grayLight;
}

Применение Sass вложения и определения переменных ко всему SCSS файлу дает нам файл представленный в Листинге 5.16. Это использует Sass переменные (как определенные в Bootstrap) так и встроенные названия цветов (т.е., white для #fff). Обратите внимание, в частности, на кардинальное улучшение в правилах для тега footer.

@import "bootstrap";

/* mixins, variables, etc. */

$grayMediumLight: #eaeaea;

/* universal */

html {
  overflow-y: scroll;
}

body {
  padding-top: 60px;
}

section {
  overflow: auto;
}

textarea {
  resize: vertical;
}

.center {
  text-align: center;
  h1 {
    margin-bottom: 10px;
  }
}

/* typography */

h1, h2, h3, h4, h5, h6 {
  line-height: 1;
}

h1 {
  font-size: 3em;
  letter-spacing: -2px;
  margin-bottom: 30px;
  text-align: center;
}

h2 {
  font-size: 1.2em;
  letter-spacing: -1px;
  margin-bottom: 30px;
  text-align: center;
  font-weight: normal;
  color: $grayLight;
}

p {
  font-size: 1.1em;
  line-height: 1.7em;
}


/* header */

#logo {
  float: left;
  margin-right: 10px;
  font-size: 1.7em;
  color: white;
  text-transform: uppercase;
  letter-spacing: -1px;
  padding-top: 9px;
  font-weight: bold;
  line-height: 1;
  &:hover {
    color: white;
    text-decoration: none;
  }
}

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $grayMediumLight;
  color: $grayLight;
  a {
    color: $gray;
    &:hover {
      color: $grayDarker;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 10px;
    }
  }
}
Листинг 5.16. Начальный SCSS сконвертированный для использования вложенностей и переменных. app/assets/stylesheets/custom.css.scss

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

Вадим Обозин
Вадим Обозин

Здравствуйте, записался на курс. При этом ставил галочку на "обучаться с тьютором". На email пришло письмо, о том, что записался на самостоятельное изучение курса. Как выбрать тьютора?