Настало время познакомиться с препроцессором Stylus. Ниже привожу перевод статьи от David Walsh, посвященную малоизвестному, но крайне полезному препроцессору Stylus. Оригинал статьи размещен здесь - Getting Started with Stylus

Stylus

В среде web-разработчиков можно часто и постоянно слышать только о двух препроцессорах: Sass и LESS. Однако, существует еще один препроцессор, о котором слышно совсем не так часто - это Stylus. При редизайне Mozilla Developer Network мною был выбран Stylus по нескольким причинам:

  • так как Stylus основан на Node.js, то отпадает необходимость в использовании сторонней технологии (Sass требует для своей работы Ruby)
  • Stylus предоставляет набор JavaScript API, что делает возможным дальнейшую настройку этого инструмента
  • синтаксис Stylus не нуждается в скобках (brackets), запятых (comma), двоеточиях (colons), точках с запятыми (semicolon) - он целиком и полностью основан на использовании табуляции и пробелов; но если необходимо использовать любой из видов пунктуаций, то его можно легко применить в Stylus - компиляция произойдет корректно
  • под препроцессор Stylus имеется готовая библиотека миксинов (mixin) под названием Nib

Установка Stylus

Препроцессор Stylus является Open Source проектом, расположенным на GitHub, поэтому его можно легко установить как из исходных файлов, так и с помощью менеджера пакетов

1
npm
:

  $ sudo npm install stylus -g

CSS-файлы, созданные при помощи синтаксиса Stylus, должны иметь расширение

1
.styl
и могут располагаться в любом месте проекта. Препроцессор Stylus не имеет какого-либо конфигурационного файла, для начала компиляции достаточно запустить утилиту командной строки
1
stylus
с минимальным набором ключей:

$ stylus app/main.styl --out /dist --compress

Представленная выше команда выполняет компиляцию исходного stylus-файла

1
main.styl
в директорию
1
/dist
с тем же самым именем
1
main.styl
. Другими словами, файл
1
main.styl
компилируется в файл
1
main.css
и помещается в директорию
1
/dist
.

Утилита

1
stylus
может запускаться не только для однократной компиляции, но и отслеживать изменения файлов, выполняя компиляцию на лету; для этого имеется ключ
1
--watch
:

$ stylus --watch app/main.styl

Как можно догадаться, у программы

1
stylus
имеется гораздо больше опций, с полным списком которых можно ознакомиться здесь - Executable. В частности, с помощью нужных ключей можно выполнять обратную конвертацию из CSS в Stylus, сравнивать ввод\вывод и многое дугое.

Но приступим к рассмотрению самого главного, ради чего и затевался данный перевод - синтаксису и возможностям препроцессора Stylus

Основы синтаксиса Stylus

Синтаксис Stylus очень похож на синтаксис остальных препроцессоров (Sass или LESS). Но давайте более детально рассмотрим, что он из себя представляет на деле:

/*  Простая переменная  */
  base-font-size = 12px

