Home Java Working with the NPMregistry from Java

Working with the NPMregistry from Java

by admin

Working with the NPMregistry from Java
NPM – a unique repository of packages from the JavaScript world.Mostly here are JS libraries that you can use in the frontend/browser, but there are also server-side ones for use in node.js and beyond.If you program in Java and need to synthesize with the NPM repository, you probably have one of the following two cases :

  • You are writing a Web application in one of the Java frameworks and certain NPM packages are required on the client side
  • You have a Java application (e.g. for Android) that needs to be able to request dependencies and the resources/packages themselves from NPM

Let’s see how this can be done in Java.

NPM resources for Web-application

You have 2 options :

  • Pack the necessary NPM resources inside your WAR/JAR
  • Use CDN for downloading the needed resources to runtime

Packing NPM resources in WAR/JAR

First of all you need to learn more about such a thing as WebJars It allows you to "mirror" NPM (and not only) packages in the Maven repository. This way you can work with NPM packages as you would with regular Java packages in Maven. For example, in order to include resources from the well known Boostrap into your WAR just add the following dependency in pom.xml:

<dependency><groupId> org.webjars.npm</groupId><artifactId> bootstrap</artifactId><version> 4.5.0</version></dependency>

WebJars reflects packages from NPM into Maven along with all the necessary dependencies, so by plugging in one JAR by dependencies, all the other necessary packages will be plugged in as well.
WebJars also has big set of libraries for different Java frameworks to make working with packed and connected resources easier. Learn more at read the documentation
WebJars is a great help for any Java backend developer. But there are easier alternatives: packing the right packages from NPM with Maven plugins. This may not be a complete list :

For example, to include the packages vue and vuex of the correct versions with jnpm-maven-plugin Add the following lines to pom.xml:

<plugin><groupId> org.orienteer.jnpm</groupId><artifactId> jnpm-maven-plugin</artifactId><version> 1.0</version><executions><execution><goals><goal> install</goal></goals><configuration><packages><package> vue@2.6.11</package><package> vuex@~3.4.0</package></packages></configuration></execution></executions></plugin>

You can use NPM notation to determine the range of versions you need :

  • Asterisk (*|X|x) – 1.* equivalent > =1.0.0 <2.0.0
  • Tilda (~) – ~1.5 equivalent > =1.5.0 <1.6.0
  • Hyphen (-) – 1.0-2.0 equivalent > =1.0.0 <=2.0.0
  • Carriage (^) – ^0.2.3 equivalent > =0.2.3 <0.3.0
  • Partial Range – 1 equivalent to 1.X or > =1.0.0 <2.0.0
  • Negation – !(1.x) equivalent to <1.0.0 > =2.0.0
  • Complex – ~1.3 | (1.4.* !=1.4.5) | ~2

You can also specify which files you want to include from packages using includes and excludes. For example, usually an NPM package contains "compiled" files in the /dist directory. The other files are source code and are not likely to be needed or useful within the Java Web application. To include only the contents of the dist/ directory, just add the following to the :

<includes><include> dist/*</include></includes>

By default, jnpm-maven-plugin packages resources in exactly the same paths as WebJars. This allows you to use the aforementioned WebJars libraries for different frameworks to access resources. If you need some other specific packaging format, please refer to the documentation

Using CDN

There are many publicly available CDNs with NPM resources. The best known and most used are :

You can also use your own CDN (e.g. hosted by docker) or even build CDN functionality into your Web-App. For example, add the following servlet to web.xml to enable the JNPMCDN. Edit as needed :

<servlet><servlet-name> CDNServlet</servlet-name><servlet-class> org.orient.jnpm.cdn.CDNServlet</servlet-class></servlet><servlet-mapping><servlet-name> CDNServlet</servlet-name><url-pattern> /cdn/*</url-pattern></servlet-mapping>

After downloading the NPM servlet, the resources will be accessible via the following URL format: http(s)://<domain> :<port> /<path to web application> /cdn/<NPM package> /<path to file> .
For example :

localhost :8080/cdn/vue@2.6.11/dist/vue.js

Working with NPM REST API from Java

Of course, you can also use the NPM Registry REST API directly, say via Retrofit This will help you with related documentation But it is more convenient to use the library JNPM which is a Java wrapper for this REST API and not only.
Include JNPM Jar in pom.xml:

<dependency><groupId> org.orienteer.jnpm</groupId><artifactId> jnpm</artifactId><version> 1.0</version></dependency>

Initialize JNPM API:

JNPMService.configure(JNPMSettings.builder().homeDirectory(Paths.get("/home/myuser/.jnpm")) //Optionally.downloadDirectory(Paths.get("/tmp")) //Optional//Other possible options - see documentation.build());

JNPM API provides 2 options: Synchronous API and Asynchronous API via RXJava. Which one you use is up to you:

JNPMService jnpmService = JNPMService.instance(); //Synchronous Java APIRxJNPMService rxJnpmService = JNPMService.instance().getRxService() //RXJava API

Example of use :

//General information about the NPM registrySystem.out.println(JNPMService.instance().getRegistryInfo());//Get and print information about the latest version of the VUESystem.out.println(JNPMService.instance().getPackageInfo("vue").getLatest());//print a description of the package vue@2.6.11.System.out.println(JNPMService.instance().getVersionInfo("vue", "2.6.11").getDescription());//Print the latest version before the second official releaseSystem.out.println(JNPMService.instance().bestMatch("vue@<2").getVersionAsString());//Download the archive for vue@2.6.11 and print the local pathVersionInfo vueVersion = JNPMService.instance().getVersionInfo("vue", "2.6.11");vueVersion.downloadTarball().blockingAwait();System.out.println(vueVersion.getLocalTarball().getAbsolutePath());//Search "vue" and print a description of the first resultSystem.out.println(JNPMService.instance().search("vue").getObjects().get(0).getSearchPackage().getDescription());// go through and print information on all dev dependencies of the latest version of vue//install those packages as NPM does (node_modules/vue, etc.)JNPMService.instance().getRxService().traverse(TraverseDirection.WIDER, TraversalRule.DEV_DEPENDENCIES, "vue").subscribe(t -> {System.out.println(t); t.install(Paths.get("target", "readme"), InstallationStrategy.NPM);})

If you have any specific case that has not been described here, please let me know!

You may also like