Тот же инструмент, другой язык?
Maven - самый популярный инструмент сборки и разрешения зависимостей для Java, точно так же, как NPM для JS. Но это не просто один и тот же инструмент для другого языка. Очевидно, существуют огромные различия между сборками Java и JS, и эти различия напрямую видны в том, как работает Maven. Например, в то время как многие инструменты JS полагаются на Git для выполнения некоторой тяжелой работы, Maven работает с настраиваемыми репозиториями Maven на основе файловой системы, поскольку Maven предшествует Git и должен обрабатывать двоичные артефакты, с которыми Git исторически не справлялся. В Maven есть четкое разделение между исходными кодами и двоичными файлами, хотя в мире JS это часто одно и то же.
Основы Maven
Maven в чистом виде следует декларативной модели, где pom.xml
(аналогично package.json
) определяет различные свойства сборки, но не содержит скриптов. Недостатком является то, что тонкая настройка некоторых аспектов сборки без использования скриптов может оказаться сложной задачей, поскольку вам придется полагаться на плагины. Преимущество заключается в том, что легче понять другие сборки, просто взглянув на них pom.xml
, поскольку они обычно следуют одному и тому же подходу без особой настройки. Gradle - это популярный инструмент на основе Groovy, построенный на основе стандартов и соглашений Maven, и специально разработан для упрощения pom.xml
и преодоления этого барьера, запрещающего использование скриптов.
Ссылка на ваши зависимости
Точно так же package.json
вы не работаете со pom.xml
своей зависимостью напрямую, а скорее определяете координаты зависимости и позволяете вашему инструменту сборки обрабатывать все остальное. В Maven основной формой этих координат является GAV (groupId, artifactId, version).
Плоское дерево зависимостей?
Основываясь на комментариях в другом ответе, Maven предоставляет «плоское дерево зависимостей», а не «вложенное дерево зависимостей», которое NPM предоставляет по умолчанию. Maven не позволяет использовать несколько версий одной и той же зависимости. Если бывает, что запрашиваются разные версии, Maven использует разрешение зависимостей для выбора одной версии. Это означает, что иногда ваши транзитивные зависимости получают другую версию, чем они требуют, но есть способы управлять этим. Однако это ограничение исходит от Java, а не от Maven, поскольку (обычно) в Java загрузчик классов предоставляет доступ только к одному определению класса, даже если в пути к классам обнаружено несколько определений. Поскольку Java не очень хорошо справляется с этим, Maven старается в первую очередь избегать этого сценария.
Примечание: начиная с npm v3 зависимости сглаживаются. Альтернативная пряжа диспетчера пакетов также делает то же самое.
Зрелость
Кроме того, Maven значительно старше NPM, имеет большую пользовательскую базу, огромное количество настраиваемых плагинов и, вероятно, в целом может считаться более зрелым. Иногда Maven используется для проектов, отличных от Java, или даже для многоязычных проектов, поскольку существуют плагины для работы с другими языками или конкретными средами, такими как Android. Существуют плагины, которые объединяют Maven и другие инструменты сборки, такие как frontend-maven-plugin, который фактически обрабатывает несколько инструментов сборки JS.