Maven与npm相似吗?


83

正如我与npm一起工作的那样,它在package.json文件中查找依赖项并为您下载。同样,我在Java项目中看到一个pom.xml文件。Maven是否会在此文件中查找并为我下载依赖项。我可以绕过像package.json这样的pom.xml文件,而不是提供依赖项jar吗?这些工具是否相似并且仅针对不同的平台构建?


Answers:


123

相同的工具,不同的语言?

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,版本)。

平面依赖树?

根据另一个答案中的注释,Maven提供了“平面依赖树”,而不是NPM默认提供的“嵌套依赖树”。Maven不允许相同依赖项的多个版本。如果碰巧要求使用不同的版本,则Maven使用依赖项解析来选择一个版本。这意味着有时您的传递性依赖项将获得与所需版本不同的版本,但是可以通过多种方法来管理它。但是,此限制来自Java,而不是Maven,因为(通常)在Java中,即使在类路径中找到了多个定义,类加载器也只能提供对单个类定义的访问。由于Java并不是特别擅长处理此问题,因此Maven首先尝试避免这种情况。

注意:从npm v3开始,依赖关系变得平坦。替代的卷装管理器纱线也执行相同的操作。

到期

此外,Maven比NPM年龄要大得多,拥有更大的用户群,数量众多的自定义插件,到目前为止,它可能总体上被认为更成熟。有时,Maven用于非Java甚至是多语言项目,因为有用于处理其他语言或特定环境(例如Android)的插件。有一些桥接Maven和其他构建工具的插件,例如实际上可以处理多个JS构建工具的frontend-maven-plugin


4
除了上述信息之外,以下Youtube播放列表也非常出色地描述了Maven作为包管理器的用途
Tommy Thompson

1
我经常访问npmjs.com来搜索可能有用的软件包。在Maven(search.maven.org)上找到了用于执行此操作的链接,花了很多时间进行谷歌搜索。但是,搜索不会将我指向文档,不会向我显示受欢迎程度指标,也不会指向github。我觉得这没有帮助,暗示这是人们对NPM的期望,而不是对Maven的期望。
乔·拉普

NPM和Maven之间的统计比较不错:stackshare.io/stackups/npm-vs-gradle
cacoder

1
该答案的更新:“此外,Maven比NPM年龄大得多,拥有更大的用户群...”当问题最初在2017年回答时,这可能是正确的,但不再准确。根据@cacoder发布的链接,NPM的用户基础现在比Maven大11倍。资料来源:stackshare.io/stackups/gradle-vs-maven-vs-npm
mnutsch

27

下面我用|Maven来分隔 npm条款:

共同特征:

  • 两种工具均支持基于描述符文件|依赖项的动态获取依赖项工件|包pom.xmlpackage.json,还允许您部署| 发布自己的工件| 包

  • 它们都有默认的公共存储库。注册表http://repo.maven.apache.org/maven2/ | https://registry.npmjs.org),但是也可以使用3rd-party(通过settings.xml|.npmrc)。

  • 它们都支持构建级依赖项的概念(脚本中使用的插件| devDependencies)。* Mavenprovided也支持依赖关系,但这似乎不适用于npm,因为javascript很少部署到容器中。

  • 它们都支持依赖命名空间:groupId|scope

区别:

  • Maven还有一个附加的本地存储库(缓存):

    • 无需为不同的项目再次获取相同的依赖项。
    • 本地安装的工件可以由其他本地项目自动访问。
  • 来自Maven中的项目构建的依赖项在中下载<homedir>/.m2。使用npm可以将它们下载到中<projectdir>/node_modules

  • Maven中进行构建通常是一个步骤:(mvn package获取deps,进行构建)。在npm中,这是一个两步过程:npm install(fetch deps),npm build(build)

  • 行家定义构建生命周期(用于构建,测试,部署)由阶段,到默认操作(插件的目标)连接,基于differrent封装选项(.jar.war.ear等)。然后,您可以覆盖这些操作,或注入新的操作(通过插件系统)。这为build,docgen,test,deploy等提供了一种开箱即用的解决方案。npm
    方法更加简单(请参阅: 脚本

  • 由于上述原因,npm被标记为javascript软件包管理工具,而maven被标记为java构建自动化和依赖关系管理工具

  • 在maven设置中,构建过程通常涉及编辑pom.xml
    在npm中,它涉及编写代码或配置补充构建工具(例如gulpwebpack

  • 由于某些原因,用户在npm模块中定义的版本范围比maven宽松得多。这可能会导致传递依赖项出现问题,这就是最近添加一个附加文件的原因:package-lock.json

  • 使用npm ,开始一个新项目要简单得多:npm init。使用Maven,您需要知道如何编写minimalpom.xml或阅读有关原型的信息。

  • 一般而言,编辑pom.xmlpackage.json。例如在行家添加依赖完成手动(或经由IDE),而在NPM通过命令行

  • 与所有构建工具一样,您可以从另一个内部调用一个工具,但是我认为从maven内部调用npm比在另一个内部调用更为普遍。

  • npm支持开发,生产构建。在Maven中,这需要通过配置文件进行定义。


5

是。它是Java的类似打包工具。gradle还可以通过查找为您提供更多的自由groovy language,但是首先,您可以使用maven来组织依赖项。您将它们作为标签包括在内,而maven会为您完成工作。

它遍历依赖关系树并下载所有适当的jar。


1
不确定,因为我不太熟悉所有这些js工具。gradlemaven + ant一起让我们说。它可以完成maven的工作,但它除了提供事实上的所有工作外,还为您提供了编写代码和脚本的自由。我刚才看了看gulp。从我阅读的内容来看,也许是一样的。如果您想开始使用Maven vs Gradle,我建议您从此开始maven更清晰,更容易理解,然后将其弄乱gradle
阿波斯托洛斯

谢谢。Maven是否具有平面依赖树或嵌套依赖树?
Shubham Jain

1
例如,请参见mvnrepository.com/artifact/org.hibernate/hibernate-core/…。hibernate依赖于其他各种库,但是这些jar不会存储在hibernate库内部的本地Maven存储库中,而是存储在它们自己的包中。
阿波斯托洛斯

1
我认为嵌套(传递)依赖项的处理有所不同。每个节点模块都可以包含其自己的依赖关系版本,而如果多个依赖关系要求相同的第三个依赖关系但版本不同,则maven将尝试解析为单个公共依赖关系。我也要说,自从基于任务以来,咕unt声就开始了。gradle更多的是ant + ivy,而maven的驱动力则是约定俗成。也许更接近webpack,但是没有什么相似之处。
wemu

1
对不起,你是对的。它与我有时使用并定义版本的概要文件构建过程相混淆。
阿波斯托洛斯

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.