Меню

Краткий экскурс в node package manager

01.07.2018 - Back-end, NodeJS

NPM (Node Package Manager)

По простому это тулза командной строки которая позволяет нам регистрировать сторонние библиотеки, которые мы можем добавить в наши приложения. В регистре npm очень много разнообразных библиотек, модулей. Если Вы зайдете на npmjs.com, то увидите, что уже около 700 000 строительных блоков. И все они бесплатные и переиспользуемые. Еще, если у Вас есть идея для нового функционала, то вы можете спокойно добавить свой модуль и поделиться им со всем миром через npm. Способ добавить новый модуль в приложение — через инструмент командной строки, который также называется npm.

Первое, что нужно сделать, это открыть командную строку и ввести npm -v. npm устанавливается вместе с node. Интересно, что если вы введете node -v, то увидите что у ноды и npm разные версии. Потому как эти две программы разрабатываются независимо. Давайте посмотрим как установить конкретную версию npm.

npm i -g npm@5.5.1

Package.json

Перед тем, как добавлять какие либо пакеты к нам в приложение — нужно создать файл package.json. Это json файл, в котором указан базовая информация о вашем приложении. Это метаданные вашего приложения. Все приложения ноды по стандарту имеют этот package.json файл.
Для создания этого файла воспользуемся командой npm init. Если не хотите сразу заполнять поля, то укажите флаг -y или --yesnpm init -y.

Установка npm package

Установим библиотеку underscore.
Зайдем на npmjs.com. Наберем в поиске underscore. Зайдем по нужной ссылке и увидим в правом блоке команду для установки нужного модуля. Там же увидим базовую инфу о библиотеке. Данные о публицистах, статистике и т.д.

Теперь наберем в терминале npm install underscore или npm i underscore — это одно и тоже.
Когда Вы запустите, произойдет две вещи. Первая, в файле package.json в свойстве dependencies добавится запись о только что установленной библиотеке. Т.е. в этом файле будут указана информация о всех пакетах и их версиях. Например в нашем случае мы видим : "underscore": "^1.9.1" версию 1.9.1 и знак caret означает, что и более поздние версии. Т.е. означает установить последнюю версию пакета, но не ранее меньше указанной версии. А вторая вещь которая произойдет — модуль будет установлен в папку node_modules. В ней вы увидите наш underscore, кстати у него вы тоже обнаружите файл package.json. Как мы говорили ранее, этот файл есть у всех модулей node.

Раньше, для того чтобы пакет прописался в package.json приходилось еще дописывать флаг --save.

Using a package (Использование пакета)

Мы установили стороннюю библиотеку, теперь давайте воспользуемся ей. Создадим новый файл, под название index.js. Здесь воспользуемся функцией require, для загрузки нашего модуля. Мы вводим название модуля без указания пути. По сути при импорте просматривается без пути — по умолчанию модули ядра. Затем с путем модули проект. И наконец без путей могут указываться модули, который находятся в папках node_modules.

В общем модуль мы загрузили, теперь давайте воспользуемся им.

const _ = require('underscore');

const result = _.contains([1,2,3], 2);
console.log(result);

Package dependencies (Зависимости пакетов)

Установим, например, mongoose, он успешно добавился к нам в файл package.json. Теперь заглянем в нашу папку node_modules. И вы обнаружите там дофига разных папок. Откуда они тут вообще взялись? Мы же установили только mongoose. Все эти папки, которые вы видите, это модули от которых зависит сам mongoose. Раньше в старых версиях npm все зависимости устанавливались внутрь папки модуля. Т.е. у каждого устанавливаемого модуля была папка node_modules и там были все зависимости. Это создавало беспорядок, так как один и тот же пакет устанавливался множество раз. И в некоторых случая мы получали оооочень вложенную структуру, и были проблемы в особенности в windows, где есть лимит на количество символов, которое может содержать путь. Теперь поведение изменилось, и все зависимости лежать в одной папке node_modules. Но есть исключения. Если какойто пакет использует другую версию одной из этих зависимостей, тогда эта зависимость будет установлено локально с этим пакетом.

NPM Package and source control (Пакеты и контроль версий)

Сейчас в нашем приложении немного пакетов в папке node_modules. В реальном проекте папок будет куда больше. И размер папки node_modules будет расти в геометрической прогрессии. Хорошая новость в том, что Вам не нужно везде таскать эту папку. Например, если вы передаете проект своему другу, то вам не нужно закидывать все эти модули. Все зависимости записаны в файле package.json. Мы можем легко восстановить все эти зависимости на любом компьютере. Мы можем удалить в нашем проекте сейчас папку node_modules, а затем просто напишем в терминале, в корневой папке проекта npm i. И всё. Все зависимости скачаются заново.

