Java vs. JavaScript Build Tools

When you come from a Java background like I do and you take a look at JavaScript build tools, the sheer mass of tools is overwhelming.The eco system is evolving very fast with new tools coming up every couple of months. Below, I tried to give a comparison between Java build tools and their equivalent in the JavaScript world.

Preface

The list below aims to show similarities – not differences. Of course, every tool has its own set of features and individual strengths. The tools on the left are not the very as the tools on right, just for another software stack. However, to see some similarities might help to better understand how the JavaScript world works.

Runtime

java nodejs
  • Platform where all tools will run on
  • Executes scripts, tests, etc.

Task Runner

gradleant gruntgulp
  • Executes scripts and orchestrates tasks
  • Copy files, uglify, minify, package…

Package Manager

maven bower300
  • Dependency Management
  • Versioning

Test Runner

junit karma
  • Tests
  • Test Suits

Mocking/Assertion Library

bildschirmfoto-2016-11-14-um-09-17-07 Jasmine
  • Assertions and expectations (assertThat(1 + 1, is(2)))
  • Mocks and stups

Best regards,
Thomas

Layering of Docker images

Docker images are great! They are not only portable application containers, they are also building blocks for application stacks. Using a Docker registry or the public Docker index, you can compose setups just by downloading the right Docker image.

But Docker images are not only building blocks for applications, they also use a kind of “build block” themselves: layers. Every Docker image consists of a set of layers which make up the final image.

Layers

Let us consider the following Dockerfile to build a simple Ubuntu image with an Apache installation:

If we build the image by calling docker build -t test/a . we get an image called a, belonging to a repository called test. We can see the history of your image by calling docker history test/a:

The final image a consists of six intermediate images as we can see. The first three layers belongs to the Ubuntu base image and the rest is ours: one layer for every build instruction.

We will see the benefit of this layering if build a slightly different image. Let’s consider this Dockerfile to build nearly the same image (only the text file in the last instruction has a different name):

When we build this file, the first thing we will notice is that the build is much faster. Since we already created intermediate images for the first three instructions (namely FROM..., RUN... and RUN...), Docker will reuse those layers for the new image. Only the last layer will be created from scratch. The history of this image will look like this:

As we see, all layers are the same as for image a, except of the first one where we touch a different file!

Benefits

Those layers (or intermediate images or whatever you call them) have some benefits. Once we build them, Docker will reuse them for new builds. This makes the builds much faster. This is great for contentious integration, where we want to build an image at the end of each successful build (e.g. in Jenkins). But the build is not only faster, the images are also smaller, since intermediate images are shared between images.

But maybe the best things are rollbacks: since every image contains all of its building steps, we can easily go back to a previous step if we want so. This can be done tagging a certain layer. Let’s take a look at image b again:

If we want to make a rollback and remove the last layer (maybe the file should be called c.txt instead of b.txt) we can do so by tagging the layer 9977b78fbad7:

Let’s take a look at the new history:

Our last layer is gone and with the layer the text file b.txt!

Best regards,
Thomas