/* Инициализация переменной с помощью вызова миксина */
body-background = invert(#ccc)

/* Селектор и набор правил для него */
body
  color #333
  background #fff

/* Вложенность правил */
nav
  margin 10px
    ul
      list-style-type none
        > li
          display inline-block
          &.current
            background-color lightblue

/* Использование вычисляемых значений */
div.column
  margin-right (grid-spacing / 2)
  margin-top (grid-spacing * 2)

/* Использование ранее установленного значения */
div.center-column
  width 200px
  margin-left -(@width / 2)

/* Задание значений, полученных как результат вычислений миксинов */
.promo
  apply-promo-style()
  apply-width-center(400px)

/* Итерация в цикле */
table
  for row in 1 2 3 4 5
    tr:nth-child({row})
      height 10px * row

/* Другой вариант итерации в цикле */
for row in (1..5)
  tr:nth-child({row})
    height 10px * row

/* Импортирование в Stylus-файл другой таблицы стилей в формате Stylus */
@import "links.styl"

/* extend существующего класса */
.warning
  @extend .block

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

Создание и использование миксинов

Миксины чрезвычайно полезны по нескольким причинам. Благодаря им при написании стилей на CSS можно использовать логику, а также структурировать код.

Создание миксинов в Stylus является простой задачей, а синтаксис миксинов именно такой, какой и ожидалось увидеть:

/* Простой миксин для добавления вендорных префиксов.

  Использование:
  vendorize(box-sizing, border-box)

*/

vendorize(property, value)
  -webkit-{property} value
  -moz-{property} value
  -ms-{property} value
  {property} value

При создании миксинов под Stylus можно задать значения по умолчанию для аргументов:

/* Миксин создания треугольника на CSS */

generate-arrow(arrow-width = 10px)
  &:before, &:after
    content ''
    height 0
    width 0
    position absolute
    border arrow-width solid transparent

Миксин может возвращать вычисляемое значение с помощью ключевого слова

1
return
или же возвращать стили, определенные внутри самого миксина. Такие стили можно применить к элементу, который вызывает этот миксин:

/* Миксин для задания стилей к текущему элементу и дочерним элементам текущего элемента */

special-homestyles(background = '#ccc')
  background-color background
    a
      color lightblue
    &.visited
      color navy

И конечно же, внутри миксинов можно использовать условия (впрочем, как и в любом другом месте кода на Stylus):

/* Миксин создания grid на основе минимального\максимального значений и инкремента */

generate-grid(increment,start,end,return-dimension=false)
  total = start
for n, x in 0..((end - start) / increment)
  if return-dimension
    if x+1 is return-dimension
      return total
        else
	  .column-{x+1}
	     width total
	total = total + increment

Представленный выше миксин генерирует grid на основе минимального значения (минимальной ширины столбца), максимального значения (максимальной ширины столбца) и количества столбцов (которое изменяется с помощью инкремента). Последний аргумент return-dimension служит для указания того, будет ли миксин просто возвращать полученное значение, не создавая CSS-классов.

Полезные миксины Stylus

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

Обнуление last child

Данный миксин был создан для обнуления пустого пространства у последнего элемента блока-родителя. Как правило, такими пространствами в CSS являются

1
padding-bottom
и
1
margin-bottom
.

/* Удаление пустого пространства у элемента, если он является последним у своего родителя */

prevent-last-child-spacing(element="*", property="padding-bottom")
  if element is "*"
    element = unquote(element)
      & > {element}:last-child
        {property} 0

С помощью этого миксина устанавливается

1
margin
или
1
padding
для блока-родителя. А затем просто убирается пустое пространство у последнего элемента этого блока.

Стилизация placeholder

Стилизация placeholder является достаточно хитрой задачей из-за необходимости использования вендорных префиксов, поэтому использование миксина значительно упрощает эту задачу:

  set-placeholder-style(prop, value)
   &::-webkit-input-placeholder
     {prop} value
   &::-moz-input-placeholder
     {prop} value

Заключение

На этом перевод закончен.

От себя могу добавить.

Под Sublime Text 3 имеется плагин Stylus для подсветки синтаксиса и автоматической табуляции. Если планируется дальнейшая работа в Stylus, то данный плагин обязателен к установке - без него просто тяжело и долго кодить.

Stylus Sublime Text

Плагин Emmet имеет поддержку синтаксиса Stylus (меня Emmet не перестает радовать). Все горячие клавиши Emmet остались неизменными и под Stylus, как если бы я кодил в старом добром CSS.

На моем любимом YouTube-канале Level Up Tuts недавно вышла небольшая серия видео-обзоров по Stylus - Stylus Tutorials

На этом все.


Продолжение предыдущей статьи “Стилизация SVG с помощью CSS - Часть 1”, посвященной формату векторной графики SVG.

Стилизация с помощью CSS

Между языками HTML и CSS существует четкая и ясная взаимосвязь: язык HTML предназначен для структуризации контента на странице; задача языка CSS - внешнее оформление этого контента. Формат SVG размывает четкие границы этой взаимосвязи. Например, формат версии SVG1.1 не нуждается в CSS для стилизации отдельных элементов SVG-объектов - для этой цели имеются так называемые презентационные атрибуты.

Презентационные атрибуты являются сокращениями CSS-свойств для SVG-элементов. Можно думать об этих атрибутах, как о CSS-свойствах для SVG с особым синтаксисом. К этим свойствам применима каскадность стилей, но в этой статье мы поступим более кратким способом.

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

1
"border" (stroke)
и фоновой заливки
1
"background color" (fill)
многоугольника в виде пятиконечной звезды:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="300px" viewBox="0 0 300 300">
  <polygon
    fill = "#FF931E"
    stroke = "#ED1C24"
    stroke-width = "5"
    points = "279.1,160.8 195.2,193.3 174.4,280.8   117.6,211.1 27.9,218.3 76.7,142.7 42.1,59.6 129.1,82.7 197.4,24.1 202.3,114 "/>
</svg>

Star SVG

В этом примере атрибуты

1
fill
,
1
stroke
,
1
stroke-width
являются презентационными атрибутами.

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

1
opacity
или
1
transform
. Другие же, такие как
1
fill
,
1
stroke
или
1
stroke-width
, абсолютно не похожи на свои CSS-аналоги.

В формате SVG2 имеются несколько презентационных атрибутов, таких как

1
x
,
1
y
,
1
width
,
1
height
,
1
cx
,
1
cy
и некоторые другие, которые невозможно задать с помощью CSS в SVG1.1. Список новых SVG-атрибутов можно посмотреть по этой ссылке - SVG2 спецификация.

Другим способом стилизации SVG-элементов является использование для этой цели CSS-свойств. Точно также, как и в случае в HTML-элементами, CSS-свойства могут быть заданы с помощью inline-стиля:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="width: 300px; height: 300px;" viewBox="0 0 300 300">
  <polygon
    style = "fill: #FF931E; stroke: #ED1C24; stroke-width: 5;"
    points = "279.1,160.8 195.2,193.3 174.4,280.8   117.6,211.1 27.9,218.3 76.7,142.7 42.1,59.6 129.1,82.7 197.4,24.1 202.3,114 "/>
</svg>

Каскады стилей SVG

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

Презентационные атрибуты позиционируются как “авторские стилевые правила” и могут быть переопределены любыми другими определениями: внешними таблицами стилей, внутренними таблицами стилей или же inline-стилями.

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

Таблица каскадности стилей SVG

Например, представленный ниже образец кода является кругом, написанным на SVG. Цвет заливки круга в виде атрибута

1
fill="blue"
будет переопределен цветом
1
deep pink
с помощью правила
1
style="fill:deepPink;"
:

<circle cx="100" cy="100" r="75" fill="blue" style="fill:deepPink;" />

Селекторы SVG

Большинство CSS-селекторов могут быть использованы для выборки SVG-элементов. В дополнение к основному типу, классам и идентификаторам, SVG-элементы могут быть стилизованы с помощью динамических псевдо-классов (

1
:hover
,
1
:active
,
1
:focus
) и псевдо-классов (
1
:first-child
,
1
:visited
,
1
:link
и
1
:lang
). Остальные псевдо-классы, включая тех, которые генерируют контент (такие как
1
::before
и
1
::after
) не являются частью спецификации SVG и поэтому не могут быть использованы для стилизации SVG-элементов.

Ниже приведен простой пример анимации фоновой заливки цветов круга при наведении. При этом используется селектор тега и псевдо-класс

1
:hover
.

Этот пример является простым, но можно создать и гораздо более сложные и интересные примеры. Еще одним простым, но интересным примером может послужить набор иконок Iconic, с помощью которых можно создать зажигающуюся лампочку. Демо-пример представлен здесь - demo of the effect .

Замечания

Так как презентационные атрибуты имеют XML-синтаксис, то они чувствительны к регистру. Например, при задании цвета заливки SVG-элемента атрибут должен быть записан как

1
fill="..."
, но не как
1
Fill="..."
.

Более того, ключевые значения этих атрибутов, такие как

1
italic
в
1
font-style="italic"
, также чувствительны к регистру и должны записываться в коде точно так, как это указано в спецификации.

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

1
<br>
,
1
<style>
или внешние таблицы стилей.

На этом все.


Краткий обзор плагина Sass CSS Importer для импортирования файлов CSS в файлы Sass.

В чем заключается вопрос? Как хорошо известно всем, кто постоянно работает с Sass, с помощью директивы

1
@import
можно подключать одни Sass-файлы в другие Sass-файлы.

Например, подключить файл

1
typography.scss
в файл
1
main.scss
можно так:

@import '_typography';

Оба файла

1
main.scss
и
1
typography.scss
будут объединены препроцессором в один файл
1
main.scss
, который уже будет компилироваться в файл
1
main.css
.

Знак подчеркивания в данном случае является дополнительной опцией. Этим знаком препроцессору Sass указывается не выполнять предварительную компиляцию файла

1
typography.scss
в файл
1
typography.css
перед его подключением в
1
main.scss
.

Но что, если стоит задача подключения файлов формата CSS в файлы формата Sass? Директива

1
@import
в этом случае помочь не может. CSS-файл нельзя просто так подключить в Sass-файл.

Задача подключения CSS-файлов в Sass-файлы наиболее часто может возникнуть в случае использования различных готовых слайдеров или каруселей, которые зачастую идут “в комплекте” с минимальными правилами на CSS. Что же делать?

Плагин Sass CSS Importer

Совсем недавно (17 июля сего года) Chris Eppstein выпустил специальный плагин, задачей которого и является импортирование CSS-файлов в Sass-файлы. Страничка с официальной документацией по плагину Sass CSS Importer расположена на GitHub - Sass CSS Importer Plugin.

Там все описано кратко и предельно ясно. Однако, я был так доволен тем фактом, что теперь могу свободно подключать CSS в Sass, что решил потратить часть своего времени, чтобы описать его своими словами, по-русски.

Установка Sass CSS Importer

Установка плагина выполняется как обычно, через менеджер пакетов

1
gem
:

$ sudo gem install --pre sass-css-importer

Подключение Sass CSS Importer

При использовании фреймворка Compass нужно добавить строку в конфигурационный файл

1
config.rb
своего текущего проекта:

require 'sass-css-importer'

Импортирование CSS в Sass

Теперь, чтобы импортировать CSS в Sass, нужно воспользоваться все той же директивой

1
@import
, но со специальным синтаксисом.

В общем случае этот синтаксис выглядит таким образом:

@import 'CSS:имя_директории/имя_css_файла';

В частном случае синтаксис будет выглядеть таким образом:

@import 'CSS:carousel';

Обратите внимание на важный момент: имя CSS-файла нужно указывать без расширения!

Можно запустить процесс компиляции через командную строку:

$ compass watch

… и проверить, что CSS-файл будет включен в общий вывод:

Плагин Sass CSS Importer

Заключение

В принципе, вот и все, что можно сказать о Sass CSS Importer.


Статья посвящена вопросу “тихих” placeholder’ов в препроцессоре Sass. Что это такое и в чем преимущество их использования.

Оригинал статьи размещен здесь - Understanding placeholder selectors.

Препроцессор Sass предоставляет несколько способов создания одного фрагмента кода, который будет многократно использоваться внутри CSS-кода.

Например, можно воспользоваться миксинами (

1
mixins
) для вставки группы CSS-свойств (или CSS-правил) в CSS-коде.

Или же использовать директиву

1
@extend
для расширения набора CSS-свойств одного HTML-элемента за счет CSS-свойств другого HTML-элемента.

В Sass версии 3.2 введена новая концепция под названием

1
placeholder
, которая делает использование директивы
1
@extend
еще более эффективным способом.

Но прежде чем мы перейдем к рассмотрению этого нововведенния, давайте остановимся на моменте, каким образом работает расширение (

1
@extend
) CSS-свойств в Sass.

Как работает @extend

Директива

1
@extend
в препроцессоре Sass позволяет CSS-селекторам с легкостью обмениваться между собой своими CSS-свойствами. Лучше всего вышесказанное можно проиллюстрировать на живом примере:

.icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  @extend .icon;
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  @extend .icon;
  /* здесь - специфичные стили класса .info-icon */
}

