15 января 2016 г.

Приручаем хрюшку


Немного ранее я писала статью по настройке окружения для начала разработки на Angular JS.

Сейчас предлагаю немного подробнее разобраться с такой штукой, как Grunt. Сам по себе он ничего практически не умеет. Он умеет делать только одно — запускать таски.


Навигация

  1. Структура проекта
  2. Установка Grunt
  3. Запуск сервера и LiveReload
  4. Таски для dev
    1. Copy
    2. Clean
    3. Wiredep

Структура проекта


Итак, у нас есть такая структура проекта:


Структура проекта


Описание каталогов:

  • app: исходные файлы проекта — скрипты, стили, вёрстка
  • dist: собранный проект, который можно уже использовать на production — используется минификация, обфускация и подобное
  • server: проект, который собран частично — из этого каталога запускается develop server
  • tmp: тут по названию понятно

Установка Grunt


Как я упоминала ранее, Grunt сам по себе ничего не делает, а просто запускает задачи, прописанные и настроенные в Gruntfile.js. Предположим, что Node.js у вас уже установлен. Если нет — то можете посмотреть в этой статье (шаг первый).

В систему нужно установить сам Grunt, вернее инструменты командной строки для него. Это делается только один раз на систему.
npm install -g grunt-cli
Устанавливаем Grunt как зависимость для нашего проекта. А вот это уже для каждого проекта.
npm install grunt --save-dev
Все запускаемые таски для Grunt являются модулями для Node.js. Поэтому, чтобы их можно было использовать, их надо устанавливать через npm install.

В первую очередь устанавливаем task loader. Это специальный модуль, который позволяет импортировать в Grunt все нужные модули тасков в одну строчку. Подробнее можно посмотреть тут
npm install load-grunt-tasks --save-dev
Ну вот, теперь можно начать настраивать наш Gruntfile.js. Для начала зарегистрируем свою задачу и назовём её server. В итоге наш файл будет выглядеть следующим образом:



Теперь можно даже запустить нашу таску, которая ничего не делает ) Из каталога, где находится наш Gruntfile.js открываем консоль и пишем:
grunt server
В Grunt есть два вида задач, скажем так.

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

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

Запуск сервера и Live Reload


Теперь создадим 2 таски. Первая запускает сервер (называется connect), а вторая отслеживает изменения в файлах проекта и автоматически перезагружает страницу в браузере (работает по сокету, называется watch).
npm install grunt-contrib-connect serve-static --save-dev
npm install grunt-contrib-watch --save-dev
Теперь добавляем необходимую конфигурацию для них в Gruntfile.js.



Наш супер проект доступен по адресу http://localhost:9000

В данном случае используется grunt-contrib-connect версии 0.11.x. Для его работы нужен serve-static. Объясню подробнее про строки 32 и 33.

serveStatic('app')
указывает, с какого каталога нужно смотреть файлы (относительно base, по умолчанию он смотрит на тот каталог, в котором находится Gruntfile.js). Так что когда запустите http://localhost:9000, то отобразится ./server/index.html.

connect().use('/bower_components', serveStatic('./bower_components'))
тут немногосложнее. Каталог bower_components находится в том же каталоге, что и Gruntfile.js, так что по хорошему к нему надо обращаться как ../bower_components. Но это не получится, т.к. мы попадаем на путь выше базового. Но достучаться до него нам надо (о самом bower будет чуть позже). Так что тут получается такой «маппинг», спрашиваем путь ./bower_components, а получаем содержимое ../bower_components.

Узнать про настройки можно в описании в репозитории проектов:
https://github.com/gruntjs/grunt-contrib-connect
https://github.com/gruntjs/grunt-contrib-watch

Таски для dev


Copy


Чем отличается dev от production? В production обычно необходимо сделать минификацию и обфускацию скриптов и css. В то же время для разработки нам это не надо, т.к. нужно всё это дебажить. Поэтому мы сделаем 2 основные таски:
  • server для dev
  • build для production
