Быстрая инициализация проекта

Представьте себе фронтенд-разработчика типичной среднестатистической компании, занимающейся веб-разработкой. У него часто возникает ситуация, когда каждый следующий проект начинается с тех же самых действий, что и несколько предыдущих. Можно даже сказать, что 90-95% проектов в рамках одной такой компании начинаются приблизительно с одних и тех же действий с точки зрения разработчика. Поработав так некоторое время многие начинают задумываться над вопросом оптимизации рабочего процесса: как можно избежать клонирования одной и той же структуры файлов и каталогов вручную? Как избежать поиска и загрузки новых версий используемых библиотек и не писать новые конфигурационные файлы для любимых менеджеров задач, препроцессоров и других инструментов? Как можно автоматизировать этот процесс? Как сделать инициализацию проектов более быстрой, гибкой и безболезненной? Давайте об этом поговорим.

Скаффолдинг

Наиболее часто употребляемый перевод для термина scaffolding — «инициализация проекта». На самом деле, обычно, смысл его немного глубже. Скаффолдинг — это процесс инициализации проекта, включающий развёртывание файловой структуры проекта и генерацию некоторого (иногда опционального) количества кода, требуемого пользователю. А скаффолдер — это инструмент, реализующий этот самый процесс. Таким образом, в результате скаффолдинга вы получаете заданную структуру проекта, код, сгенерированный вашим инструментом (скаффолдером), и, возможно, некоторые опциональные инструменты, вроде автоматизации задач, пакетных менеджеров, тестировщиков и т.п. Но, случается, что скаффолдер нужен только для создания определённой файловой структуры проекта без включения дополнительных компонентов в него.

Инструментарий

Удобный инструмент — это самое важное в вопросе эффективного скаффолдинга. Я открыл для себя Yeoman, и постараюсь открыть его для вас. А также предложу к рассмотрению ещё пару альтернативных скаффолдеров: Volo и grunt-init.

Yeoman

Yeoman

Yeoman — пожалуй, самый популярный в последнее время скаффолдер, поэтому о нём поговорим подробнее. На самом деле, сам Yeoman — это не просто скаффолдер, а целый набор инструментов, которые отлично дополняют друг друга в процессе скаффолдинга и гармонично сочетаются в процессе разработки. Yeoman «стоит на трёх китах», задающих тон рабочему процессу современных разработчиков: скаффолдер Yo, менеджер пакетов Bower и менеджер задач Grunt. При установке Yo вам будут установлены также Bower и Grunt, если они не были установлены ранее.

Генераторы

Генератор Yeoman — это npm-пакет с инструкциями и шаблонами для Yo, которые описывают инициализацию проекта: какие директории создать, какие файлы и куда копировать, каким образом обрабатывать шаблоны и куда их разместить после обработки. В Yeoman шаблоны обрабатываются с использованием библиотеки Underscore.js.

На момент написания статьи в npm-репозитории уже доступно для установки более 300 генераторов. Устанавливаются они как обычные npm-пакеты с использованием команды npm install <generator-name>. В конце статьи я приведу небольшой список полезных генераторов.

Использование Yeoman

Самый простой способ понять, как именно инициализировать проекты с Yeoman — это начать его использовать. Я рассмотрю процесс скаффолдинга с использованием генератора generator-webapp и опишу использование каждого из трёх компонентов Yeoman.

Yo

Установка Yo выполняется командой:

npm install -g yo

После установки необходимо обзавестись генератором приложения, которое вы хотите инициализировать. Просмотреть список доступных для установки генераторов можно по ссылке или выполнив поиск пакета в npm по ключу «yeoman-generator»: npm search yeoman-generator. Если среди существующих генераторов нет ничего подходящего, можно написать свой генератор. Но об этом позже.

Как уже было сказано, я опишу процесс скаффолдинга на примере генератора webapp. Для его глобальной установки выполните:

npm install -g generator-webapp

Теперь можно пробовать развернуть каркас будущего веб-приложения. Для запуска скаффолдинга в заранее созданной директории проекта выполните:

yo webapp

