Сайт вебмастера

LESS-компиляция через Node.js и Grunt

09-12-2015Reading time ~ 5 min.CSS, HTML, LESS, SASS 14146

Смысл этой затеи в том, чтобы автоматизировать компиляцию less-файлов. Работать должно так: сохранили любой less-файл, сам запускается компилятор и на выходе получается готовый css-файл. Сейчас я расскажу про вариант, который может использоваться любым вебмастером, но самое главное, что он универсальный и подходит и для других целей, например компиляция SCSS.

Перед началом, давайте определимся с основными понятиями.

Всё будет работать на Node.js. Node.js — это интерпретатор JavaScript. То есть исходные/исполняемые файлы для Ноды — это js-файлы. По большому счёту, нам вообще всё-равно как там что работает. Для нас главное — установить Node.js на свой компьютер. Делается это очень просто — загружается msi-файл с официального сайта и устанавливаем как обычную windows-программу.

Сразу отдельное замечание о том, как обновлять Node.js. В теории он может обновить себя сам. На практике же, проще скачать новую версию и её установить. Тогда никаких проблем не возникает.

В комплекте Node.js есть т.н. пакетный менеджер npm. Он позволяет устанавливать, удалять, обновлять и т.п. модули Node.js. Модули или пакеты — это что-то вроде программ, ради которых всё это безобразие и затевалось. Например Grunt — это модуль для автоматизации различных задач.

Работать с Node.js придется командной строкой через консоль. Стандартная консоль Windows — вещь не для слабонервных, поэтому я рекомендую поставить альтернативную. Сам я пользуюсь conemu. Консоль годится не только для Node.js, но и для кучи других задач. Для удобства conemu можно добавить в панель Total Commander.

Проверить работу Node.js можно выполнив команду

node -v

— которая выводит свою версию.

Для less-компиляции нужно установить модуль less. Делается это командой:

npm install -g less

Эта команда выполняет установку (install) модуля «less». Ключ «-g» указывает выполнить установку глобально. Если не указывать этот ключ, то установка модуля будет осуществляться только в текущий каталог. Таким образом делается установка любого другого модуля. Node.js сам скачивает через Интернет нужные файлы.

У модуля могут быть свои плагины. Например у «less» есть плагин сжатия css «less-plugin-clean-css». Устанавливается он точно также:

npm install -g less-plugin-clean-css

После такой установки в консоли будет доступна команда lessc, которой и выполняется ручная компиляция less-файлов.

Модули могут использовать другие модули (пакеты). Причём каких-то определенных версий. Человеческий мозг не в состоянии охватить всё это великолепие взаимодействие, поэтому все эти зависимости прописываются в самих модулях разработчиками. Отсюда получается, что устанавливая какой-то модуль, будет автоматом установлен еще один, там еще и т.д. В итоге модулей может оказаться довольно прилично. Я об этом специально упоминаю, потому что требуемый модуль может весить 2МБ, а подтянет за собой ещё 20МБ.

Сложность ещё в том, что все требуемые модули располагаются в каталоге проекта. Ну например, less-компиляция. Если у нас 10 шаблонов, то придется настроить все 10 проектов в каждом каталоге шаблона. То есть к 200КБ less-файлов придется таскать по 20МБ node-файлов.

Как обхитрить это недоразумение, я расскажу ниже, пока же рассмотрим еще одну особенность работы с Node.js.

Для того, чтобы управлять пакетами в проекте (проект — по сути это просто рабочий каталог), используется специальный файл package.json. В нём задаются настройки проекта, включая и используемые модули. То есть перед тем, как запустить Node.js для проекта, нужно создать package.json. Вот пример файла, который мы будем использовать для Grunt:

{
   "author" : "author",
   "name" : "ProjectName",
   "version" : "1.0.0",

   "devDependencies" : {
      "grunt" : ">= 0.4",
      "grunt-cli" : ">= 0.1.6",
      "grunt-contrib-watch" : "~0.3.1",
      "grunt-contrib-less" : ">=0.12.0"
   }
}

Секция devDependencies как раз и указывает какие модули будет использовать проект.

Инсталяция/инициализация проекта выполняется командой:

npm install

После этого Node.js немного пошурстит и в результате появится каталог node_modules. Этот каталог (и package.json) можно просто копировать между одинаковыми проектами без инсталяций.

Теперь поговорим о Grunt.

Grunt используется для автоматизации самых разных задач. Там гиганское количество плагинов и я предлагаю просто пробежаться глазами, чтобы оценить всю мощь этого инструмента. Нас будут интересовать grunt-contrib-less, который выполняет задачу less-компиляции и grunt-contrib-watch, который отслеживает каталоги на изменения и запускает нужные задачи (в нашем случае less).

Установить Grunt можно такими командами:

npm install -g grunt-cli
npm install -g grunt-contrib-less --save-dev
npm install -g grunt-contrib-watch --save-dev

Настраивать Grunt в проекте нужно через файл Gruntfile.js. Для основы возьмем такой вариант:

module.exports = function(grunt) {
   grunt.initConfig({
      less: {
         development: {
            options: {
               compress: true,
               yuicompress: true,
               optimization: 2
            },
            files: {
               // target.css file: source.less file
               "css/main.css": "less/main.less"
            }
        }
   },
   watch: {
      styles: {
         files: ['less/**/*.less'], // which files to watch
         tasks: ['less'],
         options: {
            nospawn: true
         }
      }
   }
});

grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');

grunt.registerTask('default', ['watch']);
};

В секции watch в параметре files указывается маска (можно явно файл) для less-файлов в каталоге less. Все пути указываются относительно каталога проекта.

В секции less задаются непосредственно параметры компиляции. Здесь указан исходный и конечный файлы: less/main.less скомпилируется в css/main.css.

После этого запускаем Grunt командой:

grunt

Если не было ошибок, то появится что-то вроде этого

Running "watch" task Waiting...

Теперь изменим less/main.less и увидим сообщение

Completed in 2.752s at Wed Dec 09 2015 13:07:24 - Waiting...OK
File "less/main.less" changed.

То есть любые изменения в less, автоматом приводят к компиляции css-файла. Чтобы остановить отслеживание, нажмите Ctrl+C.

Когда у вас 1-2 проекта, то в принципе можно на node_modules не обращать особого внимания. Но, когда проектов десятки, да ещё и в разных местах, то это уже проблема. Чтобы обойти это безобразие я придумал небольшую хитрость. Дело в том, что Grunt позволяет одновременно отслеживать несколько каталогов и не обязательно в каталоге проекта.

Таким образом можно создать проект где-то совершенно отдельно (вообще пофиг где), а в задачи Grunt добавить пути к нужным нам less-каталогам (например шалоны MaxSite CMS). Делается это в Gruntfile.js так (показываю только изменные строчки):

less: {
	...
           files: {
               "d:/xampp/htdocs/cms/application/maxsite/templates/default/assets/css/style.css": "d:/xampp/htdocs/cms/application/maxsite/templates/default/assets/less/style.less",
 
               "d:/xampp/htdocs/cms/application/maxsite/templates/d2000/assets/css/style.css": "d:/xampp/htdocs/cms/application/maxsite/templates/d2000/assets/less/style.less"
            } 
	...
	
watch: { 
	...
        files: [
		'd:/xampp/htdocs/cms/application/maxsite/templates/default/assets/less/**/*.less',
		'd:/xampp/htdocs/cms/application/maxsite/templates/d2000/assets/less/**/*.less'
	],
...

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

В conemu, кстати, есть пункт меню «Hide to TSA», который сворачивает консоль в иконку «к часикам» и не маячит на панели задач. Довольно удобно получается.

Related Posts