Dependency Management with Maven & Npm

Evan J B | Mar 27, 2017

TL;DR (Abstract)

A quick review and comparison between these popular build tools including a link to sample projects on github.

Intro

The 1.0 release of maven was made over 10 years ago and it continues to be a popular choice for many projects and developers. Npm reached the same milestone just over 5 years ago. Both tools aim to solve a similar problem within their respective domains.


Figure 1. Dependency management depicted with: (left) a parent holding a child's hand, who is holding the hand of a teddy bear; (right) dependency graph of parent, child and teddy bear diagram elements.

Defining Dependencies

Dependencies are nothing new. Every import, #include and require statement handles dependencies at the file level. These three tools apply the same principles to applications and software libraries. Each tool employs a similar mechanism for listing dependencies: a single file located at the project root contains the configuration. The dependencies consist of at least a name and a version.

Maven - pom.xml

...
<dependencies>
 <dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
 </dependency>
</dependencies>
 ...

Npm - package.json

 ...
 "dependencies" : {
  "express" : "4.14.0"
 }
 ...

Project Creation

This is a key feature where the two tools differ. I prefer the simplicity of the npm cli and find it faster to get started with.

Npm

To start a new project with npm simply run:

npm init

You can then add the express library with another short command:

npm i -S express
# short hand for "npm install --save express"
Create an index.js file in the same directory and your project is ready to go!

Maven

Maven has no init method. However, you can simply hand craft a pom.xml file in the root directory. The sample below defines a new java project with a testing dependency on junit.

<project>
  <modelVersion>4.0.0</modelVersion>
  <name>Maven App</name>
  <groupId>com.evanjbowling.blog</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
 
  <properties>
    <junitVersion>4.12</junitVersion>
  </properties>

  <dependencies>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junitVersion}</version>
    <scope>test</scope>
   </dependency>
 </dependencies>
 
</project>

Maven requires a specific project layout in order to work without extra configuration. Most of these conventions are easy enough to follow, so you're better off following them at first. A basic project consists of the following three paths:

Place a simple HelloWorld.java and that's it! Now you're ready to build with maven. Try the following commands:

mvn clean && mvn compile

Maven Archetypes

Another approach to creating projects with Maven is to use archetypes. These provide a way to create template projects, each with their own groupId, artifactId, and version. Create a project with archetypes by running the following:

mvn archetype:generate -Dfilter=org.apache.maven.archetypes:

This will list twelve apache archetypes to choose from (select one by the number). By default, it will use "maven-archetype-quickstart". You then choose the version of the archetype and additional project settings form the command line.


The archetype also generates a sample App.java file in your src directory.

Critiques

References