[Перевод] Распространённые ошибки при использовании npm, которых лучше не совершать

Npm — это крупнейший менеджер пакетов. Его сравнительно просто и понятно использовать в практике веб-разработки. Но когда речь заходит о применении собственных конфигураций или об использовании продвинутых возможностей npm, многое может пойти не так.

ggncu-uurz6kutuztmws1e3cc3i.jpeg

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

1. Ручное добавление зависимостей в файл package.json


Не стоит самостоятельно редактировать файл package.json, так как это может нарушить синхронизацию между этим файлом и package-lock.json.

Вместо этого можно прибегнуть к командам, выполняемым в командной строке, вроде npm i --save и npm i --save-dev, что позволит автоматически обновлять и package.json, и package-lock.json. При таком подходе система ещё и уведомит разработчика о том, что в версиях зависимостей, упомянутых в этих двух файлах, имеются расхождения.

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

Например, если выполнить команду вида npm i --save package@~1.0.0, можно ожидать, что в package.json будет отражена версия пакета, соответствующая той, что указана в команде после @. Но в подобной команде можно использовать не спецификатор версии ~, а спецификатор версии ^, что позволит расширить возможности по автоматическому обновлению пакета.

Рекомендуется тщательно проверять package.json после обновления зависимостей.

2. Ограничение зависимостей типа peerDependencies конкретной версией патча


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

Рассмотрим простой пример для того чтобы разобраться с фундаментальной причиной этой проблемы.

{
  "name": "tea-latte",
  "peerDependencies": {
    "tea": "1.x"
  }
}


В соответствии с вышеприведённым кодом, модуль tea-latte нуждается в конкретной версии (1.x) пакета tea.

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

Обратите внимание на то, что npm версий 1, 2 и 7 автоматически установит зависимости peerDependencies, если явной зависимости от них нет, выше в дереве зависимостей. А npm версий 3, 4, 5 и 6 выдаст предупреждение.

3. Публикация нескольких модулей в виде единственного пакета


image-loader.svg


Независимый компонент и схема его зависимостей

Идёт ли речь об UI-библиотеке, о наборе полезных инструментов, или о любой другой группе модулей,   публикация нескольких таких сущностей в виде единого пакета — это, практически всегда, неудачная идея.

Нет причин, по которым разработчикам стоит принуждать потребителей их кода привязывать свои проекты к целому набору модулей и компонентов, в ситуациях, когда потребителям все эти модули или компоненты не нужны. У потребителей должна быть возможность выбора конкретного модуля и его версии, он не должен сталкиваться с бессмысленными обновлениями пакетов, происходящими из-за того, что ему не нужно.

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

JavaScript-экосистема уже далеко ушла от тех времён, когда шёл спор между приверженцами монорепозиториев и полирепозиториев.

Теперь мы можем пользоваться возможностями публикации независимых компонентов из простых проектов, наподобие тех, что созданы с использованием Create React App, с возможностью контроля версий, с автоматическим созданием package.json, документации и многого другого. В частности, такие возможности даёт платформа Bit.

4. Случайная публикация секретных данных


Если вы случайно опубликовали модуль, содержащий секретные данные, то первым делом нужно отменить его публикацию.

Но это не решает проблему утечки данных, так как после того, как модуль опубликован, он копируется на все зеркала репозитория пакетов. И если отменить его публикацию — это не позволит исправить ситуацию.

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

Для применения белых списков публикуемых материалов достаточно добавить в package.json свойство с именем files. В нём можно указать список файлов или папок, которые подлежат публикации.

{
 "name”: "my-package”,
 "version”: "1.0.0”,
 "description”: "my-package”,
 "scripts”: {
 "test”: "echo \”Error: no test specified\” && exit 1"
 },
 "files”: [
 "dist/”
 ],
 "keywords”: [],
 "author”: "bhagya-withana”
}


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

5. Использование обычного токена аутентификации


Если вы используете в CI/CD-цепочке приватные модули, вам понадобится воспользоваться токеном аутентификации. Но инструменты npm, работающие в командной строке, при создании подобных токенов не позволяют управлять правами на чтение и на запись.

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

Нижеприведённая команда позволяет создать токен с ограничением доступа только чтением данных:

curl -u [USERNAME]:[PASSWORD] https://registry.npmjs.org/-/npm/v1/tokens \
-X POST -H 'content-type: application/json' \
-d '{"password":"[USERNAME]", "readonly": "true"}'


На сайте npm можно просматривать, добавлять и удалять подобные токены.

image-loader.svg


Команда для доступа к операциям с токенами

6. Бессмысленное обновление пакетов


Использование самых свежих версий пакетов — это хорошо. Но не стоит обновлять пакеты только из-за того, что выходят их новые версии. Разберёмся с причинами этой рекомендации:

  • В самой свежей версии пакета могут быть ошибки.
  • Обновление пакетов без тщательного изучения изменений может привести к неожиданным эффектам в приложении.
  • Новые возможности могут оказаться ненужными в конкретном проекте.
  • Установка самой свежей версии некоего пакета может привести к проблемам в работе других пакетов, которые от него зависят.


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

7. Удаление файла package-lock.json


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

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

В результате, вместо того, чтобы, в попытке решения некоей проблемы, удалять файл package-lock.json, можно попробовать следующее:

  • Разрешить конфликты package.json.
  • Изъять package-lock.json из главной ветки репозитория.
  • Снова выполнить команду npm install.


Итоги


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

Но работа с npm сопряжена с множеством ошибок, некоторые из которых могут привести к серьёзным проблемам. Хочется надеяться, что то, о чём мы говорили в этом материале, поможет вам совершать меньше ошибок при работе с npm.

Сталкивались ли вы когда-нибудь с проблемами, вызванными ошибками, допущенными при работе с npm?

image-loader.svg

© Habrahabr.ru