Dependency Management with Maven & Npm
Evan J B | Mar 27, 2017TL;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.
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:
- src/main/java - Java src files
- target - project build output
- pom.xml - project file (aka Project Object Model)
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¶
- Maven doesn't have support for an "init" cli method while npm does.
- The "scope" property in Maven dependencies has a complex set of values; the simple split between "dependencies" and "devDependencies" in npm is cleaner.
- Maven archetypes should default to the latest version of an archetype to make the cli interface simpler.
- Npm doesn't provide for a "groupId", only a name and version.
References ¶
- Github
- Maven
- Pom Reference
- 1.0 Release- Release date listed as 2004-07-13 on [Web archive] Retrieved from: apache archives
- Archetypes
- Npm
- 1.0 - Release determined to be in range [Mar 21, 2011; Apr 27, 2011] based on [Web archive] Retrieved from: v1.0.0-1-rc and v1.0.1rcFINAL