The Tude Abides

A personal log of web developer Stephen Tudor

Gulp and Browserify

Just a quick write-up of some things I’ve been playing with lately.

A few weeks ago, at lunch with some old coworkers, someone mentioned that gulp might just be the new hotness that steals Grunt’s thunder. More recently, I was inspired by Martin Genev to look into the gulp build system and Browserify. I’m pretty impressed with what I’ve seen of gulp thus far, but I feel the bigger story by far is Browserify.

Update (2014-04-09): Dan Tello has posted a far superior contribution on this topic. The examples he gives are really compelling.

gulp

I’ve been on several projects now that use the Grunt build system, and I’m not trying to criticize Grunt — in many ways, it was a Godsend that saved us from the hell of Makefiles and build.xml files. However, I always found configuring Grunt to be a major chore, and I was always bad at it. The up-front configuration work can be pretty intimidating.

In contrast, gulp uses conventions similar to node.js streams. I’m no expert with using streams myself, but to be able to pipe operations into other operations, Unix-style, is quite intuitive. Writing a task in gulp is nearly as simple and natural as pseudo-coding what you want it to do.

In this example, I defined a task to build and concatenate my JavaScript source into a single file (dist/built.js), adding a file watcher for good measure. Nice!

(gulpfile.js) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var gulp = require('gulp');
var util = require('gulp-util');
var concat = require('gulp-concat');
var browserify = require('gulp-browserify');

gulp.task('scripts', function (cb) {
    gulp.src('./src/app.js')
        .pipe(browserify({
            basedir: './',
            debug: !util.env.production
        }))
        .pipe(concat('built.js'))
        .pipe(gulp.dest('./dist/'))
});

gulp.task('watch', ['scripts'], function () {
    var watcher = gulp.watch('./src/**/*.js', ['scripts']);
    watcher.on('change', function (event) {
        console.log('File ' + event.path + ' was ' + event.type + ', building scripts...');
    });
});

gulp.task('default', ['scripts', 'watch']);

Browserify

I honestly don’t think I can do Browserify any justice by attempting to explain it here, but it’s basically a library that allows you to use core node modules, npm modules, and your own modules written in node.js style in the browser.

I’ve been a proponent of AMD and RequireJS for some time, but when it comes to writing modules in JavaScript, here’s my big question: Why not use the same conventions for the browser as for node.js, with minimal, if any, boilerplate needed?

Browserify lets you do that. I wrote 3 or 4 modules, using node.js-style require statements for dependencies, and exposing what I needed to with module.exports. With very little configuration (see the gulpfile.js example above), Browserify wrapped all my modules appropriately, and built them to a single JS file, which I loaded in the browser. It worked. It was glorious. The blinders were off.

My experience with Browserify thus far has only been with modules I’ve written myself. I haven’t even scratched the surface of using an npm module in the browser yet. That will be my next experiment. I’m genuinely excited.

Emergent Task Planner

For a few years now I’ve used David Seah’s excellent Printable CEO resources, to keep track of my activity across projects. I stopped doing it a while back for some reason, but recently rediscovered them, and decided they deserved a mention, particularly the Emergent Task Planner(ETP).

ETP top section

The ETP really is great to use, and the pads you can buy from Amazon are of extremely high quality. What I like most is how much it reduces the friction of plotting how I’ve spent my day. It’s dead simple to just pick up and start using. I have found the ETP to be an invaluable asset for logging of how I spend my time between different projects.

A word of caution: the ScanTron-phobic among us may wish to look elsewhere for suitable productivity tools, as the filling in of little ovals features prominently in these. But for the frictionless capturing of task-based information in the moment, I haven’t found anything else that works nearly as well for me.

Year in Review

It has been a very busy year for my family and me. I suppose this post is something of an excuse for the lack of updates to this blog, so enjoy the rambling stream of consciousness below. I have no agenda here, other than to briefly recall the year’s highlights.

Developers Are Artists

