Bower: зачем фронтенду нужен менеджер пакетов
Статья написана в 2014-м году, во времена npm 2, который был не очень популярен среди фронтендеров из-за описанных в статье недостатков. Сейчас пользуйтесь Ярном или npm, а статью считайте исторической.
Статья впервые была опубликована в майском номере журнала Хакер. В журнал вошла сильно сокращённая версия; ниже — полная.
Менеджеры пакетов упрощают установку и обновление зависимостей проекта, то есть сторонних библиотек, которые он использует: jQuery, Fotorama, всё, что используется на вашем сайте и написано не вами.
Хождение по сайтам библиотек, скачивание и распаковка архивов, копирование файлов в проект — всё это заменяется парой команд в терминале.
У многих языков программирования есть стандартные менеджеры пакетов, которыми разработчики пользуются для установки всех библиотек: gem у Руби, pip у Питона и другие. У серверного Яваскрипта есть npm (почему он не подходит для клиентского — ниже), а у клиентского яваскрипта до недавнего времени ничего не было. Было множество разных пакетных менеджеров (Jam, Component, Volo, Ender), но большинство из них так и не стали популярными, а от менеджера пакетов, которым не поставишь нужных библиотек, толку мало.
Бовер — не стандартный менеджер пакетов для клиентского Яваскрипта, но самый популярный: сейчас там больше 11 тысяч пакетов.
Бовер не навязывает пользователю свою систему сборки, а разработчику пакетов — метод подключения библиотеки (AMD, CommonJS и другие). Всё, что делает Бовер — устанавливает нужные проекту пакеты подходящих версий вместе с их зависимостями. Другими словами: просто загружает файлы нужных библиотек и всё, что нужно для их работы в специальную папку. Остальное остаётся на усмотрение разработчика.
Почему не npm
Главное отличие npm и Бовера — подход к установке зависимостей пакетов. npm устанавливает зависимости для каждого пакета отдельно, в итоге получается большое дерево пакетов (node_modules/grunt/node_modules/glob/node_modules/…), где может быть несколько версий одного и того же пакета. В клиентском Яваскрипте это недопустимо: нельзя подключить на страницу две версии jQuery или любой другой библиотеки. В Бовере каждый пакет устанавливается один раз (jQuery всегда будет в папке bower_components/jquery, сколько бы пакетов от него не зависело) и в случае конфликта зависимостей, Бовер просто не станет устанавливать пакет, не совместимый с уже установленными.
Установка Бовера
Для работы с Бовером вам потребуются Node и Git. Установка:
Работа с пакетами
Попробуем что-нибудь установить, например, jQuery:
Эта команда скачает jQuery последней версии в папку bower_components/jquery
.
Флаг --save
говорит Боверу, что он должен сохранить имя пакета и его версию в файл-манифест — bower.json
. В этом файле хранится список всех зависимостей проекта (пакетов, установленных через Бовер) и другие метаданные, нужные для создания своих пакетов (об этом в конце статьи). Вместе с именами пакетов можно указать версии, с которыми ваш проект гарантированно будет работать.
У нас такого файла ещё нет, о чём и говорит строчка «No bower.json file to save to, use bower init to create one» в логе. Создадим его:
Бовер будет задавать много вопросов, но до тех пор пока мы не захотим зарегистрировать свой пакет, ответы на большинство из них не имеют значения, можно просто нажимать Enter.
На вопрос «set currently installed components as dependencies?» нужно ответить «Yes» — все ранее установленные компоненты (в нашем случае это jQuery) автоматически попадут в созданный JSON-файл. А на вопрос «would you like to mark this package as private which prevents it from being accidentally published to the registry?» — тоже «Yes» — это предотвратит случайную регистрацию пакета в реестре Бовере.
Поставим ещё несколько пакетов:
И посмотрим, что у нас получилось:
Команда bower list
показывает список всех установленных пакетов. Тут мы видим, что все пакеты зависят от jQuery, и что Бовер смог найти подходящую всем версию — jQuery 2.1.0.
На файловой системе это выглядит вот так:
Каждый пакет устанавливается в свою папку, вложенных пакетов нет, jQuery встречается только один раз. В корне проекта лежит созданный командой bower init
файл bower.json
, но теперь там перечисленны уже все пакеты, которые показывает bower list
, а не только jQuery.
Для удаления пакетов используется команда bower uninstall
:
Вы можете спокойно удалять папку bower_components
или добавить её в ваш .gitignore
. Команда bower install
(без дополнительных параметров) вернёт всё как было:
Развёртывание проекта
Есть два подхода к развёртыванию проектов:
- В репозиторий добавляется только файл-манифест и все пакеты устанавливаются во время развёртывания проекта. Так в репозитории не хранится ничего лишнего, но если во время развёртывания упадёт Гитхаб или другой сервер, с которого устанавливаются пакеты, будут проблемы;
- В репозиторий добавляется не только
bower.json
, но папкаbower_components
. Так развёртывание не зависит от внешних серверов, но репозиторий раздувается десятками (а то и сотнями) лишних файлов.
Семантические версии (semver)
Semver — это, во-первых, подход к версионированию библиотек: формат номера версии МАЖОРНАЯ.МИНОРНАЯ.ПАТЧ и правила, по которым следует увеличивать то или иное число.
А во-вторых — это способ описания требуемых версий зависимостей, который используют Бовер и npm.
При установке с флагом --save
версии пакетов добавляются в bower.json
в виде ~1.0.1
. Тильда в начале говорит о том, что при установке будет выбрана версия 1.0.1 или с большим последним числом (ПАТЧ), если она есть. Таким образом будет установлена версия с последними исправлениями ошибок, но полностью совместимая с той, что указана в файле-манифесте.
Обновление зависимостей
В Бовере есть команда bower update
, но она обновляет пакеты с учётом требований файла-манифеста. Например, если там указан jQuery ~2.0.0
, то Бовер сможет обновить jQuery до версии, скажем, 2.0.9, но 2.1.0 уже не поставит, потому что эта версия не соответствует формуле ~2.0.0
.
Для обновления пакетов (и bower.json
) до действительно последних версий можно воспользоваться утилитой bower-update. Устанавливаем:
Запускаем:
Поиск пакетов
Есть два способа найти пакет в Бовере: гиковский и обычный.
Гиковский:
Обычный: открыть в браузере bower.io/search.
Автоматическая сборка
Бовер перекладывает проблемы сборки установленных пакетов на плечи разработчика. Самый простой способ — просто склеить JS-файлы Грантом, Галпом или любой другой системой сборки, которой вы пользуетесь.
Я пользуюсь Грантом, поэтому расскажу, как склеивать пакеты Грантом. О том как пользоваться Грантом была большая статья в июльском номере прошлого года, поэтому покажу сразу конфиг плагина grunt-contrib-concat
:
У этого способа есть много недостатков: вам нужно смотреть имена файлов для каждого пакета; следить, чтобы файлы собирались в правильном порядке (например, jQuery должен быть выше, чем скрипты, зависящие от него). Плагин grunt-bower-concat может делать это сам: он автоматически склеивает все установленные зависимости в правильном порядке в один файл:
Регистрация своих пакетов
Чтобы ваша библиотека стала доступна для установки через Бовер, её нужно зарегистрировать. Для этого:
- В корне проекта должен лежать файл-манифест
bower.json
; - У проекта должен быть гит-репозиторий (например, на Гитхабе);
- Проект должен использовать семантические версии и в репозитории должен быть гит-тег для последней версии.
Для создания файла файла-манифеста снова воспользуемся командой bower init
:
И хотя обязательно нужно заполнить только имя пакета (поле name
), остальные поля тоже очень полезны:
description
иkeywords
помогут пользователям найти вашу библиотеку через интерфейс поиска пакетов;main
определяет главный файл пакета. Это поле может быть использовано автоматическими сборщиками, такими как grunt-bower-concat;license
— всегда указывайте лицензию: она говорит потенциальному пользователю вашего пакета, сможет ли он использовать его в своём проекте. Например, лицензия GPL требует, чтобы любой использующий её проект тоже распространялся по этой лицензии, что не всегда возможно;ignore
— по умолчанию Бовер скачивает весь репозиторий, что, во-первых, увеличивает время установки, а, во-вторых, добавляет в проект лишние файлы. Лучше всего исключить всё, кроме необходимых для работы пакета файлов (главный JS-файл, CSS и так далее), лицензии и ридми;dependencies
— все пакеты, от которых зависит ваш пакет.
Теперь нужно закоммитить bower.json
, создать гит-тег с последней версией и запушить всё в удалённый репозиторий:
Вот теперь можно регистрировать пакет:
Дальше Бовер сам будет проверять обновления пакета, главное не забывать создавать гит-тег для каждой новой версии.
Для облегчения обновления своих пакетов можно воспользоваться такими инструментами, как grunt-bump или mversion.
Источник: http://nano.sapegin.ru/all/bower