Результатом компиляции этого SCSS-кода в CSS-код будет следующий фрагмент:

.icon, .error-icon, .info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  /* здесь - специфичные стили класса .info-icon */
}

Рассмотрим “механизм” показанного выше примера более детально. В нем директива

1
@extend
играет ключевую роль. С помощью нее селекторы
1
.error-icon
и
1
.info-icon
наследуют свойства селектора
1
.icon
. При изменении CSS-свойств селектора
1
.icon
автоматически будут меняться свойства селекторов
1
.error-icon
и
1
.info-icon
, так как они наследуют определенный набор CSS-свойств у селектора
1
.icon
. Довольно изящный подход, не правда ли?

А вот теперь наступает интересный момент. Что, если элемент с классом

1
.icon
не планируется использовать и он даже не будет присутствовать в HTML-разметке? Но CSS-свойства этого элемента нам нужны для стилизации элементов
1
.error-icon
и
1
.info-icon
.

Получается, что результирующий CSS-код будет неоправданно раздут из-за того, что в нем присутствует “лишний” элемент, который напрямую никогда не будет использован.

И тут наступает момент для выхода на сцену героя этой статьи - селектора

1
placeholder
(его еще называют “тихим”
1
placeholder
‘ом):

Тихий placeholder

Знакомимся с селектором placeholder

