Nginx / [Из песочницы] Серверный процессинг LESS файлов «на лету» своими руками

в 12:19, , рубрики: css, less, nginx, node.js, метки: , , ,

LESS — это популярный препроцессор для языка CSS, добавляющий возможности использовать константы, наследование, вложенные стили и много другое, чего так не хватает в CSS. Как только я познакомился с LESS я понял что это то, что мне нужно. Единственное, что омрачило мою радость — разработчики предлагают всего два варианта его использования: встраивать JavaScript файл, который занимается препроцессингом прямо в браузере или использовать специальный скрипт (который должен исполняться на node.js) который процессирует LESS файлы.
Вариант c процессингом LESS файлов на клиенте мне не понравился тем, что для больших LESS файлов это вызывает ощутимые паузы при загрузке страницы. Если использовать LESS версию твиттерного bootstrap-a — загрузка увеличивается на несколько секунд, что абсолютно недопустимо.
Вариант с предварительной компиляцией меня не устраивал тем, что приходится «вручуную» запускать препроцессор. Я видел программу, которая автоматически перегенерирует LESS файлы при их изменении, но она оказалась платной и только под МакОСь.
Мне же хотелось, чтобы LESS файлы процессировались на лету по запросу веб-сервером и, следовательно, подключались также, как и css. Такой подход лишен всех недостатков описанных выше. Однако, в этом случае чуть сложнее наблюдать за ошибками в синтаксисе LESS файлов: их можно будет видеть только в логах процессирующего сервера. Однако ошибки именно в синтаксисе LESS файлов у меня случались крайне редко, так что это не стало проблемой.
Решение

К своему сожалению, я не нашел процессоров LESS файлов ни на Python, ни на Java (языки, на которых я разрабатываю). Поэтому я просто написал маленький http-сервер на node.js, котрый использует код «официального» процессора LESS файлов и процессирует файлы «на лету». При таком подходе, правда, приходится перенаправлять раздачу less файлов на отдельный сервер, а значит без nginx не обойтись. В принципе, можно использовать и другие сервера (например lighttpd), но nginx мне ближе и далее все примеры конфигураций я буду рассматривать для него.
За основу я взял скрипт lessc — консольный процессор LESS файлов, незначительно его модифицировав и сохранив все параметры запуска (позволяющие, например, сжимать генерируемый CSS). Исходный код написанного мной сервера. Он стартует на порту 1337 и любой запрос трактует как относительный путь до .less файла, который процессирует и отдает.
Далее настроил nginx так, чтобы все less файлы проходили процессинг на полученном http-сервере:
location ~ .less$ {
proxy_path http://127.0.0.1:1337;
}

Все! Тепепрь можно спокойно использовать LESS в своих проектах, не боясь за время загрузки и не вызывая препроцессор вручную. Просто вставляю .less файлы как обычные .css:

Кеширование

Процессировать LESS файл на каждый запрос на боевом сервере, безусловно, слишком накладно. Тут нас спасет возможность nginx кешировать ответы стоящих «за ним» серверов: в этом случае результат обработки LESS файлов будет кешироваться nginx-ом (на файловой системе) в течении заданного периуда времени, например 30 секунд. Один раз в 30 секунд процессировать LESS файлы не нагрузит систему, а 30 секундные задержки при обновлении файла со стилями обычно вполне допустимы (при желании можно выбрать и меньшее время хранения кеша).
Конфигурация nginx изменится следующим образом:
# Где хранить кеш, параметры кеширования + название конфигурации кеша
# Подробно: http://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_cache_path
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=microcache:5m max_size=1000m;
server {
# ... Тут ваша конфигурация сервера
#
location ~ .less$ { # фильтруем файлы с расширением .less
proxy_cache microcache; # активируем кеширование (на основе конфигурации microcache) только для раздачи .less файлов
proxy_cache_valid 200 30s; # включаем кеширование ответов сервера с кодом 200 (ОК) в течении 30 секунд
proxy_pass http://127.0.0.1:1337; # перенаправляем запрос на http-серер занимающийся процессингом
}
}

Пошаговая инструкция

Рассмотрим теперь кратко, по шагам, что нужно сделать, что бы развернуть такое у себя:Устанавливаем node.js. На линуксе — ставим из репозиториев, на мак и вин ставим с оффсайта

Устанавливаем (если еще не используется) nginx и конфигурируем на раздачу вашего сайта

Скачиваем c github исходники LESS процессора

Берем исходный код http-сервера и кладем его в скаченную папку с LESS процессором в поддерикторию bin

Находясь в директории bin в исходниках LESS запускаем http-сервер командой
node lessserv --path=/path/to/project/root

После --path= идет путь до корня вашего проекта, откуда будут раздаваться .less файлы. Все ошибки в процессировании будут выводиться в консоль.
Перенаправляем все запросы к .less файлам через запущенный http-cервер
location ~ .less$ {
proxy_path http://127.0.0.1:1337;
}

На боевом сервере включаем кеширование для результатов обработки .less файлов

Ссылки

Официальная страница LESS с описанием языка

Главная страница node.js, на которой написан пример простейшего http-сервера

Статья про кеширование в nginx

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js