Build systems and Task runners

What are Javascript task runners?

It is imperative not to confuse Javascript task runners with Javascript runtimes. I am clarifying this point deliberately to explain the role of Node/Node.js. First and foremost, Node and Node.jsare interchangeable terms in Javascript, and mean the same thing.

I have encountered numerous sources where the terms Javascript task runners and Javascript runtimes have been used interchangeably with Javascript Build Tools. Whilst it is true that by using both task runners and runtimes one can compile or build a Javascript application; I prefer to keep these tools as separate entities for the sake of explanation. You can explore which tool suits your project needs and develop accordingly; but it is more likely in today’s projects to use a combination of multiple tools, consistently and in harmony with respect to other tools managing the project.

 

Why use a task runner?

In one word: automation. The less work you have to do when performing repetitive tasks like minification, compilation, unit testing, linting, etc, the easier your job becomes. After you've configured it through a Gruntfile, a task runner can do most of that mundane work for you—and your team—with basically zero effort.

 

What are build tools?

Build tools are programs that automate the creation of executable applications from source code(eg. .apk for android app). Building incorporates compiling,linking and packaging the code into a usable or executable form.

Basically build automation is the act of scripting or automating a wide variety of tasks that software developers do in their day-to-day activities like:

Downloading dependencies. Compiling source code into binary code. Packaging that binary code. Running tests. Deployment to production systems.

Why do we use build tools or build automation?

In small projects, developers will often manually invoke the build process. This is not practical for larger projects, where it is very hard to keep track of what needs to be built, in what sequence and what dependencies there are in the building process. Using an automation tool allows the build process to be more consistent.

 

Build System Philosophy

At their core, build systems are a functional based languages mapping a set of source resources (in most cases, files) to a target (executable). The primary assumption of the build system is that each of the build actions are idempotent. That is, each invocation of a build command with the same input and options will create the same output. This assumption allows the build system to memoize the actions that is has already performed, and only perform build actions on resources that have changed.

In order to correctly manage this memoization, the build system must know exactly which resources are being used for any given command. This process can become difficult because many modern build tools include functionality to "include" secondary files while building the primary file. In general this problem can be represented by a dependency DAG (directed acyclic graph).

hello_digraph.dot.png

In this simple example there are three source files, hello.chello_io.c, and hello.h. The .h file is included by the two .c files. The compiler takes the .c as input (and also reads in hello.h as part of the preprocessing) and produces the .o files as output. The .o files are then linked together to create the executable. The DAG informs the system what has to be rebuilt when a change occurs. If hello.cis altered everything reachable from that node in the DAG must be rebuilt.