Селекторы

1
placeholder
были введены в Sass как раз для того, чтобы решать вышеназванную проблему. Синтаксис
1
placeholder
очень похож на синтаксис обычных CSS-классов, только вместо точки (
1
.
) перед именем ставиться символ процента
1
%
.

Селекторы

1
placeholder
имеют одну специфичную для них особенность - они никак не проявляют себя в скомпилированном CSS-коде. Можно сказать по другому - вы никогда не найдете селекторов
1
placeholder
в результирующем CSS-коде (поэтому они и носят такое название - “тихие”
1
placeholder
). В скомпилированном CSS-коде будут только селекторы, которые используют “тихие”
1
placeholder
‘ы, но никак не сами “тихие”
1
placeholder
‘ы.

Вернемся назад, к нашему начальному примеру. Заменим в нем имя класса

1
.icon
на имя “тихого” placeholder’а -
1
%icon
:

%icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  @extend %icon;
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  @extend %icon;
  /* здесь - специфичные стили класса .info-icon */
}

В результате скомпилированный CSS-код будет выглядеть таким образом:

.error-icon, .info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  /* здесь - специфичные стили класса .info-icon */
}

Обратите внимание на важный момент - класс

1
.icon
теперь не присутствует в результирующем CSS-коде! Его там нет!

