Make for Javascript MVC Apps
September 20, 2014
A makefile is a list of tasks and dependencies for those tasks (called goals in makefile speak). The default filename for a makefile is called Makefile. Tasks are made of:
target: dependencies
[tab] system command
A target can be any name or a filename, dependencies can be the same (except you can have no dependencies as well). Looking at a simple example:
listfiles:
ls -la
Running make against this Makefile lists the contents of the current directory.
ls -la
total 8
drwxr-xr-x 3 carl staff 102 20 Sep 22:08 .
drwx------+ 27 carl staff 918 20 Sep 22:08 ..
-rw-r--r-- 1 carl staff 19 20 Sep 22:08 Makefile
Make runs the first goal by default. Make shows the command that is run by default. You can hide the command from the output by adding a @ to the start of the command:
listfiles:
@ls -la
Outputs
total 8
drwxr-xr-x 3 carl staff 102 20 Sep 22:08 .
drwx------+ 27 carl staff 918 20 Sep 22:08 ..
-rw-r--r-- 1 carl staff 20 20 Sep 22:09 Makefile

Starting off with copying a html file over to a dist directory:
dist/index.html: app/index.html
mkdir -p $(dir $@)
cp $^ $@
- Ensure that the dist directory exists.
- Copy the depenency file to the goal name.
In this example:
$^ = app/index.html (The dependency)
and
$@ = dist/index.html (The goal target)
We also introduce a make function here:
$(dir $@)
dir outputs the directory given a file name. In this case it will output dist.
SASS
dist/css/app.css: $(shell find app/sass -name \*.scss)
mkdir -p $(dir $@)
sass app/sass/app.scss:$@
This goal gets called when ever any file in the list that is outputted from $(shell find app/sass -name *.scss) changes.
The goal runs the sass command on the app.scss and outputs the result to dist/css/app.css.
Concatenating javascript
JS = $(shell find app/scripts -name \*.js)
dist/scripts/app.js: $(JS)
mkdir -p $(dir $@)
cat @^ > $@

JS is a variable that we have introduced. It returns all the .js files under app/scripts. The goal/task here will get called whenever a .js file is changed. It will make the dist/scripts directory, then take all .js files, cat them so they are concatenated and output them to dist/scripts/app.js.
Putting it together
JS = $(shell find app/scripts -name \*.js)
dist/css/app.css: $(shell find app/sass -name \*.scss)
mkdir -p $(dir $@)
sass app/sass/app.scss:$@
dist/scripts/app.js: $(JS)
mkdir -p $(dir $@)
cat @^ > $@
dist/index.html: app/index.html
mkdir -p $(dir $@)
cp $^ $@
all: dist/index.html dist/scripts/app.js dist/css/app.css
.DEFAULT: all
The default goal/task of the makefile has now been set to all so you can now run it by just running: make.
For a full example see https://github.com/carlwoodward/react_with_make_template. If you want to get more into make please read http://www.gnu.org/software/make/manual/make.html.
