In 2012 I ran a Build Process workshop as part of [ffconf tooling tutorials](http://2012.ffconf.org/#tooling). Early on as part of my workshop introduction I said that makefiles were hard and for harden unix beared folk…​or something. Grunt (and the like) were definitely a gentler solution.

I still stand by that, but today the idea of installing a bunch of dependancies just so I can have my Less file converted to CSS in real-time feels…​well, crap.

[I’ve published 38 videos for new developers, designers, UX, UI, product owners and anyone who needs to conquer the command line today.](https://training.leftlogic.com/buy/terminal/cli2?coupon=BLOG\&utm_source=blog\&utm_medium=banner\&utm_campaign=remysharp-discount)

Barebones[](#barebones)

When I write my JavaScript, I err on the side of barebones. I tend to roll without libraries and frameworks, and (for better or worse) I don’t use frameworks like Ember or Angular.

I prefer lean and close to the metal. Obviously I’ll employ a framework when I’m repeating myself over and over, but this has always been my preference when developing.

When I think of it like that, it makes sense that I’d eventually end up wanting to use low levels tools like Make to handle my workflow (and eventually build process).

My requirements[](#my-requirements)

I had a project that used Less to generate the CSS. Originally we had an Express middleware that would generate the CSS file on demand.

The result was the was a significant flash of unstyled content whilst the initial build of the CSS ran (perhaps on each release - I don’t recall). So we changed it so that CSS would build once.

Now when we changed the .less file, we had to re-run the build…​

I moaned (as usual) on twitter, and got lots of useful responses, but it mostly involved installing mutliple tools (Grunt or Gulp, plus some 3rd party lib to generate, then the watcher…​etc) or suggestions that changed the workflow I was using.

This doesn’t sit well. My requirements (to me) were simple:

  1. When a single .less file changes

  2. Rebuild it

  3. Repeat

Simple.

Solution[](#solution)

There’s two parts, and the execution.

  1. Watch: when a watched file changes run a command

  2. Rebuild only the file that changed

The execution is simple, in my package.json file (because I’m using npm & node), I have:

{
  "scripts": {
    "watch": "<command>"
  }
}

And on the command line I run:

$ npm run watch

Watch[](#watch)

I looked into [gaze](http://npmjs.org/gaze), [watchy](https://github.com/caseywebdev/watchy) and a few others, but eventually settled on two potentials:

Here’s how the watch works with fswatch:

$ fswatch -o public/css/*.less | xargs -n1 -I{} make

And the same thing with nodemon (via a locally installed npm install -g nodemon):

$ nodemon --quiet --watch public/css/ --ext css --exec make
# same thing except with shorthand flags:
# nodemon -q -w public/css/ -e css -x make

Now whenever a .less file changes in the public/css directory, my make command runs, and because Make is clever, it’ll only recompile the files that have actually changed.

Aside: In my own projects, I’ve gone further with nodemon, to use it for automatically re-running tests and recompiling JavaScript for development.

Rebuild[](#rebuild)

Make is clever in that it will only rebuild the files whose dependencies have changed. In that the .css file has a .less file dependency, so when that’s changed, make will run the command to rebuild our individual .css file.

# when you run `make` alone, run the `css` rule (at the
# bottom of this makefile)
all: css

# .PHONY is a special command, that allows you not to
# require physical files as the target (allowing us to
# use the `all` rule as the default target).
.PHONY: all

# replace all .less files with .css extension and cache
# the results in a variable called `css_files`
css_files := $(patsubst %.less, %.css, $(wildcard ./public/css/*.less))

# when a .css file is *not* up to date compared to the
# .less file, then make will run the the following commands:
# - echo the string "foo.less -> foo.css"
# - run the command `lessc -x --source-map foo.less foo.css`
./public/css/%.css: public/css/%.less
  @echo "$< -> $@"
  @./node_modules/.bin/lessc -x --source-map $< $@

css: $(css_files)

Final result[](#final-result)

The [final result](https://gist.github.com/remy/274232f8b47dfa163324) is pretty awesome, especially with CSS source maps enabled in devtools.

I can edit and change the Less file in devtools, and the rebuild is near instant, which in turn is detected by devtools, which is then injected into Chrome so I see the updates happening in near-real-time:

As further reading, I highly recommend you check out [James Coglan’s excellent post on using Make](https://blog.jcoglan.com/2014/02/05/building-javascript-projects-with-make/) for a full JavaScript project.

Published 2-Dec 2014 under #code. [Edit this post](https://github.com/remy/remysharp.com/blob/main/public/blog/makefile.md)

Comments

Lock Thread

Login

Add Comment[M ↓   Markdown]()

[Upvotes]()[Newest]()[Oldest]()

![](/images/no-user.svg)

ZeeMaps

0 points

8 years ago

Thanks for the post. Agree with you that all these alternative build tools may not be that necessary. (Never figured out why the Java community needed the Ant tool. So slow.)

I found that creating intermediate CSS files was a bit of a nuisance, so went with "xargs" to run trough individual "less" files:

rm $@; echo $^ | xargs -n 1 lessc >> $@;

Now my final CSS file gets built if one of the less file changes, without generating intermediate CSS files.

![](/images/no-user.svg)

Guo Du

0 points

9 years ago

Another approach would run less in browser without command line tools running in background. At build time, you just need strip out less.js and use the compiled css file for better performance. It’s less hassle for development :)

![](/images/no-user.svg)

crdx

0 points

9 years ago

\> when a .css file is not up to date compared to the .less file

As make has has no understanding of LESS/CSS, how does it "know" it’s not up to date? Are we talking about a last modified timestamp comparison?

![](/images/no-user.svg)

rem

0 points

9 years ago

It understands that the Less file is a dependancy of the CSS file with the same name via this line: ./public/css/%.css: public/css/%.less. And (I believe), yes, it’s timestamp based. The dependancy has a newer timestamp than the output, so it runs the rule.

[Commento](https://commento.io)