@extend или @include

На первый взгляд может показаться, что “тихие”

1
placeholder
- это почти тоже самое, что и миксины (
1
mixin
). С функциональной точки зрения такое утверждение абсолютно верно - результат в браузере получается идентичным. А вот с точки зрения CSS разница очень существенная!

Давайте снова изменим наш первоначальный пример и теперь воспользуемся миксином

1
@mixin icon
:

@mixin icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  @include icon;
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  @include icon;
  /* здесь - специфичные стили класса .info-icon */
}

Посмотрим на сгенерированный CSS-код:

.error-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
  /* здесь - специфичные стили класса .info-icon */
}

С точки зрения разработки данный пример ничем не хуже примера с использованием “тихого”

1
placeholder
‘а.

Но обратите внимание на тот факт, что CSS-правила

1
transition: background-color ease .2s;
и
1
margin: 0 .5em;
дублируются между селекторами
1
.error-icon
и
1
.info-icon
, что приводит к неоправданному раздутию кода. В случае использования “тихого”
1
placeholder
этого не происходит.

Ограничения

Использование директивы

1
@extend
имеет одно ограничение, связанное с тем, что применение “тихих”
1
placeholder
‘ов никак не оправдывает себя в медиа-запросах
1
@media
.

Рассмотрим такой пример:

%icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

@media screen {

  .error-icon {
    @extend %icon;
  }

  .info-icon {
    @extend %icon;
  }

}

Видим, что в данном случае “тихий”

1
placeholder
добавлен для селекторов, находящихся внутри медиа-запроса
1
@media
.

Однако, при попытке компиляции этого SCSS-кода в CSS-код получиться ошибка:

You may not @extend an outer selector from within @media. You may only @extend selectors within the same directive. From “@extend %icon” on line 8 of icons.scss

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

Механизм работы директивы

1
@extend
основан на добавлении одного селектора к другому селектору без необходимости дублировать CSS-свойства этих селекторов. Однако невозможно объединять селекторы, находящиеся в разных медиа-запросах
1
@media
.

Но можно поступить по другому, чтобы выйти из данной затруднительной ситуации. Любой медиа-запрос, который служит оберткой для “тихого”

1
placeholder
, распространяют свои свойства на селекторы, не размещенные внутри этого запроса.

Выражение достаточно запутанное, поэтому лучше приведу пример:

