Современные инструменты фронтенда и каркас Angular.js приложений

Illustration of a person sitting on the floor, leaning against a wall, engrossed in reading a book, wearing casual attire with orange sneakers. Illustration of a person sitting on the floor, leaning against a wall, engrossed in reading a book, wearing casual attire with orange sneakers.

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

На картинке мы видим структуру приложения, в котором все javascript файлы хранятся в одной папке, без какого либо разделения на логические составляющие. В index.html – подключение этих файлов кучей тэгов <script>. Далеко с таким подходом уйти не получится: файлов будет всё больше и поддерживать такое приложение станет в разы сложнее. Другие разработчики в проекте будут путаться, им придется каждый раз разбираться, что где и как.

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

Инструменты для фронтенд-разработки

Первый из них – Yeoman. Это программа для генерации кода, аналогичная генераторам из Ruby on Rails. Генераторы позволяют при помощи простых команд в консоли создавать новые приложения с определенной структурой папок, избавляя от необходимости делать это вручную и упрощают следование стандартам в организации кода. К Yeoman написано множество генераторов, в том числе для Angular.js приложений, Ember.js приложений, простых приложений с использованием jQuery и т.п.

Второй инструмент – Gulp.js. Его можно сравнить с Rake из мира Ruby: Гульп позволяет описывать различные задачи, которые нужно выполнять во время разработки: например, компиляция итоговых css и js файлов или автоматическое обновление страницы браузера после изменений этих файлов, что экономит время разработчика.

В Angular.js уже встроена поддержка модулей, поэтому нам не нужно использовать такие инструменты как Browserify или require.js чтобы управлять зависимостями между модулями.

Для того чтобы установить Yeoman и Gulp.js нам понадобится npm. npm – это менеджер пакетов для node.js, который, в свою очередь, является движком для написания серверных javascript приложений. Мы будем использовать npm для установки всех наших зависимостей при разработке.

Ещё нам понадобится Bower, ещё один менеджер пакетов, от Twitter. Bower предназначен для установки зависимостей, необходимых во фронтенде. Например, различные jQuery плагины или Angular.js библиотеки. Приемущество использования Bower для таких зависимостей заключается в том, что Bower не скачивает вложенные зависимости, поэтому каждая библиотека будет установлена только один раз. Это очень важно для конечного пользователя – никто не хочет скачивать пять версий jQuery.

Генерация Angular.js приложения

Начнём с установки node.js и npm. Если у вас Mac, то вы можете сделать это командой brew install node. Если у вас Ubuntu, то вы можете установить пакет при помощи apt-get install node. Для всех методов установки проверьте официальный сайт node.js – http://nodejs.org/.

Вместе с node.js установится и npm, а значит мы можем сразу перейти к установке Yeoman, Gulp и Bower. Делается это командой npm install yo bower gulp -g. Опция -g устанавливает пакет как глобальный. Это позволяет использовать командные утилиты из под любой директории в вашей системе. В противном случае зависимость будет скачана в текущую папку в подпапку node_modules. Если высветится ошибка, что Gulp не найден в папке с проектом, попробуйте выполнить npm link gulp.

Теперь нам нужно установить генератор для Yeoman. Вместо официального Angular.js генератора мы воспользуемся его копией, в которой используется Gulp. Альтернативой Gulp мог бы быть Grunt.js. Grunt.js похож на Gulp, но работает медленнее из-за того, что он не использует потоки node.js. Он так же более сложен в использовании.

Выполняем npm install -g generator-gulp-angular и на этом заканчиваем установку первого набора нужных нам пакетов.

Переходим к генерации приложения. Создадим новую папку ngmkdev и в ней выполним yo gulp-angular. Генератор предложит нам указать отдельные параметры нашего приложения:

  1. Выбираем latest версию Angular.js.
  2. Из дополнительных Angular.js модулей нам ничего не понадобится, поэтому пропускаем выбор angular-animate, angular-cookies, angular-touch и angular-sanitize.
  3. Выбираем jQuery 2.x. В Angular.js уже встроена облегчённая версия jQuery – jqLite. Но нам возможно понадобятся более продвинутые функции jQuery, поэтому подключим полноценную библиотеку.
  4. Так как мы планируем работу с JSON API, то нам понадобится библиотека для удобной работы с ним. Из двух вариантов наиболее популярен в сообществе и содержит больше фич Restangular, поэтому остановимся на нём.
  5. По тем же причинам выбираем UI Router вместо официального роутера.
  6. Чтобы не писать интерфейс самостоятельно мы будем использовать Twitter Boostrap. Это ускорит время вёрстки и сделает наше приложение чуть более красивым.
  7. Раз выбрали Bootstrap, то на будущее выберем на следующем шаге Angular UI Bootstrap
  8. Выберем the good old css на данный момент.
  9. Так же обойдёмся без CoffeeScript (мы его любим, но вдруг вы его ещё не знаете?)
  10. Мы будем использовать standard HTML.

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