Software development is, in part, an artistic practice. As a developer, your brush is a keyboard; your canvas, a text editor. You derive satisfaction from crafting solutions to real problems, and it is your creativity that brings the solutions to life.

KSS and Middleman

I love the idea of building an “interactive style guide” for a website design. I really do. However, working in Agencyland, it can be extremely difficult to budget enough time for this kind of tool when seemingly higher-priority tasks pile up. Right or wrong, the utopian vision of a living style guide often becomes a foregone luxury in the throes of looming deadlines.

Assumes the reader understands the basics of Ruby and CSS.

10 Vim Techniques for Novices

Since I switched to Vim as my primary editor back in March of this year, I have discovered a wealth of useful tricks that help me get things done. Most of these techniques are truly indispensible, and should find a place in any Vim user’s quiver.

I should also note that at this time, I’m nowhere near expert-level in my Vim abilities, so this post is intended to share some commands, patterns, and configurations with other Vim users who are still getting their feet wet with the editor. Experienced Vimmers will already know all this stuff, and more power to them. This is for the Vim n00bs out there.

OOCSS, for Great Justice

In my previous post, I hinted at a growing concern with CSS performance. Among those pioneering ways to approach the issue of maintainable-yet-efficient CSS is Nicole Sullivan, who is perhaps best known for her open source Object-Oriented CSS project.

Object-Oriented? CSS?

I have to admit that when I first checked out out OOCSS, I guffawed. While it’s true that, at first blush, CSS does not have many of the traditional features of a genuine OO programming language, Nicole has been exploring ways in which CSS’ inheritance/cascade can be analogous to OO concepts.

It’s taken me quite some time to come around. There are things in the OOCSS code base that seem to fly in the face of commonly-accepted CSS best practices. It is precisely this kind of resistance in the community that must have prompted Nicole to deliver her latest talk this year at Webstock, entitled Our Best Practices Are Killing Us (slides).

DNS Fail

To those who tried to visit this site only to get a 404 error in the last 24 hours, I apologize. I believe DNS propagation was the culprit, and I jumped the gun by announcing that my post was up. I was able to view stephentudor.com just fine, but quickly found that several people, including my lovely wife, could not even get to the site initially.

By this time, it appears that most folks have been able to access it. If you can see this post, you’re fine. Otherwise, you’re probably in the camp that is left wondering why this joker posted a 404 URL to Twitter.

Again, mea culpa. I’ll know better next time :)

Responsible Sass Authoring

In capable hands, Sass can do amazing things for your CSS. With Sass, you can use functions and variables that later get compiled into valid CSS. This can greatly reduce code repetition and the potential for mistakes.

For example, not that you would, but you could write some Sass like this:

(example-1.sass) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Set a couple of vars
$titleColor: #000
$titleSize: 24px

.article
  .title
    color: $titleColor
    font-size: $titleSize
  .alt-title
    @extend .title
    border-bottom: 1px solid lighten($titleColor, 80%)    // #ccc
    color: transparentize(lighten($titleColor, 20%), 0.1)
  .sub-title
    @extend .title
    font-size: round($titleSize * 0.85)    // 20.4px
    &:hover
      background-color: transparentize(change-color($titleColor, $red: 255), 0.8);

The resulting CSS might look something like this, depending upon how you set your Sass output style preference:

(example-1.css) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.article .title,
.article .alt-title,
.article .sub-title {
    color: #000;
    font-size: 24px;
}
.article .alt-title {
    border-bottom: 1px solid #cccccc;
    color: rgba(51, 51, 51, 0.9);
}
.article .sub-title {
    font-size: 20px;
}
.article .sub-title:hover {
    background-color: rgba(255, 0, 0, 0.2);
}

Pretty cool, right? You can see that the @extend keyword can be a very powerful tool, bringing a quasi-object-oriented paradigm to our CSS. The same could be true for the nested selectors; you just have to refer to .article once, and let the indentation take care of the scope for you.