@media screen {
  %icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

.error-icon {
  @extend %icon;
}

.info-icon {
  @extend %icon;
}

Компиляция пройдет без ошибок и ее результатом будет CSS-код:

@media screen {
  .error-icon, .info-icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

Заключение

Обе директивы

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

Конечно же, ничто не мешает вам смешивать между собой директиву

1
@extend
и миксин
1
mixin
(если этого требуют обстоятельства):

@media screen {
  %icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

@mixin icon($color, $url) {
  @extend %icon;
  background-color: $color;
  background-url: url($url);
}

.error-icon {
  @include icon(red, '/images/error.png');
}

.info-icon {
  @include icon(blue, '/images/info.png');
}

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


В этом посте поделюсь своим опытом реализации задачи компиляции jade-файлов в HTML-формат.

Рассмотрю два способа реализации этой задачи. Первый - самый нативный, с помощью родной утилиты

1
jade
. Второй - с помощью плагина
1
gulp-jade
под Gulp.

Но способов компиляции Jade в HTML существует больше - есть плагин под Sublime Text, существует плагин под Grunt. Обладатели Mac OS X могут воспользоваться прекрасной программой CodeKit. И я уверен, что это только малая часть того, чем можно воспользоваться.

Кратко остановлюсь на вопросе, зачем мне понадобился Jade. Честно сказать, до недавнего момента я даже не подозревал о сущестовании такого шаблонизатора. Тихо-спокойно пользовался Sublime Text + Emmet и считал, что я на вершине современных требований к web-разработчику.

Однако это оказалось не совсем так. Мне посоветовали посмотреть в сторону Jade и разобраться с работой в нем. Хотя бы с синтаксисом, для начала.

И я скажу вам - мне понравилось! Даже простое использование синтаксиса. Первое впечатление и ощущение - использование этого шаблонизатора освобождает от рамок HTML при написании кода. Точнее - при создании кода сосредотачиваешься на содержимом, которое создаешь.

Но у Jade есть еще и миксины, с которыми мне предстоит познакомиться. Так что - лучшее только впереди!

Написание кода в этом шаблонизаторе чем-то похоже на написание текста в Markdown. Под Markdown имеются (и должны иметься) утилиты\программы для компиляции в HTML. Точно также для Jade должны иметься (и имеются) утилиты\программы для компиляции в HTML.

Jade - синтаксис для Sublime Text

Прежде чем писать код в редакторе, в моем случае необходимо настроить поддержку синтаксиса Jade. Я использую Sublime Text 3, который изначально не имеет таковой.

Исправить это легко - достаточно через

1
Package Control
установить пакет
1
Jade
. Помимо подсветки синтаксиса, появиться поддержка автоматической табуляции, что значительно упрощает процесс написания кода.

Пример подсветки синтаксиса Jade в Sublime Text:

Пример подсветки синтаксиса Jade в Sublime Text

Jade - родная утилита шаблонизатора

Разработчиками была создана родная утилита для преобразования jade-файлов в HTML-файлы. Имя утилиты легко запомнить - это

1
jade
.

Утилита является модулем под Node.js, поэтому последний у вас должен быть заранее установлен (если еще не установлен по какой-то необъяснимой причине).

Инсталляция утилиты производиться банально:

$ sudo npm install -g jade

Утилита имеет немногочисленные параметры, с кратким описанием которых можно ознакомиться на странице официальной документации - Jade - Command Line.

Но стоит обратить внимание на некоторые интересные параметры:

К примеру:

  • 1
    
    -P, --pretty
    
    - создание “удобочитаемого” HTML-кода
  • 1
    
    -w, --watch
    
    - мониторинг изменений файлов

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

1
templates
:

$ jade templates

Утилита может сама создавать jade-файлы:

$ jade {foo,bar}.jade

Или же можно реализовать два способа вывода:

$ jade > my.jade > my.html
$ echo "h1 Jade!" | jade

Или же осуществить рендеринг двух директорий

1
foo
и
1
bar
в директорию
1
tmp
:

$ jade foo bar --out /tmp

Gulp-jade - компиляция под Gulp

Кто знаком с task-manager’ом Gulp, тот может воспользоваться соответствующим плагином

1
gulp-jade
под него. Страничка плагина размещена здесь - gulp-jade.

Установка плагина стандартная:

$ npm install --save-dev gulp-jade

Затем нужно создать задачу (task) для компиляции jade-файлов в HTML-файлы. Ниже приведу свой рабочий task:

var gulp = require('gulp'),
jade = require('gulp-jade');

// Jade
gulp.task('jade', function(){
  gulp.src('./template/*.jade')
    .pipe(jade())
    .pipe(gulp.dest('./dist/'))
});

// Watch
gulp.task('watch', function(){
 gulp.watch('./template/*.jade',['jade']);
});

В Сети есть еще один интересный Gulp-task. Работоспособность его не проверял, взял как есть, для - “чтобы было”.

Как говориться на странице-оригинале, эта задача производит компиляцию файлов из директории

1
app/
в директорию
1
_public/
:

jade = require 'gulp-jade'

gulp.task 'jade', ->
  gulp.src parameters.app_path + '/*.jade'
  .pipe jade pretty: true
  .pipe gulp.dest parameters.web_path
  .on 'error', gutil.log

Заключение

Я запомнил (записал для себя), а вы (уважаемый читатель) познакомились (если не знали) с двумя способами настройки компиляции jade-файлов в HTML-файлы.

На этом все.