Вопрос или проблема
Пакеты Node, которые используют быстрые нативные бинарники, часто распространяют их в зависимости от архитектуры, что приводит к появлению собственных записей в package-lock.json. Когда этот lockfile зафиксирован и затем загружается кем-то на другой платформе, npm ci
с радостью установит “неправильные” платформенные пакеты, но команды CLI затем завершатся с ошибками из-за отсутствующих пакетов. Даже если у вас нет смешанной платформенной команды, вы все равно можете столкнуться с проблемами, если используете Docker или GitHub Actions.
Существует ли общий способ в npm или любом другом менеджере пакетов игнорировать определенные зависимости при блокировке и разрешать их каждый раз при установке?
Например, при установке Vite 5 на Linux будет добавлена запись блокировки для rollup и, в конечном итоге, @esbuild/linux-x64
, которая не будет работать на Mac. esbuild имеет пакет wasm, который можно использовать вместо этого, но это проблема и для других пакетов (например, @tauri-app/cli).
Я хотел бы иметь возможность загрузить проект и запустить npm ci
или npm i
, и чтобы он действительно установил бинарные зависимости для моей платформы, а не просто то, что есть в lockfile.
Не лучшие решения, которые я рассматривал:
- Существует простое решение, заключающееся в том, чтобы просто удалить lockfile и директорию node_modules и снова запустить
npm i
, но это изменит lockfile. Вы также могли бы удалить и игнорировать lockfile из репозитория. Однако и то, и другое потенциально может вызвать другие проблемы. - Overrides — это еще один способ сделать это, но пакет должен предоставить независимый от платформы пакет, и не все они это делают, и не всегда они полностью совместимы.
- Вы могли бы потенциально использовать postinstall-скрипт для ручной установки всех пакетов, необходимых для текущей архитектуры, но это кажется громоздким и подверженным сбоям, если изменяются вложенные зависимости.
Ответ или решение
К сожалению, на данный момент NPM не предоставляет встроенного способа игнорировать платформо-специфические пакеты в lock-файлах (например, для Linux, Darwin и т.д.) при выполнении команд установки, таких как npm ci
или npm install
. Тем не менее, есть несколько подходов, которые вы можете рассмотреть для решения данной проблемы.
1. Удаление и Игнорирование lock-файла
Несмотря на то, что это не самый идеальный подход, удаление файла package-lock.json
и каталога node_modules
, а затем выполнение команды npm install
может быть быстрым решением. Однако, как вы упомянули, это приведет к модификации lock-файла, что может вызвать проблемы в команде, если работают разработчики на разных платформах.
2. Использование Overrides
Использовать флаг overrides
в вашем package.json
— еще один возможный путь. Например:
"overrides": {
"@esbuild/linux-x64": "@esbuild/wasi"
}
Этот способ работает только в том случае, если зависимость имеет платформо-независимый пакет, который совместим с теми библиотеками, которые вы используете. Этот подход может потребовать дополнительной проверки совместимости, чтобы избежать возникновения ошибок при работе.
3. Пост-установка
Вы можете создать скрипт, который будет запускаться после установки пакетов, чтобы удалять платформо-специфические пакеты и устанавливать альтернативные версии, подходящие для вашей платформы. Например, используйте команду npm install
для установки необходимых пакетов для вашей архитектуры. Но следует отметить, что этот подход может быть хрупким и требует поддержания кода, что не всегда является оптимальным.
4. Использование Docker
Если ваша команда использует Docker, поддержите стандарты окружения, выбрав один и тот же базовый образ Docker для всех разработчиков. Это поможет избежать проблем, связанных с различиями в платформе, и гарантирует, что все разработчики работают в идентичной среде.
5. Использование других инструментов
Рассмотрите возможность использования других пакетных менеджеров, таких как Yarn, который имеет несколько улучшений в управлении зависимостями и может предложить более гибкие настройки в зависимости от вашей структуры.
Заключение
Несмотря на отсутствие прямого способа игнорировать платформо-специфические пакеты в lock-файлах NPM, существуют обходные пути, которые могут помочь в вашей ситуации. Каждый из предложенных методов имеет свои плюсы и минусы, и оптимальное решение будет зависеть от ваших конкретных требований и особенностей команды. Рекомендуется проводить тестирование и оценку влияния каждого из подходов в контексте вашего проекта.