Let's Make a Framework: JSLint, Makefiles
Let’s Make a Framework is an ongoing series about building a JavaScript framework from the ground up.
These articles are tagged with lmaf. The project we’re creating is called Turing. Documentation is available at turingjs.com.
JSLint is a code quality tool. There are arguments for and against many of its suggestions, so I usually tailor its options per project. I like to run it over my client-side projects just to make sure I don’t get any nasty surprises (generally found when I come to minimise a project).
Using JSLint does require care, however. Blindly following all of the suggestions could change delicate logic. However, unit tests should catch any behaviour changes.
Installation
I’ve put jslint in Turing’s package.json under devDependencies.
Interesting JSLint Errors
I think this was my favourite:
for (property in properties) {
if (properties.hasOwnProperty(property)) {
properties[property] = parseCSSValue(properties[property], element, property);
if (property === 'opacity' && opacityType === 'filter') {
element.style.zoom = 1;
} else if (CSSTransitions.vendorPrefix && (property === 'left' || property === 'top')) {
CSSTransitions.start(element, duration, property, properties[property].value + properties[property].units, options.easing);
setTimeout(function() { CSSTransitions.end(element, property); }, duration);
return;
}
}
}
The error was “Don’t make functions within a loop”. The function expression defined inside the loop, used as a callback by setTimeout, might be executed for each iteration. However, in this case it returns after running the callback. It doesn’t seem like idiomatic JavaScript to me, so I moved the callback out.
Building with make
I was reviewing Turing’s build scripts when I realised I’d basically rewritten cat. Rather than using Node to concatenate files, this saves a lot of time and effort:
cat *.js build/turing.js
Rather than shelling out in Node, this can easily be put into a Makefile. Writing Makefiles is pretty easy, but you need to know a few things up front:
- Make is designed to determine which files need to be recompiled. My simple JavaScript-oriented Makefiles don’t usually take advantage of this
- Rules are indented with tabs. If you’re using vim,
:set noexpandtab - GNU
makehas great documentation here: GNU make manual
I was happily using language-specific build tools until I noticed TJ Holowaychuk was using Makefiles all over the place. I’m not sure if he got the idea from other Node developers, but it’s convenient for a number of reasons.
Firstly, using make means I don’t need to install yet another dependency just to build my projects. It’s also good to learn something that can be applied to many languages. And I find it discourages me from putting too much code inside my build scripts; fat build scripts often mean there’s a lot of untested code hanging around.
Another bonus is we can use the wealth of shell commands that are already installed on our systems. And they’re simple, too. Take a look at Turing’s Makefile:
SRC = turing.core.js turing.oo.js turing.enumerable.js turing.promise.js turing.functional.js turing.dom.js turing.plugins.js turing.events.js turing.net.js turing.touch.js turing.anim.js
lint:
./node_modules/.bin/jslint --onevar false *.js
build: $(SRC)
cat $^ > build/turing.js
min: build
./node_modules/.bin/uglifyjs --no-mangle build/turing.js > build/turing.min.js
A few lines and the entire build process is done. Feel free to steal this, improve it, or check the Node community’s many Makefiles to get ideas for your own projects.
The last Turing commit was 71daa50.
