Making the case for make
Make gives you access to many tiny, powerful UNIX tools and shouldn't be overlooked as a build tool.
Harness tiny UNIX tools ¶
Make is the original UNIX build tool. It existed a long time before gulp,
or grunt. Loved by some, loathed by others it is at least worth being aware
of how make
works, what the strengths are and where it falls short.
Make is available on UNIX-like systems. That means OSX, BSD and Linux. It
exposes any system command meaning that you can run system commands and execute
arbitrary scripts. There is no doubt that tools like gulp and grunt are inpsired
by or at least a reaction to make
.
To use make
you create a Makefile and then run make [what to run]
from the
terminal. In the following examples it is assumed make build
will be run from
the terminal.
Concatenating Files ¶
A common build task is to concatenate various files into a single file. In the tradition of UNIX single line commands this is easy.
build: mkdirs concat-css
mkdirs:
@mkdir -p ./build/css
concat-css:
@cat ./src/stylesheets/*\.css > ./build/css/application.css
That’s it - five lines of code.
UNIX tools already exist to make directories and combine files and they are fast because more often than not the underlying tools are C based.
Minifying CSS ¶
We can extend the previous example to minify the CSS using the cssmin node module to minify the css too.
build: mkdirs concat-css min-css
mkdirs:
@mkdir -p ./build/css
concat-css:
@cat ./src/stylesheets/*\.css > ./build/css/application.css.tmp
min-css:
@./node_modules/cssmin/bin/cssmin ./src/css/application.css.tmp > ./build/css/application.css && rm ./build/css/application.css.tmp
Copying files ¶
UNIX has many tools for copying files around the filesystem. One of those tools is rsync. It lets you synchronise folders on your own filesystem or even over the network.
build: copy-files
copy-files:
@rsync -aq ./src/ ./build
If you want to exclude files or folders you can do it like this
build: copy-files
copy-files:
@rsync -aq --exclude='_*' ./src/ ./build
This will exclude any folder names prefixed with _.
Uglifying JavaScript ¶
Foo. Assuming you’ve concatenated your JavaScript files in the same way the css example did it becomes a one line command. In this example I’m using the uglifyjs node module.
build: uglifyjs
uglifyjs:
@./node_modules/uglify-js/bin/uglifyjs ./build/js/main.js.tmp > ./build/js/main.js && rm ./build/js/main.js.tmp
Strengths ¶
UNIX encourages small, distinct tools. A Makefile allows you to pick the best tool for the job. If it runs on UNIX it runs on Make. There is no need to create a wrapper or integrate with a build framework. In this sense it allows you to choose the best tool for the job and you can throw out the idea that you have to write everything in JavaScript.
It is fast. In all tests I’ve run locally using system commands via a Makefile is always faster than using a build framework.
It is simple. If you can complete a task in five lines of code there is less to go wrong and it is easier to understand.
Weaknesses ¶
Probably the biggest weakness is that Make is not cross platform. So if you have a windows developer in your team they will have to jump through some hoops to get it working. Make can also become unmaintainable as it is just one big file. Of course you can break tasks down to individual bash scripts that get called in the Makefile.
Managing dependencies is a manual process. For node modules you can use npm to make sure a particular version is available but for UNIX tools you are on your own. Some UNIX tools vary between platforms both in terms of where they are located and what they allow you to do. GNU sed is different from BSD sed for example.
Another weakness is that it is not JavaScript. I’ve seen developers shaking
their head at Makefiles as soon as they see system commands or lines of code
that don’t start with the word var. This is more of a cultural thing than
anything to do with technology but if you are working in a team or accepting
contributions to open source projects you might find people just refuse to use
make
.
Bash - another option ¶
For a super lightweight build system you can also just craft your own bash scripts and ignore Make altogether.
Conclusion ¶
There is a tendency within any programming community to want to do everything in
the community’s language. But sometimes the problem has already been solved by
men with beards in the 1970’s. If you can park the hipster hacker mentality
there are tools that have been around for a long time that are stable and fast
that already solve your problem. The main thing is to keep it small and
distinct. If you know a little UNIX maybe you should try make
or a small bash
script as your build tool.
References ¶
Tags
Can you help make this article better? You can edit it here and send me a pull request.
See Also
-
Command Line Utilities with Node.js
Node.js is a great platform for creating small command line utilities, especially where I/O occurs. -
Continuously deploy Node apps with GitHub, Travis and Heroku
GitHub, Travis and Heroku make it simple to build a continuous deployment pipeline for Node.js applications. Here is a walkthrough. -
Working with filesystems in Node.js
Node's fs module gives you a great cross-platform toolkit for working with filesystems. With a few third-party modules it becomes everything you need