Гайд по NPM

NPM (Node Package Manager) — это инструмент для управления пакетами в среде Node.js. Он позволяет устанавливать необходимые библиотеки, контролировать зависимости проекта, а также настраивать и редактировать его метаданные.

Загрузка пакетов

Пакеты в NPM — это упакованный программный код, который может представлять собой библиотеку, утилиту или полноценное приложение.

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

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

Для установки NPM воспользуемся командой install либо i

npm install create-react-app 
// скачает React JS

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

npm install react react-dom 
// скачает сразу 2 пакета 

Ставим зависимости

Зависимости в проекте - это набор пакетов, которые необходимы для запуска и работы приложения. Их список указывается в файле packade.json в разделе dependencies а конфиг запускается командой npm init

npm init

После запуска команды, в консольке появятся несколько вопросов об авторе, названии проекта, версии и т.д.

Можно пропустить и не отечать на эти вопросы, ничего страшного не произойдет.

У init есть флаг, прописав который вопросы будут автоматически скипнуты.

В любом случае получаем готовый файлик package.json

{
    "name": "test",
    "version": "1.0.0",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "El'ham",
    "License": "MIT",
    "description": ""
}

А теперь добавим список зависимостей в разделе dependencies в формате "название_пакета":"версия"

{
    "name": "test",
    "version": "1.0.0",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "El'ham",
    "License": "MIT",
    "description": "",
    "dependencies": {
        "express": "4.17.1",
        "lodash": "4.17.21",
    }
}

А теперь сохранимся и запустим команду npm install

NPM чекнет список зависимостей, создаст файлик package_lock.json а все скачанные модули теперь будут лежать в папке проекта node_modules

Автоматически добавим зависимости

В NPM есть функция автоматического добавления зависимостей в файл package.json, что избавляет от необходимости вручную редактировать раздел dependencies. Для этого воспользуемся флагами команд:

Флаг --save или -S позволяет добавить название пакета и его версию в раздел dependencies во время установки. Однако стоит отметить, что этот флаг актуален только для старых версий NPM. Начиная с версии NPM 5, все устанавливаемые пакеты по умолчанию автоматически добавляются в раздел dependencies, что упрощает процесс управления зависимостями.

Флаг --save-dev или -D используется для добавления зависимостей в раздел devDependencies при установке пакетов. Он предназначен для пакетов, которые необходимы только в процессе разработки и не используются в финальной версии проекта. Например, сюда могут входить инструменты для тестирования, линтеры, сборщики и другие вспомогательные библиотеки, которые помогают в разработке, но не требуются для работы готового приложения.

Обновим пакеты

Для обновления модулей в проекте используем команду npm update. Она позволяет NPM проверить список зависимостей в файле package.json и установить все доступные обновления, если они не ограничены специальными правилами.

Ограничения на обновления задаются в разделе dependencies с помощью символа каретки (^). Например, список зависимостей с указанными ограничениями может выглядеть следующим образом:

{
    "name": "test",
    "version": "1.0.0",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "El'ham",
    "License": "MIT",
    "description": "",
    "dependencies": {
        "express": "^4.17.1",
        "lodash": "^4.17.21",
    }
}

Теперь NPM обновит все модули до минорных версий и патчей, игнорирую мажорные версии.

Пакеты в NPM следуют принципу семантического версионирования, где версии указываются в формате MAJOR.MINOR.PATCH. Каждая часть версии имеет своё значение:

- MAJOR (мажорная версия) — указывает на крупные изменения, которые могут повлиять на совместимость пакета с другими модулями или инструментами.

- MINOR (минорная версия) — добавляет новые функции, которые не нарушают обратную совместимость и не мешают использованию пакета.

- PATCH (патч) — включает исправления ошибок, не затрагивающие функциональность пакета.

Такой подход помогает разработчикам понимать, какие изменения влечёт за собой обновление пакета.

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

npm update react

Загрузим пакеты определенных версий

Если после автоматического обновления всех пакетов в проекте, становится понятно что в одном из них появились ошибки или исчезли необходимые функции, в NPM есть возможность откатиться к предыдущей версии и заблокировать дальнейшие обновления.

Для начала определим, какая версия пакета использовалась до проблемного обновления. Например, предположим, что сейчас установлен пакет react версии 10.2.0. Чтобы найти предыдущие версии, воспользуемся калькулятором NPM SemVer: набираем название модуля и диапазон версий. В данном случае это 10.x.x — все релизы мажорной версии 10. Также список всех доступных версий можно посмотреть на странице пакета в NPM.

После того выяснили что с версией 10.1.0 не было проблем, пропишем его в package.json

{
    "name": "test",
    "version": "1.0.0",
    "main": "index.js",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "El'ham",
    "License": "MIT",
    "description": "",
    "dependencies": {
        "express": "^4.17.1",
        "lodash": "^4.17.21",
        "react": "10.1.0",
    }
}

И ставим с помощью команды npm install

Запуск скриптов в NPM

В файле package.json можно прописать скрипты и сложные команды, которые будут выполняться для сборки проекта, тестирования или обработки ошибок. Например, многие разработчики используют Webpack для объединения нескольких файлов с JavaScript-кодом в одно приложение. Чтобы запустить процесс сборки, достаточно выполнить соответствующую команду, указанную в package.json.

NODE_ENV=production webpack -p --config webpack.conf.js

Упростим задачу, добавив команду в раздел scripts файла package.json. Перед командой укажем название скрипта, которое будет использоваться для его запуска. Например, в нашем случае это будет prod:

{
    "name": "test",
    "version": "1.0.0",
    "main": "index.js",
    "scripts": {
        "prod": "NODE_ENV=production webpack -p --config webpack.conf.js"
    },
    "author": "El'ham",
    "License": "MIT",
    "description": "",
    "dependencies": {
        "express": "^4.17.1",
        "lodash": "^4.17.21",
        "react": "10.1.0",
    }
}

Теперь этот скрипт запускается с помощью npm run prod

Разберем файл package.json

Файл package.json — это ключевой компонент проектов в экосистеме Node.js.

Рассмотрим всю его структуру и возможности.

Version - говорит о текучей версии проекта. Версия задается по правилам семантического версионирования.

"version": "1.0.0"

Desription - короткое описание проекта.

"description": "Это супер мощный скрипт"

Main - точка входа в приложение.

"main": "app/main.js"

Scripts - список скриптов которые мы собираемся запускать в дальнейшем.

"scripts": {
    "say-hi": "echo 'Hello Frends!'"
}

Dependencies - список зависимостей для запуска приложения или программы.

"depenencies": {
    "express": "^4.17.1",
    "lodash": "^4.17.21"
}

Engines - список версий Node.js на которых запустится приложение

"engines": {
  "node": ">= 5.0.0",
  "npm": ">= 2.5.0",
  "yarn": "^0.14.0"
}

Autor - инфа об авторе проекта.

{
  "author": {
    "name": "El'ham",
    "email": "hello@elham.ru",
    "url": "https://elham.ru"
  }
}

Bugs - адрес на баг-трекер проекта.

{
  "bugs": "https://github.com/e1hxm/package/issues"
}

Homepage - адрес официального сайта проекта

{
    "homepage": "https://elham.ru"
}

devDependencies - список зависимостей необходимых для ведения разработки.

"devDependencies": {
  "autoprefixer": "^7.1.2",
  "babel-core": "^6.22.1"
}

Правильное версионирование

В процессе разработки проекта чаще всего изменения происходят в разделах dependencies и devDependencies. Разработчики добавляют новые пакеты, обновляют версии существующих и удаляют ненужные зависимости. Для управления версиями пакетов используется принцип семантического версионирования, а NPM предоставляет удобные инструменты для работы с ними. Разберём специальные символы, которые помогают контролировать версии пакетов.

Символы для управления версиями пакетов в NPM:

СимволОписание
^Разрешает обновления до последней минорной версии (например, ^1.2.3 обновит до 1.x.x, но не до 2.0.0).
~Разрешает обновления только в пределах патчей (например, ~1.2.3 обновит до 1.2.x, но не до 1.3.0).
>Устанавливает версию выше указанной.
<Устанавливает версию ниже указанной.
>=Устанавливает версию не ниже указанной.
<=Устанавливает версию не выше указанной.
=Устанавливает точную версию (можно не указывать, это поведение по умолчанию).
-Задаёт диапазон версий (например, 1.2.3 - 2.0.0).
*Разрешает установку любой версии.
xОбозначает “любое значение” в версии (например, 1.x.x или 1.2.x).

Эти символы позволяют гибко управлять версиями пакетов, обеспечивая стабильность и совместимость проекта.

Рассмотрим файл package-lock.json

Файл package-lock.json автоматически создаётся при установке пакетов через NPM. Скорее всего, этот файл уже есть в папке вашего проекта. Его основная задача — зафиксировать все зависимости, необходимые для работы сторонних пакетов.

Рассмотрим пример. Предположим, я решил разработать библиотеку для обработки онлайн-платежей. Для этого я использовал несколько готовых модулей из NPM и на их основе создал собственное решение.

Спустя некоторое время вы нашли мою библиотеку и решили добавить её в свой проект. Информация о ней будет зафиксирована в файле package.json, а все зависимости, без которых моя библиотека не сможет работать, запишутся в package-lock.json. Если говорить проще, то package-lock.json содержит информацию о зависимостях зависимостей.

Если заглянуть в папку node_modules, то там можно найти не только пакеты, которые мы поставили сами, но и множество других модулей. Они появились там автоматически, потому что необходимы для работы библиотек, которые используются. Это стало возможным благодаря записям в package-lock.json.