Как управлять зависимостями npm и не сойти с ума?

Работаю над довольно большим React-проектом и каждый раз, когда ставлю новый пакет, сталкиваюсь с дикими конфликтами версий. Пробовала использовать npm ci, но это не всегда помогает, особенно когда работаю в команде. Есть ли более умный способ справиться с этой ситуацией без того, чтобы всё переделывать с нуля?

3 ответа

★ Лучший ответ

Никогда не трогай `package-lock.json` руками, это первая ошибка! Мне очень помогло использовать `npm ci` локально и особенно настроить `.npmrc` с `save-exact=true` в проекте, так что когда устанавливаешь новые пакеты, сохраняются точные версии вместо `^` и `~`, которые создают беду.

Потом добавь pre-commit hook с husky, который блокирует попытки закоммитить поломанный `package-lock.json` - банально, но работает как чудо, потому что команда не сможет всё испортить случайно. И если уж надо добавить пакет, делай это всегда через `npm install --save-exact имяпакета` и дай кому-то проверить перед пушем!

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

Проблема в том, что npm по умолчанию слишком гибкий. В первую очередь убедись, что все в команде используют `npm ci` вместо `npm install` при работе на уже запущенном проекте. Разница в том, что `npm ci` читает ровно то, что есть в `package-lock.json`, не изменяя его, а `install` начинает автоматически обновлять патч- и минор-версии, когда ему захочется. Если ты используешь `npm install` для добавления новых пакетов, а потом пушишь файл блокировки, остальные получат другие версии. К тому же, всегда коммить `package-lock.json` в репозиторий - звучит очевидно, но многие это не делают и потом удивляются, почему билд падает.

Для новых пакетов используй `npm install --save-exact`, если ты действительно хочешь заморозить конкретную версию, или посмотри на инструменты вроде `npm audit` для проверки на известные конфликты зависимостей. Если проблема серьёзная и много вложенных зависимостей, попробуй время от времени использовать `npm dedupe` для чистки дерева зависимостей. На самом деле, можешь попробовать pnpm или yarn, если готов переходить на другую экосистему - они управляют зависимостями аккуратнее, - но если ты хочешь остаться с npm, соблюдение схемы `ci` + `package-lock.json` в git должно решить большинство проблем.

Francesca1967 автор вопроса Да, мы всегда коммитим lock-файл. Проблема в том, что некоторые коллеги до сих пор используют `npm install` для добавления новых пакетов. Попробую стандартизировать на `npm ci` и `--save-exact` для новых пакетов.

Вот что меня спасло на самом деле - всегда использовать `npm ci`, но главное - настаивать, чтобы это делала вся команда, а не `npm install`.

В момент, когда кто-то делает обычный `install` для добавления пакета, `package-lock.json` изменяется странным образом, а потом остальные застревают с абсурдными merge conflicts.

Я делаю `npm install <package> --save` только когда нужно добавить что-то новое, и позволяю файлу блокировки обновиться, потом коммичу всё вместе с остальным. Но настоящий трюк - настроить версии в `package.json` с более консервативными диапазонами - типа `^16.0.0` вместо `*` - так React не обновится на minor version, что всё сломает. Я видела большие проекты, где они просто положили в репо общий файл `.npmrc` с `save-exact=true`, так что каждый новый пакет привязывается к точной версии.

Это более жёсткий подход, но хотя бы не сойдёшь с ума при совместной работе.

Ваш ответ

Войдите, чтобы ответить.