Генератор выполняет скаффолдинг по сценарию, который зависит от действий пользователя. Обычно на выбор предлагаются некоторые фундаментальные вещи, от которых будет существенно зависеть дальнейший процесс работы над проектом. В случае с webapp нам будет предложено выбрать, хотим ли мы в проекте использовать Bootstrap для Sass, RequireJS и Modernizr.

webapp-setup

По завершении скаффолдинга вы получаете следующую структуру:

app/
node_modules/
test/
.bowerrc
.editorconfig
.gitattributes
.gitignore
.jshintrc
bower.json
Gruntfile.js
package.json

В директории app находится dev-версия вашего проекта — там содержатся все файлы в исходном состоянии, не прошедшие конкатенацию, минификацию и прочие обработки. Дальнейшая разработка проекта обычно не выходит за пределы этой директории.

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

Grunt

Как вы уже поняли, конкатенация, минификация и другие преобразования файлов, не требующие человеческого вмешательства выполняются при помощи инструмента Grunt. Если вы до сих пор не знакомы с ним, предлагаю для ознакомления прочесть пост в блоге Артёма Сапегина, вводный пост на сайте Smashing Magazine или краткое руководство на официальном сайте. Этого будет достаточно, чтобы начать его использовать. А пока вам необходимо знать только то, что запуск задач Grunt происходит по команде grunt [<задача>].

Генератор в процессе скаффолдинга устанавливает пакеты, необходимые для выполнения задач Grunt. Большинство генераторов создают достаточно объёмный Gruntfile.js, имея в распоряжении «багаж» полезных задач. Чтобы понять, какие задачи можно выполнять для проекта достаточно заглянуть в Gruntfile.js или выполнить grunt -h для директории с файлом Gruntfile.js. Webapp, например, имеет в качестве основных функциональных задач default, build, test, server.

Задача server выполняет очистку временной папки .tmp в корне проекта (создаёт её, если директория .tmp отсутствует), обрабатывает имеющиеся Sass-файлы и кладёт результат в .tmp/css, запускает слежку за изменением файлов в директории проекта, запускает сервер для обработки статичных файлов и открывает страницу проекта в браузере с возможностью запустить LiveReload, если у вас установлен плагин LiveReload для браузера. Эта задача обычно запущена во время работы над проектом.

Задача test собирает тестовую версию проекта, запускает тестировщик Mocha или Jasmine, в зависимости от того, что было выбрано при установке.

Задача default, которая также запускается по команде grunt, выполняет проверку JS-файлов из директории app/scripts на предмет ошибок с помощью JSHint и запускает задачу test.

Задача build выполняет компоновку релизной версии проекта с файлами, прошедшими конкатенацию, минификацию и переименование. Релизная версия проекта располагается в директории dist, которая будет создана в корне проекта при первом запуске этой задачи.

Стоит отметить, что если вы не используете в проекте RequireJS и хотите чтобы добавленные вами CSS-стили и JS-скрипты были доступны для автоматической конкатенации и минификации (если вы планируете использовать Grunt) их нужно записывать в index.html указывая тип файла и путь к нему в релизной версии проекта.

Важно понимать, что такое поведение — лишь частный случай генератора, т.к. в Webapp используется задача useminPrepare (плагин grunt-usemin), который берёт на обработку файлы, описанные в HTML-файлах особым образом.

Например, добавляя в проект app/css/main.css, который в релизной версии будет расположен по пути dist/css/main.css, мы должны добавить в index.html следующие строки:

<!-- build:css(.tmp) css/main.css -->
<link rel="stylesheet" href="css/main.css">
<!-- endbuild -->

Подобная ситуация и с JavaScript:

<!-- build:js js/vendor.js -->
<script src="bower_components/jquery/jquery.js"></script>
<!-- endbuild -->

Также можно осуществлять конкатенацию нескольких скриптов из dev- версии в один скрипт в релизной версии при помощи той же схемы:

<!-- build:js js/vendor.js -->
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/foundation/js/foundation/foundation.js"></script>
<!-- endbuild -->

Так нужно делать только в случае со всеми CSS-файлами и JS-библиотеками, добавленными в проект вручную. Инструмент Bower, который будет рассмотрен следующим, может автоматизировать процесс добавления библиотек в проект. Если ваш Gruntfile.js содержит задачу bower-install, то можно воспользоваться следующим алгоритмом:

  1. убедиться, что в HTML-файле имеется следующие комментарии:

     <!-- bower:js -->
     <!-- endbower -->
    
  2. установить требуемую библиотеку, выполнив:

     bower install jquery --save
    
  3. вызвать задачу bower-install:

     grunt bower-install
    