Разбор структуры Angular.js приложения

На генерацию уйдёт какое-то время, по прошествии которого мы получим каркас для нашего приложения. Посмотрим что именно у нас сгенерировалось.

package.json

Файл package.json содержит различные метаданные о вашем проекте: имя проекта, версия, описание.

dependencies – пока что пустой список зависимостей проекта.

devDependencies – это зависимости, необходимые для разработки приложения. Не факт, что мы будем использовать все зависимости, которые там сгенерировал Yeoman, но часть из них точно пригодится, а лишние можно будет удалить потом.

engines указывает версию node.js, которую мы (неявно) будем использовать.

{
  "name": "ngmkdev",
  "version": "0.0.0",
  "dependencies": {},
  "devDependencies": {
    "gulp": "~3.8.10",
    "gulp-autoprefixer": "~2.0.0",
    "gulp-angular-templatecache": "~1.4.2",
    "del": "~0.1.3",
    "gulp-consolidate": "~0.1.2",
    "gulp-csso": "~0.2.9",
    "gulp-filter": "~1.0.2",
    "gulp-flatten": "~0.0.4",
    "gulp-jshint": "~1.9.0",
    "gulp-load-plugins": "~0.7.1",
    "gulp-size": "~1.1.0",
    "gulp-uglify": "~1.0.1",
    "gulp-useref": "~1.0.2",
    "gulp-ng-annotate": "~0.3.6",
    "gulp-replace": "~0.5.0",
    "gulp-rename": "~1.2.0",
    "gulp-rev": "~2.0.1",
    "gulp-rev-replace": "~0.3.1",
    "gulp-minify-html": "~0.1.7",
    "gulp-inject": "~1.0.2",
    "gulp-protractor": "~0.0.11",
    "gulp-karma": "~0.0.4",
    "gulp-angular-filesort": "~1.0.4",
    "main-bower-files": "~2.4.0",
    "jshint-stylish": "~1.0.0",
    "wiredep": "~2.2.0",
    "karma-jasmine": "~0.3.1",
    "karma-phantomjs-launcher": "~0.1.4",
    "require-dir": "~0.1.0",
    "browser-sync": "~1.7.1",
    "http-proxy": "~1.7.0",
    "chalk": "~0.5.1",
    "protractor": "~1.4.0",
    "uglify-save-license": "~0.4.1"
  },
  "engines": {
    "node": ">=0.10.0"
  }
}

bower.json

В bower.json хранятся зависимости, необходимые для конечного пользователя. Как уже было сказано раньше, Bower не скачивает вложенные зависимости, что делает его идеальным для фронтенд-зависимостей вашего приложения. Здесь мы видим, например, указанные ранее jQuery, Twitter Boostrap, Restangular.

{
  "name": "ngmkdev",
  "version": "0.0.0",
  "dependencies": {
    "jquery": "~2.1.1",
    "restangular": "~1.4.0",
    "angular-ui-router": "~0.2.13",
    "bootstrap": "~3.3.1",
    "angular-bootstrap": "0.12.x",
    "angular": "~1.3.4"
  },
  "devDependencies": {
    "angular-mocks": "~1.3.4"
  },
  "resolutions": {
    "jquery": "~2.1.1",
    "angular": "~1.3.4"
  }
}

gulpfile.js

gulpfile.js всего лишь подключает все файлы из папки gulp/. В этой папке содержатся различные задачи, выполняемые Gulp.js. Например, gulp/build.js собирает итоговое приложение, готовое к использованию в продакшене. Не будем углубляться в синтаксис gulp-задач, мы рассмотрим это как-нибудь в другой раз.

node_modules и bower_components

В node_modules/ npm скачивает все зависимости из package.json. В bower_components/ скачиваются все зависимости из bower.json.

karma.conf.js

Здесь хранится конфигурация karma – тестового фреймворка Angular.js. Его мы тоже рассмотрим в другой раз. Так же к тестовому окружения относятся папка e2e/ (end-to-end) и protractor.conf.js.


Во всех остальных папках, которые мы будем рассматривать в следующих статьях, содержится само приложение и тесты к нему.

А теперь давайте запустим наше приложение и посмотрим как оно выглядит в браузере. Для этого нам необходимо выполнить команду gulp serve (что именно делает эта команда можно посмотреть в файле gulp/server.js в районе 34-ой строки). После её выполнения приложение автоматически откроется в браузере. В режиме разработки оно будет крутиться по адресу localhost:3000.

Обратите внимание: это так же запустит live reload. Если добавить что-нибудь в index.html, то после сохранения файла Gulp перезагрузит страницу в браузере за нас.

Итак, мы сгенерировали каркас для нашего проекта, рассмотрели основные файлы и папки приложения и запустили его. В следующей статье мы начнём писать само приложение. Полный код приложения, разрабатываемого в пределах этой серии, доступен на GitHub: https://github.com/mkdev-me/ng.mkdev. Каждой статье посвящён отдельный коммит в репозитории.

Дополнительное чтение