Поэтому всегда исключайте папку node_modules из программы контроля версий. Если у вас git, то всё что вам надо, в корне проекта создать файл .gitignore и добавить туда запись node_modules/.

Semantic versioning (Семантика версий)

Ранее в версии пакета мы видели знак caret^ («mongoose»: «^5.1.7»). Что это значит?
Чтобы это понять, для начала нам нужно понять семантику версионности (SemVer). В semantic versioning npm пакеты имеют 3 компонента — 3 номера.

Первый номер, это то что мы называем главная версия (Major version). Второй называется Minor version. Последняя цифра — Patch version? используется при исправлении багов. Давайте представим что завтра создатели монгуса выпустят исправление бага. Текущая версия — («mongoose»: «^5.1.7»). Они зарелизят фикс и выпустят версию 5.1.8. Когда исправляют баг, то увеличивают patch version.

Minor version использует при добавлении новых фич, которые не ломают существующий API. Т.е. если создатели монгуста выпустили свежую фичу, которая не ломает текущий API, то они увеличат minor version — тогда версия будет 5.2.0. Ноль, потому что в этой версии багов еще не найдено.

И наконец, если сделают версию, которая возможно может потенциально сломать приложения, которые были построены на прошлой версии, тогда увеличивается major version. Тогда следующая версия будет 6.0.0. Вот что значит SemVer.

Знак caret^, говорит npm, что мы заинтересованы в любой версии mongoose, которая равна major version. Т.е. если будут доступны свежи версии minor или patch, то мы заинтересованы в этих версиях. Второй способ описать данный функционал без caret использовать x5.x. Также иногда вместо знака ^ вы можете увидеть знак ~ (тильда)(~5.2.3). Это означает вы заинтересованы в любой версии, например, при указанном примере, где major version равно 5, а minor version равно 2. Другой способ указать данный вариант — 5.2.x.

Эти символы помогают нам держать наши приложения up-to-date. Однако в реальных примерах это приводит к проблемам. Например, давате представим underscore выпустила новую версию (была 1.8.3 стала 1.8.4). Они исправили какие то баги, которые были фичей в вашем приложении )). Вы можете просто убрать все эти caret. И у вас всегда будет одна и так же версия зависимостей.

Listing the installed packages (листинг зависимостей)

Когда у нас стоит ^ или ~ в версии, то большая вероятность, что версия, которая на самом деле лежит в node_modules выше, чем указана в основном package.json. Есть два способа посмотреть нужную версию. Первый — залазить в каждую папку и смотреть package.json каждого файла. Для того чтобы не заниматься ерундой, придумали команду npm list, которая покажет структуру зависимостей и реальные версии пакетов. Но в таком виде указаны зависимости с их зависимостями. Если вы хотите узнать зависимости только своего проекта, то укажите флаг —depth.

npm list --depth=0

Viewing registry info for a package (Просмотр полезной инфы о пакетах)

Ранее мы обсуждали, что если вы хотите узнать побольше о пакете, то вам прямая дорога на npmjs.com. Где в поиске вы можете набрать название вашего пакета.

На странице пакета Вы можете увидеть всю метаинформацию о нём. Одно из свойств, которое может вас заинтересовать — это зависимости. Для этого на странице с зависимостью, нужно проскролить немного вниз и справа будет блок с зависимостью модуля. Также мы можем посмотреть информацию о пакете из терминала, набрав команду npm view.

npm view mongoose

Если же Вас интересуют только зависимости, то вы можете набрать команду npm view package dependencies, где package это интересующий вас пакет. Также вы можете посмотреть все версии интересующего вас пакета через команду npm view package versions.

Installing a specific version of package (Установка конкретной версии пакета)

Иногда нам нужно установить определенную версию пакета. Итак, для этого нам нужно указать название пакета, и указать знак собаки и версию.

npm i mongoose@2.4.2

Updating local packages (Обновление пакетов проекта)

Иногда нам могут понадобиться более свежие версии зависимостей которые у нас установлены. И так… вы хотите быстро найти какие пакеты нужно обновить и какие новые версии. Чтобы получить эту инфу, нужно воспользоваться командой.

npm outdated