Bower установит необходимую библиотеку, попытается записать файл библиотеки между комментариями из пункта 1 и сообщит вам, удалось ли ему это.

Bower

Третьим немаловажным компонентом Yeoman является Bower — менеджер пакетов для веб-приложений. Этот инструмент упрощает поиск, установку и обновление библиотек для вашего проекта. В процессе скаффолдинга Bower позволяет генератору загружать необходимые версии библиотек, зависимости которых определены в файле bower.json. Часто bower.json представляет собой шаблон, обрабатываемый генератором во время инициализации проекта. В таком случае он способствует опциональной загрузке библиотек в процессе скаффолдинга. Завершив скаффолдинг проекта, вы сможете без лишних движений доставить требуемые библиотеки при помощи Bower.

Всё, что для этого нужно: команды bower search [<ключевое_слово>] и bower install <имя_пакета>. Установка пакетов идёт в директорию, путь к которой прописан в конфигурационном файле .bowerrc. C более тонкой настройкой Bower вы сможете ознакомиться тут.

Bower работает с протоколами Git и HTTP(S) и способен устанавливать пакеты как из репозитория, так и из простого zip-архива.

Некоторые могут задуматься над вопросом: «Зачем нужен Bower, если есть npm?». Наиболее подходящее объяснение описано на сайте и состоит в том, что основное его предназначение — довольно простое управление отдельными пакетами с точки зрения фронтенд-разработчика за счет плоского дерева зависимостей и удобный API, который может быть использован для реализации более опциональных рабочих процессов. К тому же, Bower имеет отдельную от npm-плагинов директорию в проекте, что позволяет разработчику версионировать проект вместе с установленными пакетами и игнорировать локально установленные плагины для Node.js, которые зачастую занимают внушительное дисковое пространство.

Свой собственный генератор

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

Полезные генераторы Yeoman

Volo

Volo будет рассмотрен менее подробно, так как он обладает меньшими возможностями, в отличии от Yeoman. Volo, как нам сообщают на сайте разработчика:

Volo — это инструмент, который даёт возможность быстро создавать проекты, добавлять библиотеки и автоматизировать простые задачи используя Node.js и JavaScript.

Посмотрим, что он может:

Создание проекта

volo create [<имя_проекта>] [<репозиторий> | <ссылка_на_шаблон>]

Примеры:

volo create foo h5bp/html5-boilerplate/4.0.0
volo create foo http://mozilla.github.com/mortar/builds/app-stub.zip

Подробнее об инициализации проектов с Volo можно прочесть в этой статье.

Добавление библиотек в проект:

volo add jquery
volo add backbone
volo add requirejs/~2
volo add amdjs/backbone

Подробнее о добавлении библиотек

Для описания автоматизации процесса сборки проекта Volo использует свой конфигурационный файл — volofile. При этом, естественно, необходимо предварительно установить node-плагины, используемые для автоматизации задач таких, как jshint или uglify-js. Подробнее об автоматизации с Volo можно узнать здесь.

Скаффолдинг с Grunt-init

Grunt-init — инструмент от разработчиков Grunt, позволяющий разворачивать проекты, используя шаблоны. То, что в Yeoman называлось генераторами, у grunt-init называется шаблонами. Для установки плагина вам необходимо выполнить:

npm install -g grunt-init

Использование grunt-init концептуально ничем не отличается от других скаффолдеров. Вам аналогично необходимо загрузить шаблон и запустить скаффолдер. Однако, grunt-init имеет специфику в установке шаблонов. Процесс установки шаблона заключается в клонировании git-репозитория c исходным кодом шаблона в директорию ~/.grunt-init/. Выполнив клонирование шаблона, можно запускать скаффолдер командой:

grunt-init <TEMPLATE_NAME>

Небольшой список доступных шаблонов можно найти на официальном сайте, а также в репозитории Артёма Сапегина.

Кроме того, вы можете написать свой шаблон. Подробные инструкции можно найти на том же официальном сайте и в блоге Артёма Сапегина.