Sometimes you just want to ship a small number of JavaScript and CSS assets that’s an adjunct to some software you’ve written (perhaps in another language). None of the JavaScript build systems that I’ve looked at are particularly simple or intuitive — they all have a painful learning curve, and/or confusing documentation. Some of them require you to work in their way which might not fit with your practices.

This post is going to walk you through a quick and dirty approach to just shipping your assets with all their dependencies. This will give you an insight into what a full build system does, while at the same time allowing you to get started right away with your project without having to think about any of that stuff.

If you do really want a build system, then I’d recommend checking out this post which, although a few years old, will give you some good tips.

Things we’re going to need

We’re going to do this in bash, which you’ll have available if you’re on a unix-like system. If you are on Windows, I expect the concepts translate, though you are on your own.

In addition we’re going to need Node which will allow us to run JavaScript files on the command line.

We’ll also need a minifier of some kind. I’m using r.js from Require but you could use something else like uglify if you like. I’m using r.js because it will minify both JS and CSS (also, it happens to use uglify internally anyway).

The Script

Let’s work our way through the script and look at each section as we go.

First, declare that this is a bash script, and set variables which point to our instances of Node and r.js :

#!/usr/bin/env bash



NODEJS="nodejs"

R="/path/to/r.js"

Next declare some convenience variables that we’ll use a few times in the coming script. This gives us a chance to think about what the inputs and outputs are:

An output directory where all the compiled assets will end up

The source directory for your working code and CSS

Filenames for your own code and CSS once they have been compiled

Filenames for the JS and CSS bundles for your code’s dependencies

A file in which to record some build information (not necessary, but good practice)

OUT="release"

SRC="src"

COMPILED_JS=$OUT/myapp.min.js

DEPENDENCIES_JS=$OUT/myapp.dependencies.js

COMPILED_CSS=$OUT/myapp.min.css

DEPENDENCIES_CSS=$OUT/myapp.dependencies.css

BUILD_INFO=$OUT/build.txt

Our build is going to proceed in two steps:

Minification of individual assets Concatenation of all assets

Because of this two stage approach, we’re going to need a couple of intermediate staging areas where the minified code is stored before it is concatenated:

MINIFIED_JS=$OUT/minified_js

MINIFIED_CSS=$OUT/minified_css

To begin working for real, start with the boring but essential step of cleaning out any old builds, and resetting our directory structure ready for the new build:

rm -r $OUT

mkdir $OUT

mkdir $MINIFIED_JS

mkdir $MINIFIED_CSS

Building the project JavaScript source

Probably the most interesting bit is in building the actual JS that you wrote. First we compile our entire JS tree into the MINIFIED_JS directory that we created above:

$NODEJS $R -o appDir=$SRC/js baseDir=. dir=$MINIFIED_JS

This command requires some unpacking. First of all, the variables $NODEJS and $R point to our Node executable and our r.js file, which just asks Node to execute that script. r.js then takes 3 arguments, which are prefixed by -o :

appDir — the source directory for your JavaScript

— the source directory for your JavaScript baseDir — specifies the base directory for the source, which should be set to the current directory with a . .

— specifies the base directory for the source, which should be set to the current directory with a . dir — the output directory for the minified code

When this command is run, the entire tree will be traversed, all the files individually minified, and placed into an identical tree structure in the dir .

Since this process has not concatenated all these files, we need to do that ourselves, in a process which is annoyingly verbose.

We explicitly cat all of our source files in the right order, according to how they depend on each other (dependencies come higher up the list than dependents) into our final COMPILED_JS file, thus:

cat $MINIFIED_JS/myapp.js <(echo) \

$MINIFIED_JS/extension.js <(echo) \

$MINIFIED_JS/custom.js <(echo) \

> $COMPILED_JS

You now have the JS that you wrote all minified and held in a single file.

Assemble the JavaScript Dependencies

Your project probably relies on some external dependencies. For example, if you’re like me you will be using jQuery, and perhaps ChartJS, and it would be convenient if all those dependencies can be delivered to the user in a single bundle. We can do that using cat in exactly the same way as we did above:

cat /path/to/jquery-1.12.4.min.js <(echo) \

/path/to/Chart.min.js <(echo) \

> $DEPENDENCIES_JS

Note that we don’t try to minify these assets — we’re using those projects minified releases already.

Building the project CSS

CSS compilation works a little differently to JS compilation in r.js . For example, for some reason you cannot minify the entire tree, you must do it file-by-file. Our command to do each file looks something like:

$NODEJS $R -o cssIn=$SRC/css/myapp.css out=$MINIFIED_CSS/myapp.css baseUrl=.

Again we’re executing the r.js script via Node, and this time our arguments are:

cssIn — the CSS file to be minified

— the CSS file to be minified out — the resulting output file

— the resulting output file baseUrl — the base URL from which any URLs will be expanded. We can just use . here.

Finally, as before, just cat all the resulting CSS files together:

cat $MINIFIED_CSS/myapp.css <(echo) \

$MINIFIED_CSS/theme.css <(echo) \

> $COMPILED_CSS

Assemble the CSS Dependencies

Just as with the JS, you may have CSS dependencies (such as Bootstrap) and you’ll want to bundle them in the same way as you bundle your JS dependencies. Again, it’s just cat (making sure that your files are in the right order):

cat /path/to/bootstrap.min.css <(echo) \

/path/to/other.min.css <(echo) \

> $DEPENDENCIES_CSS

Write some Build info

We’re done with the actual important bits of the build, but it’s always a good idea to remember when you last ran your build, especially if you are building for release. We can write a really quick build information file like this:

echo "Build $(date -u +"%Y-%m-%dT%H:%M:%SZ")" > $BUILD_INFO