#Package     Current  Wanted  Latest  Location
#mongoose      2.4.2  2.9.10   5.1.7  npm-demo
#underscore    1.4.0   1.9.1   1.9.1  npm-demo

Мы увидим пакеты, которые можно обновить, увидем текущую их версию. Но также мы увидим версию которую мы «хотим», точнее максимальную версию с такой же мажоритарной версией (в том случае, если у нас стоит ^ в package.json в версии пакета. Также нам отображается самая последняя версия доступного пакета.

Итак, для того чтобы обновить эти пакеты, на нужно ввести команду

npm update

Но это сработает для обновления minor и patch выпуски пакетов.

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

npm i -g npm-check-updates

Введем команду npm-check-updates или alias в виде ncu.
Увидем что мы можем обновить и как. Будет сказано, что если мы захотим обновить инфу в package.json для обновления нужных нам пакетов до последних версий, то нужно ввести команду ncu с флагом -u.

ncu -u

Теперь осталось просто ввести команду npm i.

DevDependencies (Зависимости разработки)

Все зависимости, которые мы пока устанавливали, это зависимости приложения. Т.е. наше приложение нуждается в этих зависимостях для корректной работы. Но иногда нам нужны зависимости, которые мы используем только во время разработки. Есть тулы для пакетирования, для юнит тестирования и т.д. и т.п. Эти зависимости — это зависимости разработки (development dependencies). Они не должны попадать в среду продакшн, где размещено наше приложение. Посмотрим как установить одну из таких дев зависимостей jshint. Для того, чтобы указать, что это дев зависимость, то при установке укажем флаг --save-dev или -D

npm i jshint -D

Мы увидим, что в package.json попал в раздел для дев зависимостей.

"dependencies": {
    "mongoose": "^5.1.7",
    "underscore": "^1.9.1"
  },
  "devDependencies": {
    "jshint": "^2.9.5"
  }

Это скажет ноде, что это дев зависимость и она не должна идти в продакшн. Обратите внимание, что и обычные зависимости и дэв зависимости хранятся в одной node_modules директории. А разделены только в файле package.json.

Uninstalling a package (Удаление пакета)

Мы уже узнали как устанавливать пакеты и как их обновлять. Но также иногда приходится и удалять пакеты, которые становятся не нужны. Для этих целей воспользуемся командой uninstall или её короткой версией un после которой укажем имя пакета.

npm un mongoose

Теперь package.json больше не содержит записей о mongoose. Он также удален из директории node_modules вместе со своими зависимостями.

Работа с глобальными пакетами

Все пакеты, которые мы не так давно устанавливали относятся к конкретном у проекту, как правило. Но есть тулзы, которые мы хотим использовать везде, вне зависимости от проекта. NPM например, является одной из таких тулзов. Это приложение командной строки, которая работает в любом месте. Другая популяная глобальная тулза это ng cli. Для создание angular проекта. Если вы хотите установить пакет глобально, то при установке используется флаг -g. Все команды, которые мы изучили ранее, для работы с пакетами, также работают и с глобальными пакетами.

Мы просто добавляем флаг -g

npm -g outdated

Publishing a package (Публикация пакета)

Создадим библиотеку shitpack-lib. Создадим папку с одноименным названием. Теперь создадим package.json с помощью npm init -y. Теперь откроем эту директорию с помощью code .. Теперь создадим файл index.js, так как это отправная точка нашего пакета. Здесь мы можем экспортировать одну или более функций. Для примера экспортируем очень простую функцию.

module.exports.add = (a, b) => a + b;

Теперь возвращаемся к терминалу. Если у вас нет пользователя в npm, то воспользуйтесь командой npm adduser, если у вас есть аккаунт, то воспользуйтесь командой npm login. Теперь чтобы опубликовать, нужно всего лишь ввести команду npm publish. Теперь мы можем использовать его в другом nodejs приложении.

Update a published package

Давайте добавим еще одну функцию в наш пакет.

module.exports.mult = (a, b) => a * b;

Теперь мы опубликуем новую версию. Теперь если мы из нашей папки с проектом, наберем команду npm publish, то получим ошибку. Мы не можем опубликовать ту же версию. В зависимости от того, какие изменения мы сделали, на нужно обновить версию. В нашем случае это был не багфикс, а новая фича, поэтому обновим минорную версию. Мы можем обновить версию вручную в package.json или через терминал с помощью команды npm version major|minor|patch

npm version minor

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *