📦 Что такое npm? Гайд по Node Package Manager для начинающих

Как установить, опубликовать и проверить JavaScript-пакеты на уязвимость с помощью npm – менеджера пакетов Node.js.

Программная платформа Node.js появилась в 2009 г., и с тех пор на ней были построены сотни тысяч приложений. Одной из причин успеха стал npm – популярный пакетный менеджер, позволяющий JS-разработчикам быстро делиться пакетами.

На момент написания статьи в npm содержится 1.3 млн пакетов с общим количеством скачиваний 16 млрд.

1. Что такое npm?

npm (Node Package Manager) – дефолтный пакетный менеджер для JavaScript, работающий на Node.js. Менеджер npm состоит из двух частей:

  • CLI (интерфейс командной строки) – средство для размещения и скачивания пакетов,
  • онлайн-репозитории, содержащие JS пакеты.

Структуру репозитория npmjs.com можно представить, как центр исполнения заказов, который получает товары (npm-пакеты) от продавцов (авторы пакетов) и распространяет эти товары среди покупателей (пользователи пакетов).

В центре исполнения заказов (npmjs.com) в качестве персональных менеджеров для каждого покупателя работает армия вомбатов (npm CLI).

Зависимости поставляются следующим образом (Рис. 1).

Рис. 1. Процесс установки пакета через npm install

Процесс размещения пакета выглядит, как показано на Рис. 2.

Рис. 2. Процесс размещения пакета через npm publish

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

1.1. Файл package.json

Каждый проект в JavaScript – будь то Node.js или веб-приложение – может быть скопирован как npm-пакет с собственным описанием и файлом package.json.

package.json можно представить, как стикеры (список пакетов нужных версий) на npm-коробке (проект). Файл генерируется командой npm init при создании JavaScript/Node.js проекта со следующими метаданными:

  • name: название JS библиотеки/проекта.
  • version: версия проекта.
  • description: описание проекта.
  • license: лицензия проекта.

1.2. Скрипты npm

В package.json включено поле scripts для автоматизации сборки, например:

{
  "scripts": {
    "build": "tsc",
    "format": "prettier --write **/*.ts",
    "format-check": "prettier --check **/*.ts",
    "lint": "eslint src/**/*.ts",
    "pack": "ncc build",
    "test": "jest",
    "all": "npm run build && npm run format && npm run lint && npm run pack && npm test"
  }
}

eslint, prettier, ncc, jest могут быть установлены глобально или локально для проекта внутри node_modules/.bin/.

1.3. dependencies и devDependencies

dependencies и devdependencies представляют собой словари с именами npm-библиотек (ключ) и их семантические версии (значение). Пример из шаблона TypeScript Action:

{
  "dependencies": {
    "@actions/core": "^1.2.3",
    "@actions/github": "^2.1.1"
  },
  "devDependencies": {
    "@types/jest": "^25.1.4",
    "@types/node": "^13.9.0",
    "@typescript-eslint/parser": "^2.22.0",
    "@zeit/ncc": "^0.21.1",
    "eslint": "^6.8.0",
    "eslint-plugin-github": "^3.4.1",
    "eslint-plugin-jest": "^23.8.2",
    "jest": "^25.1.0",
    "jest-circus": "^25.1.0",
    "js-yaml": "^3.13.1",
    "prettier": "^1.19.1",
    "ts-jest": "^25.2.1",
    "typescript": "^3.8.3"
  }
}

Эти зависимости устанавливаются командной npm install с флагами --save и --save-dev. Они предназначены соответственно для использования в продакшене и разработке.

О версионировании:

  • ^: последний минорный релиз. Например, ^1.0.4 установит версию 1.3.0, если это последний минорный релиз в серии 1 мажорного релиза.
  • ~: последний патч-релиз. ~1.0.4 установит 1.0.7, если эта последняя минорная версия в серии минорных релизов 1.0.

Все версии пакетов будут отображены в сгенерированном файле package-lock.json.

1.4. Файл package-lock.json

Файл package-lock.json описывает версии пакетов, используемые в JavaScript-проекте. Если package.json включает общее описание зависимостей (название товара), то package-lock.json более детальный – всё дерево зависимостей.

package-lock.json генерируется командой npm install и читается npm CLI, чтобы обеспечить воспроизведение окружения для проекта через npm ci.

2. Установка пакетов

Так как пользователи чаще скачивают пакеты (16 млрд скачиваний против 13 млн публикаций), хорошо бы разобраться, как их устанавливать.

2.1. npm install

npm install команда, устанавливающая пакеты.

По умолчанию npm install <package-name> со знаком ^ установит последнюю версию пакета. npm install скачает пакет в папку проекта node_modules в соответствии с конфигурацией в файле package.json, обновив версию пакета везде, где это возможно (и, в свою очередь, обновив package-lock.json). При необходимости установки пакета глобально можно указать флаг -g .

npm сделал установку пакетов JavaScript настолько простой, что команда часто используется некорректно и в сообществе разрабов появились мемы на эту тему:

Рис. 3. Мем про node_modules

При добавлении флага --production установятся только нужные для работы приложения зависимости из dependencies, не раздувая node_modules.

2.2. npm ci

Если npm install --production оптимален для продакшена, существует ли аналогичная команда для локальной разработки? Да, она называется npm ci.

Как и раньше, если package-lock.json еще не существует в проекте, он будет сгенерирован при вызове npm install. npm ci обращается к Lock-файлу для загрузки точной версии пакетов. Таким образом, на разных машинах набор пакетов останется неизменным.

2.3. npm audit

Чтобы избежать добавления в репозитории вредоносных пакетов, организация npm.js пришла к идее аудита экосистемы, создав модуль npm audit. Он предоставляет информацию об уязвимостях в пакетах и о существовании версий с исправлениями.

Пример аудита для пакета static-eval

Если исправления доступны в следующих версиях пакета, npm audit fix автоматически обновит версии затронутых зависимостей.

3. Размещение пакетов

Перейдем от потребления пакетов к их размещению.

3.1. npm publish

Отправить пакет в npmjs.com очень просто – нужно набрать в консоли npm publish. Важная часть, которой пренебрегают авторы – версионирование. Вот набор эмпирические правил semver.org, указывающих, когда следует увеличить номер версии:

  • Мажорная версия: когда сделаны обратно несовместимые изменения API.
  • Минорная версия: когда вы добавляете новую функциональность, не нарушая обратной совместимости.
  • Патч-версия: когда вы делаете обратно совместимые исправления.

Еще более важно следовать вышеуказанным правилам при публикации собственных пакетов, чтобы гарантировать, что вы не нарушаете чью-либо совместимость, так как по умолчанию в npm берется версия ^ (следующая младшая версия).

Заключение

В этой публикации мы познакомились со структурой npm и узнали:

  • в каких файлах хранятся данные о зависимостях (package.json, package-lock.json).
  • как установить пакеты в продакшен (npm install), на локальной машине (npm ci) и провести аудит пакетов (npm audit).
  • как добавить пакет в репозиторий (npm publish).
***

Мне нужно оперативно погрузиться во фронтенд. Какой вариант самый быстрый и качественный?

Если 15 лет назад для того, чтобы называть себя фронтенд-разработчиком достаточно было знать HTML, CSS и JavaScript, то сейчас фронтенд-разработка почти не отстает от бэкенд-разработки по количеству фреймворков и сложности стеков. Самый быстрый и качественный вариант — получить знания из первых рук от преподавателей со стажем. Поэтому мы запустили курс «Frontend Basic: принцип работы современного веба», на котором вы:

  • освоите стек технологий, который позволит начать работать в любой компании на любом проекте;
  • сверстаете свой первый адаптивный макет с учетом семантики и множества декоративных элементов на HTML и CSS;
  • поймете, как с помощью JavaScript разрабатывать пользовательские интерфейсы;
  • разберетесь, как JavaScript используется в работе с backend и создадите свой первый обмен данными сервером;
  • углубитесь в более сложную разработку на React.js и напишете свой интернет-магазин;
  • изучите основные команды для работы с GIT, важнейшего инструмента для работы в любой команде.

Источники

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

admin
10 июня 2018

Лайфхак: в какой последовательности изучать JavaScript

Огромный инструментарий JS и тонны материалов по нему. С чего начать? Расск...