Т.к. часто используется less, который надо компилировать всегда (и для dev, и для production), а так же будут специальные настройки в самом index.html (об этом будет чуть позже), то для dev server и production build нам понадобятся несколько дополнительных каталогов в проекте. Они были описаны выше. А сейчас добавим настройки в Gruntfile.js, чтобы он знал про них. Добавим такую штуку:



Не забывайте, что это всё обычный JavaScript, который выполняется в среде Node.js. Итак. Теперь нам нужно скопировать рабочие файлы из нашего проекта в каталог server. Пока что будем копировать как есть. Для этого есть таска grunt-contrib-copy. Устанавливаем и настраиваем:
npm install grunt-contrib-copy --save-dev



Теперь немного пройдёмся по настройкам.
cwd: '<%= config.app %>' // откуда копируем
Тут надо подробнее объяснить, что означает '<%= config.app %>'. Если посмотрите на строку 17, то увидите, что мы создали ссылку на наш список каталогов (config). Таким образом наша строка зарезолвится в значение, которое указано в config.app (т.е. в 'app'). Аналогично можно ссылаться на значения, которые указаны в конфигурациях тасков ('<%= connect.options.port %>' например).
dest: '<%= config.server %>/' // куда копируем
Тут аналогично, ничего нового не добавилось.
src: ['**', '!**/*.less'] // что копируем
А тут тоже подробнее объясню. Фактически это обозначает «скопировать все файлы, кроме файлов с расширением '.less' и не важно, в каком каталоге они находятся». Для указания паттернов путей или файлов используется такая штука как node-glob.

Clean


Любому опытному разработчику ясно, что все эти папочки с билдами, временными файлами нужно очищать. Сейчас мы такую штуку сделаем. Устанавливаем и настраиваем, как всегда.
npm install grunt-contrib-clean --save-dev



Я уже не добавляла сюда весь файл, а только изменения. Теперь каждый раз при запуске сервера, наш каталог будет очищаться и туда скопируются файлы с нуля. Это очень полезно, чтобы не оставались устаревшие файлы, из-за которых потом могут быть проблемы (вы внесли нужные изменения, а оно не работает оО).

Wiredep


Вот это будет очень интересная таска. При разработке UI части проекта, могут использоваться различные сторонние js-библиотеки или темы со стилями. Ручками их скачивать и добавлять в проект слишком муторно (все программисты ленивые же).


Wiredep аботает вместе с bower. Bower — система для управления зависимостями в js-проектах (например, стили bootstrap или библиотека jquery).

npm install grunt-wiredep --save-dev



Для того, чтобы посмотреть, как это работает, добавим jquery и bootstrap с помощью bower. Про установку и инициализацию bower в проекте смотрите тут.

bower install jquery --save
bower install bootstrap --save

Wiredep для включения зависимостей в html-файл использует специальные комментарии. Выше в настройке самой таски указан файл, который надо обработать (src: ['<%= config.server %>/index.html']). Вот таким образом он будет сейчас выглядеть:



Запускаем сервер
grunt server

Смотрим в server/index.html:



Упс… Скрипты есть, а куда же подевались стили? Вообще да, bootstrap немного странно работает с bower. И тут надо кое-что подправить. Wiredep в процессе работы смотрит в файл bower.json. Вот его то мы и подправим.



Перезапускаем наш сервер, и теперь server/index.html выглядит так:



Что мы тут сделали? Обычно bower зависимости поставляются не только в виде готового для употребления js- или css-файла, но и с исходниками или другими сопутствующими файлами (например, шрифтами). Естественно из всего этого добра нам в html-файл нужно включить только часть. Вот именно эту информацию для wiredep’а мы и подправили. Кстати, теперь у нас не включился bootstrap’овский js-файл (будет вам небольшое домашнее задание исправить это ;)

Вообще это не всё. Даже для dev ещё много чего есть. Об этом я буду писать позже. А потом ещё и для production. Так что не расслабляйтесь (а точнее мне надо не лениться и писать дальше).

Комментариев нет:

Отправить комментарий