logo
Разработка Web-приложения с использованием JavaScript каркаса Node.js

Менеджер пакетов для Node (npm)

npm - это система управления и распространения пакетов для Node, ставшая стандартом де-факто. Концептуально она похожа на такие инструменты, как apt-get (Debian), rpm/yum (Redhat/Fedora), MacPorts (Mac OS X), CPAN (Perl) и PEAR (PHP). Ее задача - обеспечить публикацию и распространение пакетов Node через Интернет с помощью простого интерфейса командной строки. Npm позволяет быстро находить пакеты для решения конкретной задачи, загружать и устанавливать их, а также управлять уже установленными пакетами.

В npm определен формат пакета для Node, основанный на спецификации CommonJS.

Формат npm-пакета

Npm-пакет представляет собой структуру каталогов, описанную в файле package.json. Именно так мы выше определили составной модуль, отличие только в том, что npm распознает значительно больше полей, чем Node. Исходной точкой для определения формата package,json для npm послужила спецификация CommonJS Packages/1.0. Получить документацию по структуре файла package,json позволяет следующая команда:

$ npm help json

Простейший файл package,json выглядит следующим образом:

{ name: "packageName",

version: "1.0",

main: "mainModuleName",

modules: {

"mod1”: "lib/mod1",

"mod2": "lib/mod2"

}

}

Файл представлен в формате JSON, c. которым вы как программист на JavaScript, должно быть, встречались уже сотни раз.

Наиболее важны поля name и version. Значение name подставляется в URL-адреса и названия команд, поэтому выбирать его следует с учетом безопасности в этих контекстах. Если мы соберемся опубликовать пакет в общедоступном репозитории npm-пакетов, то должны проверить, не занято ли выбранное имя. Для этого можно обратиться к сайту http://search.npmjs.org с помощью следующей команды:

$ npm search packageName

Поле main служит той же цели, что и в составных модулях (см. предыдущий раздел). Оно ссылается на модуль, который следует загружать при вызове функции require(packageName). Пакеты могут содержать много модулей, и все их можно перечислить в списке модулей.

Пакеты можно упаковывать в tgz-архивы, что особенно удобно для распространения через Интернет.

Пакет может объявлять зависимости от других пакетов. Именно благодаря этой возможности npm способен автоматически устанавливать модули, необходимые тому, который устанавливается явно. Зависимости объявляются следующим образом:

"dependencies":

{ "foo" : "1.0.0 - 2.9999.9999"

, "bar" : ">=1.0.2 <2.1.2"

}

Людям будет проще найти пакет в npm-репозитории (http://search.npmjs.org), если пакет снабжен описанием (поле description) и ключевыми словами (поле keywords). Для сведений о владельце предназначены поля homepage, author и contributors:

"description”: "My wonderful packages walks dogs",

"homepage": "http://npm.dogs.org/dogwalker/",

"author": dogwhisperer@dogs.org

В состав некоторых npm-пакетов входят исполняемые программы, которые должны быть установлены в каталог, упомянутый в переменной PATH для данного пользователя. Они объявляются с помощью поля bin. Это словарь, отображающий имена команд на имена реализующих их скриптов. Командные скрипты устанавливаются в каталог, содержащий исполняемый файл node, под указанным именем.

bin: {

nodeload.js: ./nodeload.js , nl.js: ./nl.js

}

В поле directories документируется структура каталогов пакета. Каталог lib автоматически просматривается при поиске загружаемых модулей. Существуют также поля для двоичных файлов, страниц руководства и документации.

directories: { lib: ./lib, bin: ./bin },

В поле scripts перечисляются скриптовые команды, запускаемые на различных этапах жизненного цикла пакета, а именно: установка, активация, удаление, обновление и др. Для получения дополнительных сведений о скриптовых командах нужно ввести следующую команду:

$ npm help scripts

Это лишь краткое введение в формат npm-пакетов, для получения полной документации необходимо набрать npm help json.

Версии и диапазоны версий пакета

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

Ранее мы использовали команду npm list для вывода списка установленных пакетов, и в этом списке отображались также номера версий. Если же требуется узнать только номер версии конкретного модуля, то подойдет следующая команда:

$ npm view express version

2.4.0

Во всех случаях, когда команда npm принимает имя пакета, вы можете дописать в конец имени номер или метку версии. Это позволяет работать с конкретной версией пакета. Например, если вы протестировали приложение с определенной версией пакета в тестовой среде, то можете установить ту же версию и в производственной:

$ npm install express@2.3.1

mime@1.2.2 ./node_modules/express/node_modules/mime

connect@1.5.1 ./node_modules/express/node_modules/connect

qs@0.2.0 ./node_modules/express/node_modules/qs

express@2.3.1 ./node_modules/express

В npm есть концепция метки (tag), которой можно воспользоваться, чтобы установить самую свежую стабильную версию пакета:

$ npm install sax@stable

Имена меток произвольны и необязательны. Их выбирает автор пакета, и не во всех пакетах они применяются.

Npm позволяет просмотреть зависимости от других пакетов, хранящиеся в файле package:

$ npm view mongoose dependencies

{ hooks: 0.1.9 }

$ npm view express dependencies

{ connect: >= 1.5.1 < 2.0.0,

mime: >= 0.0.1,

qs: >= 0.0.6 }

Зависимости - это механизм, с помощью которого npm узнает, какие еще модули необходимо установить. Во время установки модуля npm смотрит, от чего он зависит, и устанавливает те модули, которые не были установлены ранее.

Хотя эта система проста и понятна всякому, кто хоть раз имел дело с программным обеспечением, за ней стоит строгая модель. Реализуя систему нумерации версий, автор npm пользовался спецификацией семантической версионности, опубликованной на сайте http://semver.org. Формулируется она следующим образом:

Версии представляются строками вида X.Y.Z, где X, Y и Z обычно являются целыми числами; X - основной номер, Y - дополнительный номер, Z - номер исправления (например, 1.2.3).

После номера исправления в строке может указываться произвольный текст, описывающий так называемые «специальные версии» (например, 1.2.3betal).

При сравнении номеров версий сравниваются не строки, а числа X, Y и Z. Например, 1.9.0 < 1.10.0 < 1.11.3. и 1.0.0betal < 1.0.0beta2 < 1.0.0.

Совместимость документируется с помощью следующих соглашений о нумерации версий:

пакеты с основным номером версии 0 (X = 0) совершенно нестабильны, их API может измениться в любое время;

если изменение исправляет только ошибки и гарантирует обратную совместимость, то следует увеличивать номер исправления (Z);

дополнительный номер версии (Y) нужно увеличивать при добавлении функциональности, сохраняющей обратную совместимость (например, добавлена новая функция, а все прочие обратно совместимы);

основной номер версии (X) следует увеличивать при внесении несовместимых изменений.