Apr 14, 2016

Using Self Contained Node.js and npm instances with Gradle

Recently I was given the task to get a new project started from ground zero. This is the day I always dreaded since jumping into an existing project is easy but starting from scratch involves a lot of time just setting up the project scaffolding and creating a lot of configuration items. Oh and one more thing was tossed in: the build server doesn’t have node.js or npm (Node Package Manager) installed but we really wanted to use it. At this point I was thinking this is a not-so-fun situation but after researching how to do this, I found out not only is it possible but it actually makes sense to have your node.js and npm version defined in the build script so that the developers and build server are all using the same build tool versions. Not just that, but some places still have environments so locked down that developers still aren’t able to install applications. There are workarounds of course to this but a universal solution is talked about here.

For this example, I’m going to show you how to get node.js and npm installed via gradle. In a post coming up later, I’ll explain how I got react working with webpack to transcompile all my scripts for me, all with using gradle only and not needing to have node.js or npm globally installed. Let’s start with a simple Spring Boot application with a few modifications:

A few things of note here:

  • We’re using the gradle-node-plugin
  • Jcenter is added to the build repositories (not hosted on maven central)
  • There’s a node section defining the version numbers we want

To get node and npm downloaded, just run:

gradlew npmInstall

after the gradle items are setup and that’s it.  That’s great and all but I haven’t given you enough to actually use it. Common tasks for npm are normally to install and delete dependencies. Let’s start with an empty package.json file in the root of our project:

If npm were installed, we could something like “npm install –save angular” or something similar. We can do this as well but we’d have to change to the node_modules/.bin directory and run the command. Now there are plenty of ways to solve this problem and this shouldn’t be taken gospel if you have a better idea. I tried really hard to get this to work via gradle but I ran into a lot of issues.  One of the issues is that if you have bootRun running, you can’t run any gradle commands since it locks a gradle file.  Not a huge deal but once I got it working, I found out it worked great by itself but then always ran before bootRun would start and then would fail since I added error checking which threw an error if the task wasn’t passed in the dependency parameter.  Bummer.  The gradle idea wasn’t too good though since gradle doesn’t handle command line parameters that well. I was running commands like “gradle npmInstallSave -Pdep=angular” and I would need to create a task for every common task or create longer command line arguments for a generic task.  The -P arguments don’t exactly role off the fingers at all.  The other solutions for this are to change to the directory or write a script.  I went the script route and committed these to the root of the project.

Here are the super complex scripts to get this working (be kind and commit both):

Windows – npm.cmd

*nix – npm

Now I can run npm from the root of the project and use it as if the command was installed system wide. These simple scripts pass all the parameters you give it to the actual npm program. You can test it by running “npm install -save angular" and you should see the custom banner at top and also the package.json file should be updated.  Full working example is available here.  Check back later for another example showing how to use Webpack, React, and gradle together to compile and package javascript files with gradle.

About the Author

Jeff Torson profile.

Jeff Torson

Sr. Consultant

Jeff is a full stack developer with experience in the government/defense and finance industry. He has experience ranging from thick client Eclipse RCP programs to microservices using Spring Boot for data access and Elasticsearch. He enjoys learning about anything related to the IT field and has even managed Linux and Windows servers and setup deployment pipelines. He is a true believer in that if something is worth doing, then it’s worth doing right the first time and fully unit/integration tested.

One thought on “Using Self Contained Node.js and npm instances with Gradle

  1. Alaa Elhadba says:

    Does it really make sense to have node_modules on the project home dir instead of putting it inside src/main/resources ?
    everything generated by npm will be used/accessed as resources within a running application!
    Im trying to put packages.json inside the resources folder and build everything there.. but im failing to get it right

    1. Jeff Torson says:

      Alla, nothing from node_modules will be accessed via a running application. Webpack will figure out what your application needs by you defining entry points and it then digging through your source and dependencies to see what it needs to include inside the bundle. This bundle has everything it needs in one giant file or multiple files if you set it up that way. You can then debug the code by using source maps (turned on in this example) for browsers to reconstruct the original source and allow you to put break points in as if you were using the original source files.

  2. jake says:

    do you know how to integrate a custom .npmrc file into the build for gradle’s npm instance to use? -TIA

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
Google Professional Machine Learning Engineer Exam 2021
Exam Description A Professional Machine Learning Engineer designs, builds, and productionizes ML models to solve business challenges using Google Cloud technologies and knowledge of proven ML models and techniques. The ML Engineer is proficient in all aspects […]
Designing Kubernetes Controllers
There has been some excellent online discussion lately around Kubernetes controllers, highlighted by an excellent Speakerdeck presentation assembled by Tim Hockin. What I’d like to do in this post is explore some of the implications […]
React Server Components
The React Team recently announced new work they are doing on React Server Components, a new way of rendering React components. The goal is to create smaller bundle sizes, speed up render time, and prevent […]
Jolt custom java transform
Jolt is a JSON to JSON transformation library where the transform is defined in JSON. It’s really good at reorganizing the json data and massaging it into the output JSON you need. Sometimes, you just […]